rgame 0.2.0 → 0.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/CHANGELOG.md +135 -1
- data/README.md +67 -65
- data/docs/api/README.md +86 -82
- data/docs/api/app.md +125 -68
- data/docs/api/assets.md +203 -165
- data/docs/api/audio.md +130 -89
- data/docs/api/cli.md +259 -0
- data/docs/api/components.md +1032 -265
- data/docs/api/drawing.md +160 -160
- data/docs/api/examples.md +263 -0
- data/docs/api/game.md +149 -50
- data/docs/api/images.md +39 -39
- data/docs/api/input.md +226 -148
- data/docs/api/internals.md +241 -62
- data/docs/api/localization.md +285 -0
- data/docs/api/scene_graph.md +397 -244
- data/docs/api/signals.md +81 -76
- data/docs/api/systems.md +186 -73
- data/docs/api/text.md +58 -41
- data/docs/api/tile_maps.md +237 -0
- data/docs/api/toolbox.md +395 -146
- data/docs/api/ui.md +883 -54
- data/docs/api/values.md +216 -33
- data/examples/assets/README.md +322 -0
- data/examples/assets/blip.ogg +0 -0
- data/examples/assets/glyphs.json +5 -0
- data/examples/assets/glyphs.png +0 -0
- data/examples/assets/hero.json +12 -0
- data/examples/assets/hero.png +0 -0
- data/examples/assets/icons.json +13 -0
- data/examples/assets/icons.png +0 -0
- data/examples/assets/music.ogg +0 -0
- data/examples/assets/skills.json +10 -0
- data/examples/assets/skills.png +0 -0
- data/examples/assets/tileset.png +0 -0
- data/examples/assets/tileset.tsx +65 -0
- data/examples/assets/town.tmx +26 -0
- data/examples/assets/ui.json +11 -0
- data/examples/assets/ui.png +0 -0
- data/examples/collision/locales/en.yml +8 -0
- data/examples/collision/main.rb +316 -0
- data/examples/collision_tiles/locales/en.yml +9 -0
- data/examples/collision_tiles/main.rb +274 -0
- data/examples/fullscreen/locales/en.yml +10 -0
- data/examples/fullscreen/main.rb +216 -0
- data/examples/game_menu/locales/en.yml +8 -0
- data/examples/game_menu/main.rb +170 -0
- data/examples/input_glyphs/locales/en.yml +14 -0
- data/examples/input_glyphs/main.rb +213 -0
- data/examples/jump_topdown/locales/en.yml +9 -0
- data/examples/jump_topdown/main.rb +178 -0
- data/examples/localization/locales/de.yml +12 -0
- data/examples/localization/locales/en.yml +13 -0
- data/examples/localization/main.rb +158 -0
- data/examples/menu_navigation/locales/en.yml +23 -0
- data/examples/menu_navigation/main.rb +365 -0
- data/examples/music/locales/en.yml +7 -0
- data/examples/music/main.rb +134 -0
- data/examples/pathfinding/locales/en.yml +17 -0
- data/examples/pathfinding/main.rb +298 -0
- data/examples/pooling/locales/en.yml +7 -0
- data/examples/pooling/main.rb +259 -0
- data/examples/quick_wheel/locales/en.yml +16 -0
- data/examples/quick_wheel/main.rb +184 -0
- data/examples/radial_menu/locales/en.yml +16 -0
- data/examples/radial_menu/main.rb +184 -0
- data/examples/save_load/locales/en.yml +11 -0
- data/examples/save_load/main.rb +207 -0
- data/examples/save_load_ids/locales/en.yml +11 -0
- data/examples/save_load_ids/main.rb +322 -0
- data/examples/scroll_map/locales/en.yml +4 -0
- data/examples/scroll_map/main.rb +140 -0
- data/examples/signals/locales/en.yml +6 -0
- data/examples/signals/main.rb +278 -0
- data/examples/skill_bar/locales/en.yml +14 -0
- data/examples/skill_bar/main.rb +159 -0
- data/examples/sound/locales/en.yml +6 -0
- data/examples/sound/main.rb +122 -0
- data/examples/split_screen/locales/en.yml +9 -0
- data/examples/split_screen/main.rb +304 -0
- data/examples/sprite/locales/en.yml +8 -0
- data/examples/sprite/main.rb +180 -0
- data/examples/timer/locales/en.yml +12 -0
- data/examples/timer/main.rb +273 -0
- data/examples/velocity/locales/en.yml +6 -0
- data/examples/velocity/main.rb +196 -0
- data/examples/walk/locales/en.yml +4 -0
- data/examples/walk/main.rb +99 -0
- data/exe/rgame +9 -0
- data/ext/rgame_core/app/app.c +33 -3
- data/ext/rgame_core/app/locale.c +67 -0
- data/ext/rgame_core/app/locale.h +28 -0
- data/ext/rgame_core/audio/audio.c +39 -2
- data/ext/rgame_core/example.rb +0 -49
- data/ext/rgame_core/extconf.rb +0 -125
- data/ext/rgame_core/include/rgame/core.h +38 -2
- data/ext/rgame_core/ruby/audio_ext.c +10 -5
- data/ext/rgame_core/ruby/core_ext.c +30 -7
- data/ext/rgame_core/ruby/core_ext.h +3 -0
- data/ext/rgame_core/ruby/locale_ext.c +44 -0
- data/ext/rgame_core/ruby/recording_ext.c +1 -1
- data/ext/rgame_core/ruby/renderer_ext.c +20 -20
- data/ext/rgame_util/extconf.rb +2 -20
- data/ext/rgame_util/route_search.c +305 -0
- data/ext/rgame_util/route_search.h +86 -0
- data/ext/rgame_util/route_search_ext.c +150 -0
- data/ext/rgame_util/solid_grid.c +58 -0
- data/ext/rgame_util/solid_grid.h +49 -0
- data/ext/rgame_util/solid_grid_ext.c +161 -0
- data/ext/rgame_util/tile_sweep.c +164 -0
- data/ext/rgame_util/tile_sweep.h +62 -0
- data/ext/rgame_util/tile_sweep_ext.c +155 -0
- data/ext/rgame_util/util_ext.c +3 -0
- data/ext/rgame_util/util_ext.h +15 -0
- data/lib/rgame/boot.rb +0 -10
- data/lib/rgame/cli/new_project.rb +139 -0
- data/lib/rgame/cli/templates/Gemfile.tt +23 -0
- data/lib/rgame/cli/templates/README.md.tt +93 -0
- data/lib/rgame/cli/templates/Rakefile.tt +9 -0
- data/lib/rgame/cli/templates/assets/locales/en.yml.tt +10 -0
- data/lib/rgame/cli/templates/game.rb.tt +23 -0
- data/lib/rgame/cli/templates/gitignore.tt +12 -0
- data/lib/rgame/cli/templates/main.rb.tt +11 -0
- data/lib/rgame/cli/templates/nodes/root.rb.tt +24 -0
- data/lib/rgame/cli/templates/rspec.tt +2 -0
- data/lib/rgame/cli/templates/rubocop.yml.tt +75 -0
- data/lib/rgame/cli/templates/ruby-version.tt +1 -0
- data/lib/rgame/cli/templates/spec/locales_spec.rb.tt +18 -0
- data/lib/rgame/cli/templates/spec/nodes/root_spec.rb.tt +18 -0
- data/lib/rgame/cli/templates/spec/spec_helper.rb.tt +37 -0
- data/lib/rgame/cli.rb +66 -0
- data/lib/rgame/core/app.rb +6 -44
- data/lib/rgame/core/asset_manager.rb +13 -31
- data/lib/rgame/core/audio.rb +37 -16
- data/lib/rgame/core/font.rb +0 -3
- data/lib/rgame/core/locale.rb +22 -0
- data/lib/rgame/core/nine_slice.rb +0 -21
- data/lib/rgame/core/renderer.rb +6 -63
- data/lib/rgame/core/sprite_sheet.rb +0 -3
- data/lib/rgame/core/tile_map_renderer.rb +2 -19
- data/lib/rgame/core/ui_atlas.rb +28 -13
- data/lib/rgame/core.rb +1 -8
- data/lib/rgame/engine/actor_blockers.rb +131 -0
- data/lib/rgame/engine/animation_set.rb +1 -0
- data/lib/rgame/engine/audio_director.rb +36 -6
- data/lib/rgame/engine/bounds_blockers.rb +74 -0
- data/lib/rgame/engine/camera.rb +3 -3
- data/lib/rgame/engine/circle_collider.rb +4 -2
- data/lib/rgame/engine/collision_box.rb +26 -1
- data/lib/rgame/engine/collision_system.rb +110 -22
- data/lib/rgame/engine/component.rb +34 -10
- data/lib/rgame/engine/components/action_trigger.rb +0 -1
- data/lib/rgame/engine/components/animated_sprite.rb +27 -25
- data/lib/rgame/engine/components/box_collider.rb +99 -0
- data/lib/rgame/engine/components/camera_follow.rb +6 -5
- data/lib/rgame/engine/components/character_body.rb +20 -61
- data/lib/rgame/engine/components/circle_collider.rb +47 -11
- data/lib/rgame/engine/components/collision_world.rb +159 -31
- data/lib/rgame/engine/components/despawn_offscreen.rb +24 -8
- data/lib/rgame/engine/components/feet_collider.rb +61 -0
- data/lib/rgame/engine/components/hop.rb +76 -0
- data/lib/rgame/engine/components/identity.rb +73 -0
- data/lib/rgame/engine/components/mover.rb +285 -0
- data/lib/rgame/engine/components/navigator.rb +145 -0
- data/lib/rgame/engine/components/path_follow.rb +123 -31
- data/lib/rgame/engine/components/player_controller.rb +5 -2
- data/lib/rgame/engine/components/pool.rb +1 -1
- data/lib/rgame/engine/components/screen_wrap.rb +33 -11
- data/lib/rgame/engine/components/sprite.rb +12 -6
- data/lib/rgame/engine/components/targeting.rb +9 -11
- data/lib/rgame/engine/components/thrust_controller.rb +1 -1
- data/lib/rgame/engine/components/tile_world.rb +41 -13
- data/lib/rgame/engine/components/timer.rb +1 -1
- data/lib/rgame/engine/components/velocity.rb +23 -7
- data/lib/rgame/engine/components/wander_controller.rb +6 -2
- data/lib/rgame/engine/components/world.rb +133 -0
- data/lib/rgame/engine/contact_set.rb +74 -0
- data/lib/rgame/engine/culling.rb +4 -6
- data/lib/rgame/engine/debug_overlay.rb +5 -11
- data/lib/rgame/engine/i18n/plural.rb +45 -0
- data/lib/rgame/engine/i18n/plural_rules.rb +82 -0
- data/lib/rgame/engine/i18n/template.rb +59 -0
- data/lib/rgame/engine/i18n.rb +276 -51
- data/lib/rgame/engine/input/action_mapper.rb +0 -26
- data/lib/rgame/engine/input/actions.rb +2 -8
- data/lib/rgame/engine/input/input_map.rb +39 -21
- data/lib/rgame/engine/nav_grid.rb +87 -0
- data/lib/rgame/engine/node2d.rb +248 -133
- data/lib/rgame/engine/path.rb +4 -6
- data/lib/rgame/engine/players.rb +6 -13
- data/lib/rgame/engine/presentation.rb +171 -0
- data/lib/rgame/engine/scene/scene_stack.rb +4 -4
- data/lib/rgame/engine/sealed_privates.rb +54 -0
- data/lib/rgame/engine/spatial_hash.rb +51 -19
- data/lib/rgame/engine/text.rb +194 -0
- data/lib/rgame/engine/tile_blockers.rb +63 -0
- data/lib/rgame/engine/tile_map.rb +2 -3
- data/lib/rgame/engine/tile_map_layer.rb +0 -2
- data/lib/rgame/engine/tileset.rb +2 -4
- data/lib/rgame/engine/timer.rb +2 -2
- data/lib/rgame/engine/ui/button.rb +248 -0
- data/lib/rgame/engine/ui/column.rb +20 -0
- data/lib/rgame/engine/ui/icon_button.rb +93 -0
- data/lib/rgame/engine/ui/menu.rb +246 -71
- data/lib/rgame/engine/ui/navigation.rb +57 -0
- data/lib/rgame/engine/ui/nine_slice_style.rb +50 -0
- data/lib/rgame/engine/ui/option_button.rb +163 -0
- data/lib/rgame/engine/ui/panel_button.rb +32 -0
- data/lib/rgame/engine/ui/panel_menu.rb +36 -0
- data/lib/rgame/engine/ui/pointing.rb +146 -0
- data/lib/rgame/engine/ui/radial_menu.rb +85 -0
- data/lib/rgame/engine/ui/ring.rb +55 -0
- data/lib/rgame/engine/ui/row.rb +21 -0
- data/lib/rgame/engine/ui/shape_style.rb +102 -0
- data/lib/rgame/engine/ui/stack.rb +58 -0
- data/lib/rgame/engine/ui/stepping.rb +93 -0
- data/lib/rgame/engine/ui/text_button.rb +59 -0
- data/lib/rgame/engine/viewports.rb +2 -5
- data/lib/rgame/engine/world_view.rb +5 -4
- data/lib/rgame/engine.rb +31 -25
- data/lib/rgame/game.rb +99 -27
- data/lib/rgame/rubocop/cop/game/draw_in_local_space.rb +103 -0
- data/lib/rgame/rubocop/cop/game/hot_path.rb +36 -0
- data/lib/rgame/rubocop/cop/game/layer_boundary.rb +43 -0
- data/lib/rgame/rubocop/cop/game/no_core_in_engine_layer.rb +100 -0
- data/lib/rgame/rubocop/cop/game/no_engine_in_core_layer.rb +84 -0
- data/lib/rgame/rubocop/cop/game/no_interpolation_in_hot_path.rb +50 -0
- data/lib/rgame/rubocop/cop/game/no_literal_text.rb +41 -0
- data/lib/rgame/rubocop/cop/game/no_needless_allocation.rb +112 -0
- data/lib/rgame/rubocop/default.yml +39 -0
- data/lib/rgame/rubocop/plugin.rb +45 -0
- data/lib/rgame/rubocop.rb +11 -0
- data/lib/rgame/util/color.rb +20 -24
- data/lib/rgame/util/controls.rb +14 -28
- data/lib/rgame/util/route_search.rb +27 -0
- data/lib/rgame/util/save_file.rb +107 -0
- data/lib/rgame/util/solid_grid.rb +37 -0
- data/lib/rgame/util/tensor.rb +0 -9
- data/lib/rgame/util/tile_sweep.rb +36 -0
- data/lib/rgame/util/z.rb +4 -14
- data/lib/rgame/util.rb +4 -3
- data/lib/rgame/version.rb +1 -1
- data/lib/rgame.rb +0 -15
- metadata +152 -11
- data/lib/rgame/engine/actor.rb +0 -53
- data/lib/rgame/engine/body.rb +0 -49
- data/lib/rgame/engine/cached_label.rb +0 -33
- data/lib/rgame/engine/input/player_controller.rb +0 -14
- data/lib/rgame/engine/matrix.rb +0 -32
- data/lib/rgame/engine/resettable.rb +0 -67
- data/lib/rgame/engine/tile_collision.rb +0 -78
- data/lib/rgame/engine/ui/menu_item.rb +0 -84
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'json'
|
|
4
|
+
require 'fileutils'
|
|
5
|
+
|
|
6
|
+
module RGame
|
|
7
|
+
module Util
|
|
8
|
+
# A game's saved state, as one JSON file.
|
|
9
|
+
#
|
|
10
|
+
# save = SaveFile.new('slot1.json', game: 'sheepdog')
|
|
11
|
+
# save.write(dog: [120, 80], sheep: [[40, 40], [90, 30]])
|
|
12
|
+
# save.read # => { dog: [120, 80], sheep: [...] }
|
|
13
|
+
# save.read.fetch(:dog, nil) # => nil when there is no save yet
|
|
14
|
+
#
|
|
15
|
+
# It holds no open handle — it opens, reads or writes, and closes — which is
|
|
16
|
+
# why this is `Util` rather than `Core` (see CLAUDE.md, "Value objects go in
|
|
17
|
+
# Util"). JSON comes from the standard library, so nothing here adds a
|
|
18
|
+
# runtime dependency.
|
|
19
|
+
#
|
|
20
|
+
# ## Reading never raises
|
|
21
|
+
#
|
|
22
|
+
# `read` answers with the default for a file that is missing, empty,
|
|
23
|
+
# truncated, not JSON, or JSON that is not an object. That is deliberate and
|
|
24
|
+
# it is the whole reason this class exists rather than three lines of
|
|
25
|
+
# `JSON.parse(File.read(...))` at a call site.
|
|
26
|
+
#
|
|
27
|
+
# A save file is the one input a game has that it did not produce this run.
|
|
28
|
+
# It survives crashes, disk-full, a killed process mid-write, an editor, and
|
|
29
|
+
# a copy from someone else's machine. A game that raises on any of those is
|
|
30
|
+
# a game that cannot be started again, and the player's only fix is to find
|
|
31
|
+
# and delete a file they were never told about. Losing a save is bad;
|
|
32
|
+
# refusing to launch is worse.
|
|
33
|
+
#
|
|
34
|
+
# **Writing still raises.** A read failure has a sensible answer — "there is
|
|
35
|
+
# no save" — and a write failure does not: silently discarding the player's
|
|
36
|
+
# progress is the failure that gets noticed hours later. A caller that wants
|
|
37
|
+
# to survive a full disk can rescue; it cannot un-swallow an exception this
|
|
38
|
+
# class never raised.
|
|
39
|
+
#
|
|
40
|
+
# ## Writing is atomic
|
|
41
|
+
#
|
|
42
|
+
# `write` writes a temporary file beside the target and renames it over the
|
|
43
|
+
# top. `File.rename` within one directory is atomic on every platform this
|
|
44
|
+
# engine supports, so a save is either the old one or the new one and never
|
|
45
|
+
# half of each.
|
|
46
|
+
#
|
|
47
|
+
# This matters more than it sounds: the moment a game most wants to save is
|
|
48
|
+
# on the way out, which is also the moment it is most likely to be killed.
|
|
49
|
+
# A plain `File.write` truncates first and fills in after, so a crash in
|
|
50
|
+
# between leaves a zero-byte file where the player's afternoon used to be.
|
|
51
|
+
class SaveFile
|
|
52
|
+
# Where saves go, per platform, following each one's own convention rather
|
|
53
|
+
# than dropping a dotfile in the home directory:
|
|
54
|
+
#
|
|
55
|
+
# Linux $XDG_DATA_HOME/<game>, or ~/.local/share/<game>
|
|
56
|
+
# macOS ~/Library/Application Support/<game>
|
|
57
|
+
# Windows %APPDATA%\<game>
|
|
58
|
+
#
|
|
59
|
+
# `game` names the directory, so two games do not share a save.
|
|
60
|
+
def self.directory(game)
|
|
61
|
+
case RbConfig::CONFIG['host_os']
|
|
62
|
+
when /darwin/ then File.join(Dir.home, 'Library', 'Application Support', game)
|
|
63
|
+
when /mswin|mingw|cygwin/ then File.join(ENV.fetch('APPDATA', Dir.home), game)
|
|
64
|
+
else File.join(ENV.fetch('XDG_DATA_HOME', File.join(Dir.home, '.local', 'share')), game)
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
|
|
68
|
+
attr_reader :path
|
|
69
|
+
|
|
70
|
+
# `name` is a file name inside the game's save directory; pass `dir:` to
|
|
71
|
+
# put it somewhere else, which is what a spec does.
|
|
72
|
+
def initialize(name, game: 'rgame', dir: nil)
|
|
73
|
+
@path = File.join(dir || SaveFile.directory(game), name)
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
def exist? = File.exist?(@path)
|
|
77
|
+
|
|
78
|
+
# The saved state, or `default` if there is nothing usable to read. Keys
|
|
79
|
+
# come back as Symbols, so a game writes and reads the same shape.
|
|
80
|
+
def read(default = {})
|
|
81
|
+
parsed = JSON.parse(File.read(@path), symbolize_names: true)
|
|
82
|
+
parsed.is_a?(Hash) ? parsed : default
|
|
83
|
+
rescue Errno::ENOENT, Errno::EACCES, Errno::EISDIR, JSON::ParserError
|
|
84
|
+
default
|
|
85
|
+
end
|
|
86
|
+
|
|
87
|
+
# Writes `state` as JSON, atomically. Creates the directory if it is not
|
|
88
|
+
# there — a first save on a fresh machine is the normal case, not an error.
|
|
89
|
+
def write(state)
|
|
90
|
+
FileUtils.mkdir_p(File.dirname(@path))
|
|
91
|
+
temporary = "#{@path}.#{Process.pid}.tmp"
|
|
92
|
+
File.write(temporary, JSON.pretty_generate(state))
|
|
93
|
+
File.rename(temporary, @path)
|
|
94
|
+
self
|
|
95
|
+
end
|
|
96
|
+
|
|
97
|
+
# Removes the save, and says nothing if there was not one. "Delete my
|
|
98
|
+
# save" and "there was no save" leave the player in the same place.
|
|
99
|
+
def delete
|
|
100
|
+
File.unlink(@path)
|
|
101
|
+
self
|
|
102
|
+
rescue Errno::ENOENT
|
|
103
|
+
self
|
|
104
|
+
end
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rgame/util_ext'
|
|
4
|
+
|
|
5
|
+
module RGame
|
|
6
|
+
module Util
|
|
7
|
+
# Which cells of a tile grid are solid: one byte a cell, in C. A value with no handle
|
|
8
|
+
# behind it, which is why it lives in Util and why the engine layer may own one.
|
|
9
|
+
#
|
|
10
|
+
# It is the one store a tile world's solidity lives in. The blockers that stop a walker
|
|
11
|
+
# and the RouteSearch that plans one both read it, so they cannot disagree about a wall,
|
|
12
|
+
# and a cell changed with #set_solid is changed for both at once.
|
|
13
|
+
#
|
|
14
|
+
# #revision counts the changes: it moves on a #set_solid that changes a cell and on no
|
|
15
|
+
# other, so anything derived from the cells — a search's region labels — can tell
|
|
16
|
+
# whether it is stale without being told.
|
|
17
|
+
#
|
|
18
|
+
# Coordinates are Integers, and anything else is a TypeError. Outside the grid is open,
|
|
19
|
+
# including an Integer too large to be inside any grid.
|
|
20
|
+
#
|
|
21
|
+
# grid = RGame::Util::SolidGrid.build(8, 3) { |col, _row| col == 3 }
|
|
22
|
+
# grid.solid?(3, 1) # => true
|
|
23
|
+
# grid.solid?(-1, 0) # => false
|
|
24
|
+
# grid.set_solid(3, 1, false)
|
|
25
|
+
# grid.revision # => 1
|
|
26
|
+
class SolidGrid
|
|
27
|
+
# A grid with each cell's solidity read from the block, once per cell, row by row.
|
|
28
|
+
def self.build(width, height)
|
|
29
|
+
grid = new(width, height)
|
|
30
|
+
height.times do |row|
|
|
31
|
+
width.times { |col| grid.set_solid(col, row, true) if yield(col, row) }
|
|
32
|
+
end
|
|
33
|
+
grid
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
end
|
data/lib/rgame/util/tensor.rb
CHANGED
|
@@ -1,12 +1,3 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# RGame::Util::Tensor is implemented in C — see ext/rgame_util/tensor.c. It used
|
|
4
|
-
# to be a pure-Ruby class here; the public API (RGame::Util::Tensor.new(width,
|
|
5
|
-
# height, depth, initial: nil), #[], #[]=, #width/#height/#depth) is unchanged,
|
|
6
|
-
# only the backing implementation moved to C for speed and a compact flat-array
|
|
7
|
-
# layout.
|
|
8
|
-
#
|
|
9
|
-
# The compiled extension is a separate .so from the SDL/GL engine, so requiring
|
|
10
|
-
# Tensor pulls in no graphics libraries. It loads from lib/rgame/util_ext.so,
|
|
11
|
-
# which the build (`make ext-util`) copies out of ext/rgame_util/.
|
|
12
3
|
require 'rgame/util_ext'
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'rgame/util_ext'
|
|
4
|
+
|
|
5
|
+
module RGame
|
|
6
|
+
module Util
|
|
7
|
+
# An axis-aligned box against the solid tiles of a SolidGrid, in C. It reads its grid and
|
|
8
|
+
# never writes it, and keeps it alive; any number of sweeps may read one grid, so a change
|
|
9
|
+
# made with SolidGrid#set_solid is seen by all of them at once.
|
|
10
|
+
#
|
|
11
|
+
# It answers two questions with one piece of arithmetic, so they cannot disagree:
|
|
12
|
+
#
|
|
13
|
+
# - **#resolve_x / #resolve_y** — where the box's left (top) edge lands moving dx (dy). A
|
|
14
|
+
# step that would enter a solid tile snaps the box flush against that tile's edge. Each
|
|
15
|
+
# axis is resolved on its own. The step is assumed smaller than a tile; a longer one can
|
|
16
|
+
# pass through a tile without seeing it.
|
|
17
|
+
# - **#travel?** — whether the box can move by (dx, dy) without any resolve along the way
|
|
18
|
+
# falling short of where it was heading. The box is swept in overlapping windows half a
|
|
19
|
+
# tile long, a quarter tile apart, each resolved X-then-Y and Y-then-X, which makes the
|
|
20
|
+
# answer sound for a walker that resolves its own steps and steps less than a quarter tile
|
|
21
|
+
# at a time.
|
|
22
|
+
#
|
|
23
|
+
# Boxes are given by their top-left corner and size, in pixels. Outside the grid is open.
|
|
24
|
+
# Results are Floats. A coordinate that is not a number is a TypeError; a non-finite one is
|
|
25
|
+
# a FloatDomainError, except in a resolve with no movement, which returns the box where it
|
|
26
|
+
# is.
|
|
27
|
+
#
|
|
28
|
+
# grid = RGame::Util::SolidGrid.build(20, 15) { |col, _row| col == 5 } # a wall at x 80..96
|
|
29
|
+
# sweep = RGame::Util::TileSweep.new(grid, 16, 16)
|
|
30
|
+
# sweep.resolve_x(58.0, 32.0, 12, 6, 14.0) # => 68.0, flush against the wall
|
|
31
|
+
# sweep.travel?(10.0, 32.0, 12, 6, 50.0, 0) # => true
|
|
32
|
+
# sweep.travel?(10.0, 32.0, 12, 6, 90.0, 0) # => false
|
|
33
|
+
class TileSweep
|
|
34
|
+
end
|
|
35
|
+
end
|
|
36
|
+
end
|
data/lib/rgame/util/z.rb
CHANGED
|
@@ -45,29 +45,15 @@ module RGame
|
|
|
45
45
|
# swapping places between frames, and would be very hard to see as a
|
|
46
46
|
# precision problem.
|
|
47
47
|
module Z
|
|
48
|
-
# How much room a node has for ordering its own drawing. Nothing in this
|
|
49
|
-
# repo uses more than three offsets; a thousand is room to stop thinking
|
|
50
|
-
# about it.
|
|
51
48
|
SLOT = 1024
|
|
52
49
|
HALF = SLOT / 2
|
|
53
50
|
|
|
54
|
-
# What a `z:` argument on a drawing call may be. Signed, because a node
|
|
55
|
-
# drawing something *behind* its sprite is as ordinary as drawing
|
|
56
|
-
# something in front of it, and the sprite's own default is 0.
|
|
57
51
|
Z_MIN = -HALF
|
|
58
52
|
Z_MAX = HALF - 1
|
|
59
53
|
|
|
60
|
-
# The gap between bands: 2**30 slots each, which no frame will approach.
|
|
61
54
|
STRIDE = 1 << 40
|
|
62
55
|
SLOTS_PER_BAND = STRIDE / SLOT
|
|
63
56
|
|
|
64
|
-
# In order, back to front.
|
|
65
|
-
#
|
|
66
|
-
# `:world` is what a node with no band ancestor is in, so a game that
|
|
67
|
-
# never mentions a band is entirely in it. `:hud` is one player's own
|
|
68
|
-
# screen space (RGame::Engine::PlayerLayer), `:overlay` is screen space
|
|
69
|
-
# across the whole window — a cutscene, a results panel — and `:debug` is
|
|
70
|
-
# the development overlay, over everything by construction.
|
|
71
57
|
BANDS = %i[world hud overlay debug].freeze
|
|
72
58
|
DEFAULT = :world
|
|
73
59
|
|
|
@@ -78,6 +64,8 @@ module RGame
|
|
|
78
64
|
# Raises unless `band` names one. Called where a band is *set* rather than
|
|
79
65
|
# where it is used, so a typo surfaces at assignment with the list in the
|
|
80
66
|
# message instead of as a KeyError from inside a draw.
|
|
67
|
+
#
|
|
68
|
+
# @api private
|
|
81
69
|
def self.band!(band)
|
|
82
70
|
return band if band?(band)
|
|
83
71
|
|
|
@@ -97,6 +85,8 @@ module RGame
|
|
|
97
85
|
# Takes the band's *index* rather than its name because a renderer already
|
|
98
86
|
# has the index in hand (it counts slots per index), and looking the same
|
|
99
87
|
# Symbol up twice per node per frame is work with nothing to show for it.
|
|
88
|
+
#
|
|
89
|
+
# @api private
|
|
100
90
|
# hot-path
|
|
101
91
|
def self.slot_base(band_index, slot_index)
|
|
102
92
|
if slot_index >= SLOTS_PER_BAND
|
data/lib/rgame/util.rb
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# RGame::Util — everything that does NOT depend on SDL, OpenGL, or anything
|
|
4
|
-
# built on them. Backed by the graphics-free extension in ext/rgame_util/.
|
|
5
|
-
# Its counterpart is RGame::Core (see lib/rgame/core.rb).
|
|
6
3
|
require_relative 'util/color'
|
|
7
4
|
require_relative 'util/controls'
|
|
5
|
+
require_relative 'util/route_search'
|
|
6
|
+
require_relative 'util/save_file'
|
|
7
|
+
require_relative 'util/solid_grid'
|
|
8
8
|
require_relative 'util/tensor'
|
|
9
|
+
require_relative 'util/tile_sweep'
|
|
9
10
|
require_relative 'util/z'
|
data/lib/rgame/version.rb
CHANGED
data/lib/rgame.rb
CHANGED
|
@@ -1,20 +1,5 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
# Entry point for `require "rgame"`: everything that runs without a window.
|
|
4
|
-
#
|
|
5
|
-
# require 'rgame' # RGame::Util + RGame::Engine — no graphics libraries
|
|
6
|
-
# require 'rgame/core' # adds the window, the GPU and the sound device
|
|
7
|
-
# require 'rgame/game' # all of it, wired together
|
|
8
|
-
#
|
|
9
|
-
# Each line is a strict superset of the one above, and the split is the point.
|
|
10
|
-
# **This one loads no SDL and no OpenGL** — `RGame::Util` is a graphics-free
|
|
11
|
-
# extension and `RGame::Engine` is pure Ruby — so game logic and the specs that
|
|
12
|
-
# cover it run with no display present. `spec/rgame/no_graphics_spec.rb` holds
|
|
13
|
-
# that up rather than leaving it to good intentions.
|
|
14
|
-
#
|
|
15
|
-
# Nothing is forced through this file. `rgame/util`, `rgame/engine` and
|
|
16
|
-
# `rgame/core` are separately requirable, which is how the Core spec suite loads
|
|
17
|
-
# exactly one layer and gets a `NameError` if it reaches for another.
|
|
18
3
|
require_relative 'rgame/version'
|
|
19
4
|
require_relative 'rgame/util'
|
|
20
5
|
require_relative 'rgame/engine'
|
metadata
CHANGED
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: rgame
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.3.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Paul Süßenbach
|
|
8
|
-
bindir:
|
|
8
|
+
bindir: exe
|
|
9
9
|
cert_chain: []
|
|
10
10
|
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
11
|
dependencies: []
|
|
@@ -21,7 +21,8 @@ description: |
|
|
|
21
21
|
collision systems, debugging tools and an UI toolkit.
|
|
22
22
|
email:
|
|
23
23
|
- 2452696+psuessenb@users.noreply.github.com
|
|
24
|
-
executables:
|
|
24
|
+
executables:
|
|
25
|
+
- rgame
|
|
25
26
|
extensions:
|
|
26
27
|
- ext/rgame_core/extconf.rb
|
|
27
28
|
- ext/rgame_util/extconf.rb
|
|
@@ -34,24 +35,96 @@ files:
|
|
|
34
35
|
- docs/api/app.md
|
|
35
36
|
- docs/api/assets.md
|
|
36
37
|
- docs/api/audio.md
|
|
38
|
+
- docs/api/cli.md
|
|
37
39
|
- docs/api/components.md
|
|
38
40
|
- docs/api/drawing.md
|
|
41
|
+
- docs/api/examples.md
|
|
39
42
|
- docs/api/game.md
|
|
40
43
|
- docs/api/images.md
|
|
41
44
|
- docs/api/input.md
|
|
42
45
|
- docs/api/internals.md
|
|
46
|
+
- docs/api/localization.md
|
|
43
47
|
- docs/api/scene_graph.md
|
|
44
48
|
- docs/api/signals.md
|
|
45
49
|
- docs/api/systems.md
|
|
46
50
|
- docs/api/text.md
|
|
51
|
+
- docs/api/tile_maps.md
|
|
47
52
|
- docs/api/toolbox.md
|
|
48
53
|
- docs/api/ui.md
|
|
49
54
|
- docs/api/values.md
|
|
55
|
+
- examples/assets/README.md
|
|
56
|
+
- examples/assets/blip.ogg
|
|
57
|
+
- examples/assets/glyphs.json
|
|
58
|
+
- examples/assets/glyphs.png
|
|
59
|
+
- examples/assets/hero.json
|
|
60
|
+
- examples/assets/hero.png
|
|
61
|
+
- examples/assets/icons.json
|
|
62
|
+
- examples/assets/icons.png
|
|
63
|
+
- examples/assets/music.ogg
|
|
64
|
+
- examples/assets/skills.json
|
|
65
|
+
- examples/assets/skills.png
|
|
66
|
+
- examples/assets/tileset.png
|
|
67
|
+
- examples/assets/tileset.tsx
|
|
68
|
+
- examples/assets/town.tmx
|
|
69
|
+
- examples/assets/ui.json
|
|
70
|
+
- examples/assets/ui.png
|
|
71
|
+
- examples/collision/locales/en.yml
|
|
72
|
+
- examples/collision/main.rb
|
|
73
|
+
- examples/collision_tiles/locales/en.yml
|
|
74
|
+
- examples/collision_tiles/main.rb
|
|
75
|
+
- examples/fullscreen/locales/en.yml
|
|
76
|
+
- examples/fullscreen/main.rb
|
|
77
|
+
- examples/game_menu/locales/en.yml
|
|
78
|
+
- examples/game_menu/main.rb
|
|
79
|
+
- examples/input_glyphs/locales/en.yml
|
|
80
|
+
- examples/input_glyphs/main.rb
|
|
81
|
+
- examples/jump_topdown/locales/en.yml
|
|
82
|
+
- examples/jump_topdown/main.rb
|
|
83
|
+
- examples/localization/locales/de.yml
|
|
84
|
+
- examples/localization/locales/en.yml
|
|
85
|
+
- examples/localization/main.rb
|
|
86
|
+
- examples/menu_navigation/locales/en.yml
|
|
87
|
+
- examples/menu_navigation/main.rb
|
|
88
|
+
- examples/music/locales/en.yml
|
|
89
|
+
- examples/music/main.rb
|
|
90
|
+
- examples/pathfinding/locales/en.yml
|
|
91
|
+
- examples/pathfinding/main.rb
|
|
92
|
+
- examples/pooling/locales/en.yml
|
|
93
|
+
- examples/pooling/main.rb
|
|
94
|
+
- examples/quick_wheel/locales/en.yml
|
|
95
|
+
- examples/quick_wheel/main.rb
|
|
96
|
+
- examples/radial_menu/locales/en.yml
|
|
97
|
+
- examples/radial_menu/main.rb
|
|
98
|
+
- examples/save_load/locales/en.yml
|
|
99
|
+
- examples/save_load/main.rb
|
|
100
|
+
- examples/save_load_ids/locales/en.yml
|
|
101
|
+
- examples/save_load_ids/main.rb
|
|
102
|
+
- examples/scroll_map/locales/en.yml
|
|
103
|
+
- examples/scroll_map/main.rb
|
|
104
|
+
- examples/signals/locales/en.yml
|
|
105
|
+
- examples/signals/main.rb
|
|
106
|
+
- examples/skill_bar/locales/en.yml
|
|
107
|
+
- examples/skill_bar/main.rb
|
|
108
|
+
- examples/sound/locales/en.yml
|
|
109
|
+
- examples/sound/main.rb
|
|
110
|
+
- examples/split_screen/locales/en.yml
|
|
111
|
+
- examples/split_screen/main.rb
|
|
112
|
+
- examples/sprite/locales/en.yml
|
|
113
|
+
- examples/sprite/main.rb
|
|
114
|
+
- examples/timer/locales/en.yml
|
|
115
|
+
- examples/timer/main.rb
|
|
116
|
+
- examples/velocity/locales/en.yml
|
|
117
|
+
- examples/velocity/main.rb
|
|
118
|
+
- examples/walk/locales/en.yml
|
|
119
|
+
- examples/walk/main.rb
|
|
120
|
+
- exe/rgame
|
|
50
121
|
- ext/README.md
|
|
51
122
|
- ext/rgame_core/app/app.c
|
|
52
123
|
- ext/rgame_core/app/app_gl.h
|
|
53
124
|
- ext/rgame_core/app/frame_loop.c
|
|
54
125
|
- ext/rgame_core/app/frame_loop.h
|
|
126
|
+
- ext/rgame_core/app/locale.c
|
|
127
|
+
- ext/rgame_core/app/locale.h
|
|
55
128
|
- ext/rgame_core/audio/audio.c
|
|
56
129
|
- ext/rgame_core/audio/audio_internal.h
|
|
57
130
|
- ext/rgame_core/audio/vorbis_decoder.c
|
|
@@ -90,6 +163,7 @@ files:
|
|
|
90
163
|
- ext/rgame_core/ruby/core_ext.h
|
|
91
164
|
- ext/rgame_core/ruby/font_ext.c
|
|
92
165
|
- ext/rgame_core/ruby/image_ext.c
|
|
166
|
+
- ext/rgame_core/ruby/locale_ext.c
|
|
93
167
|
- ext/rgame_core/ruby/recording_ext.c
|
|
94
168
|
- ext/rgame_core/ruby/renderer_ext.c
|
|
95
169
|
- ext/rgame_core/text/atlas.c
|
|
@@ -113,11 +187,36 @@ files:
|
|
|
113
187
|
- ext/rgame_util/color.h
|
|
114
188
|
- ext/rgame_util/color_ext.c
|
|
115
189
|
- ext/rgame_util/extconf.rb
|
|
190
|
+
- ext/rgame_util/route_search.c
|
|
191
|
+
- ext/rgame_util/route_search.h
|
|
192
|
+
- ext/rgame_util/route_search_ext.c
|
|
193
|
+
- ext/rgame_util/solid_grid.c
|
|
194
|
+
- ext/rgame_util/solid_grid.h
|
|
195
|
+
- ext/rgame_util/solid_grid_ext.c
|
|
116
196
|
- ext/rgame_util/tensor.c
|
|
197
|
+
- ext/rgame_util/tile_sweep.c
|
|
198
|
+
- ext/rgame_util/tile_sweep.h
|
|
199
|
+
- ext/rgame_util/tile_sweep_ext.c
|
|
117
200
|
- ext/rgame_util/util_ext.c
|
|
118
201
|
- ext/rgame_util/util_ext.h
|
|
119
202
|
- lib/rgame.rb
|
|
120
203
|
- lib/rgame/boot.rb
|
|
204
|
+
- lib/rgame/cli.rb
|
|
205
|
+
- lib/rgame/cli/new_project.rb
|
|
206
|
+
- lib/rgame/cli/templates/Gemfile.tt
|
|
207
|
+
- lib/rgame/cli/templates/README.md.tt
|
|
208
|
+
- lib/rgame/cli/templates/Rakefile.tt
|
|
209
|
+
- lib/rgame/cli/templates/assets/locales/en.yml.tt
|
|
210
|
+
- lib/rgame/cli/templates/game.rb.tt
|
|
211
|
+
- lib/rgame/cli/templates/gitignore.tt
|
|
212
|
+
- lib/rgame/cli/templates/main.rb.tt
|
|
213
|
+
- lib/rgame/cli/templates/nodes/root.rb.tt
|
|
214
|
+
- lib/rgame/cli/templates/rspec.tt
|
|
215
|
+
- lib/rgame/cli/templates/rubocop.yml.tt
|
|
216
|
+
- lib/rgame/cli/templates/ruby-version.tt
|
|
217
|
+
- lib/rgame/cli/templates/spec/locales_spec.rb.tt
|
|
218
|
+
- lib/rgame/cli/templates/spec/nodes/root_spec.rb.tt
|
|
219
|
+
- lib/rgame/cli/templates/spec/spec_helper.rb.tt
|
|
121
220
|
- lib/rgame/core.rb
|
|
122
221
|
- lib/rgame/core/app.rb
|
|
123
222
|
- lib/rgame/core/asset_manager.rb
|
|
@@ -126,6 +225,7 @@ files:
|
|
|
126
225
|
- lib/rgame/core/gamepad.rb
|
|
127
226
|
- lib/rgame/core/image.rb
|
|
128
227
|
- lib/rgame/core/input.rb
|
|
228
|
+
- lib/rgame/core/locale.rb
|
|
129
229
|
- lib/rgame/core/nine_slice.rb
|
|
130
230
|
- lib/rgame/core/recording.rb
|
|
131
231
|
- lib/rgame/core/renderer.rb
|
|
@@ -133,13 +233,12 @@ files:
|
|
|
133
233
|
- lib/rgame/core/tile_map_renderer.rb
|
|
134
234
|
- lib/rgame/core/ui_atlas.rb
|
|
135
235
|
- lib/rgame/engine.rb
|
|
136
|
-
- lib/rgame/engine/
|
|
236
|
+
- lib/rgame/engine/actor_blockers.rb
|
|
137
237
|
- lib/rgame/engine/animation_set.rb
|
|
138
238
|
- lib/rgame/engine/animator.rb
|
|
139
239
|
- lib/rgame/engine/audio_bus.rb
|
|
140
240
|
- lib/rgame/engine/audio_director.rb
|
|
141
|
-
- lib/rgame/engine/
|
|
142
|
-
- lib/rgame/engine/cached_label.rb
|
|
241
|
+
- lib/rgame/engine/bounds_blockers.rb
|
|
143
242
|
- lib/rgame/engine/camera.rb
|
|
144
243
|
- lib/rgame/engine/circle_collider.rb
|
|
145
244
|
- lib/rgame/engine/collision_box.rb
|
|
@@ -147,11 +246,17 @@ files:
|
|
|
147
246
|
- lib/rgame/engine/component.rb
|
|
148
247
|
- lib/rgame/engine/components/action_trigger.rb
|
|
149
248
|
- lib/rgame/engine/components/animated_sprite.rb
|
|
249
|
+
- lib/rgame/engine/components/box_collider.rb
|
|
150
250
|
- lib/rgame/engine/components/camera_follow.rb
|
|
151
251
|
- lib/rgame/engine/components/character_body.rb
|
|
152
252
|
- lib/rgame/engine/components/circle_collider.rb
|
|
153
253
|
- lib/rgame/engine/components/collision_world.rb
|
|
154
254
|
- lib/rgame/engine/components/despawn_offscreen.rb
|
|
255
|
+
- lib/rgame/engine/components/feet_collider.rb
|
|
256
|
+
- lib/rgame/engine/components/hop.rb
|
|
257
|
+
- lib/rgame/engine/components/identity.rb
|
|
258
|
+
- lib/rgame/engine/components/mover.rb
|
|
259
|
+
- lib/rgame/engine/components/navigator.rb
|
|
155
260
|
- lib/rgame/engine/components/path_follow.rb
|
|
156
261
|
- lib/rgame/engine/components/player_controller.rb
|
|
157
262
|
- lib/rgame/engine/components/pool.rb
|
|
@@ -163,42 +268,78 @@ files:
|
|
|
163
268
|
- lib/rgame/engine/components/timer.rb
|
|
164
269
|
- lib/rgame/engine/components/velocity.rb
|
|
165
270
|
- lib/rgame/engine/components/wander_controller.rb
|
|
271
|
+
- lib/rgame/engine/components/world.rb
|
|
272
|
+
- lib/rgame/engine/contact_set.rb
|
|
166
273
|
- lib/rgame/engine/culling.rb
|
|
167
274
|
- lib/rgame/engine/debug_overlay.rb
|
|
168
275
|
- lib/rgame/engine/i18n.rb
|
|
276
|
+
- lib/rgame/engine/i18n/plural.rb
|
|
277
|
+
- lib/rgame/engine/i18n/plural_rules.rb
|
|
278
|
+
- lib/rgame/engine/i18n/template.rb
|
|
169
279
|
- lib/rgame/engine/input/action_mapper.rb
|
|
170
280
|
- lib/rgame/engine/input/actions.rb
|
|
171
281
|
- lib/rgame/engine/input/input_map.rb
|
|
172
|
-
- lib/rgame/engine/input/player_controller.rb
|
|
173
282
|
- lib/rgame/engine/layout.rb
|
|
174
|
-
- lib/rgame/engine/
|
|
283
|
+
- lib/rgame/engine/nav_grid.rb
|
|
175
284
|
- lib/rgame/engine/node2d.rb
|
|
176
285
|
- lib/rgame/engine/path.rb
|
|
177
286
|
- lib/rgame/engine/player.rb
|
|
178
287
|
- lib/rgame/engine/player_layer.rb
|
|
179
288
|
- lib/rgame/engine/players.rb
|
|
180
289
|
- lib/rgame/engine/pool.rb
|
|
181
|
-
- lib/rgame/engine/
|
|
290
|
+
- lib/rgame/engine/presentation.rb
|
|
182
291
|
- lib/rgame/engine/scene/scene_stack.rb
|
|
292
|
+
- lib/rgame/engine/sealed_privates.rb
|
|
183
293
|
- lib/rgame/engine/signal.rb
|
|
184
294
|
- lib/rgame/engine/spatial_hash.rb
|
|
185
|
-
- lib/rgame/engine/
|
|
295
|
+
- lib/rgame/engine/text.rb
|
|
296
|
+
- lib/rgame/engine/tile_blockers.rb
|
|
186
297
|
- lib/rgame/engine/tile_map.rb
|
|
187
298
|
- lib/rgame/engine/tile_map_layer.rb
|
|
188
299
|
- lib/rgame/engine/tileset.rb
|
|
189
300
|
- lib/rgame/engine/timer.rb
|
|
301
|
+
- lib/rgame/engine/ui/button.rb
|
|
302
|
+
- lib/rgame/engine/ui/column.rb
|
|
303
|
+
- lib/rgame/engine/ui/icon_button.rb
|
|
190
304
|
- lib/rgame/engine/ui/menu.rb
|
|
191
|
-
- lib/rgame/engine/ui/
|
|
305
|
+
- lib/rgame/engine/ui/navigation.rb
|
|
306
|
+
- lib/rgame/engine/ui/nine_slice_style.rb
|
|
307
|
+
- lib/rgame/engine/ui/option_button.rb
|
|
308
|
+
- lib/rgame/engine/ui/panel_button.rb
|
|
309
|
+
- lib/rgame/engine/ui/panel_menu.rb
|
|
310
|
+
- lib/rgame/engine/ui/pointing.rb
|
|
311
|
+
- lib/rgame/engine/ui/radial_menu.rb
|
|
312
|
+
- lib/rgame/engine/ui/ring.rb
|
|
313
|
+
- lib/rgame/engine/ui/row.rb
|
|
314
|
+
- lib/rgame/engine/ui/shape_style.rb
|
|
315
|
+
- lib/rgame/engine/ui/stack.rb
|
|
316
|
+
- lib/rgame/engine/ui/stepping.rb
|
|
317
|
+
- lib/rgame/engine/ui/text_button.rb
|
|
192
318
|
- lib/rgame/engine/view.rb
|
|
193
319
|
- lib/rgame/engine/viewports.rb
|
|
194
320
|
- lib/rgame/engine/world_view.rb
|
|
195
321
|
- lib/rgame/fonts/LiberationSans-Regular.ttf
|
|
196
322
|
- lib/rgame/fonts/OFL.txt
|
|
197
323
|
- lib/rgame/game.rb
|
|
324
|
+
- lib/rgame/rubocop.rb
|
|
325
|
+
- lib/rgame/rubocop/cop/game/draw_in_local_space.rb
|
|
326
|
+
- lib/rgame/rubocop/cop/game/hot_path.rb
|
|
327
|
+
- lib/rgame/rubocop/cop/game/layer_boundary.rb
|
|
328
|
+
- lib/rgame/rubocop/cop/game/no_core_in_engine_layer.rb
|
|
329
|
+
- lib/rgame/rubocop/cop/game/no_engine_in_core_layer.rb
|
|
330
|
+
- lib/rgame/rubocop/cop/game/no_interpolation_in_hot_path.rb
|
|
331
|
+
- lib/rgame/rubocop/cop/game/no_literal_text.rb
|
|
332
|
+
- lib/rgame/rubocop/cop/game/no_needless_allocation.rb
|
|
333
|
+
- lib/rgame/rubocop/default.yml
|
|
334
|
+
- lib/rgame/rubocop/plugin.rb
|
|
198
335
|
- lib/rgame/util.rb
|
|
199
336
|
- lib/rgame/util/color.rb
|
|
200
337
|
- lib/rgame/util/controls.rb
|
|
338
|
+
- lib/rgame/util/route_search.rb
|
|
339
|
+
- lib/rgame/util/save_file.rb
|
|
340
|
+
- lib/rgame/util/solid_grid.rb
|
|
201
341
|
- lib/rgame/util/tensor.rb
|
|
342
|
+
- lib/rgame/util/tile_sweep.rb
|
|
202
343
|
- lib/rgame/util/z.rb
|
|
203
344
|
- lib/rgame/version.rb
|
|
204
345
|
homepage: https://github.com/psuessenb/rgame
|
data/lib/rgame/engine/actor.rb
DELETED
|
@@ -1,53 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RGame
|
|
4
|
-
module Engine
|
|
5
|
-
# A character in the world. Composes the pieces it owns — a collision box, an
|
|
6
|
-
# animator, a sprite id (the renderer maps it to a sheet), and a controller that
|
|
7
|
-
# decides movement — rather than baking them in. Pure logic; no graphics.
|
|
8
|
-
#
|
|
9
|
-
# The controller responds to `intent(dt, input) -> [ix, iy]` with each axis in
|
|
10
|
-
# [-1, 1]; PlayerController reads input, AI/scripted controllers ignore it.
|
|
11
|
-
class Actor
|
|
12
|
-
attr_accessor :x, :y
|
|
13
|
-
attr_reader :sprite_id, :collision_box, :animator
|
|
14
|
-
|
|
15
|
-
def initialize(x:, y:, sprite_id:, collision_box:, animator:, controller:, speed: 120.0)
|
|
16
|
-
@x = x
|
|
17
|
-
@y = y
|
|
18
|
-
@sprite_id = sprite_id
|
|
19
|
-
@collision_box = collision_box
|
|
20
|
-
@animator = animator
|
|
21
|
-
@controller = controller
|
|
22
|
-
@speed = speed
|
|
23
|
-
end
|
|
24
|
-
|
|
25
|
-
def update(dt, collision_system, input)
|
|
26
|
-
intent_x, intent_y = @controller.intent(dt, input)
|
|
27
|
-
|
|
28
|
-
collision_system.move(self, intent_x * @speed * dt, intent_y * @speed * dt)
|
|
29
|
-
|
|
30
|
-
@animator.play(walk_animation(intent_x, intent_y))
|
|
31
|
-
@animator.update(dt)
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
# [row, col, flip_x] for the current frame.
|
|
35
|
-
def frame
|
|
36
|
-
@animator.frame
|
|
37
|
-
end
|
|
38
|
-
|
|
39
|
-
private
|
|
40
|
-
|
|
41
|
-
# Facing follows movement intent (so we still "walk" while pushing a wall);
|
|
42
|
-
# horizontal wins over vertical.
|
|
43
|
-
def walk_animation(intent_x, intent_y)
|
|
44
|
-
if intent_x.negative? then :walk_left
|
|
45
|
-
elsif intent_x.positive? then :walk_right
|
|
46
|
-
elsif intent_y.negative? then :walk_up
|
|
47
|
-
elsif intent_y.positive? then :walk_down
|
|
48
|
-
else :stand
|
|
49
|
-
end
|
|
50
|
-
end
|
|
51
|
-
end
|
|
52
|
-
end
|
|
53
|
-
end
|
data/lib/rgame/engine/body.rb
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RGame
|
|
4
|
-
module Engine
|
|
5
|
-
# Reusable kinematics for free-moving, rotating entities (ship, rocks, bullets):
|
|
6
|
-
# position, linear velocity, facing angle and angular velocity. `integrate`
|
|
7
|
-
# advances them by a fixed dt; `wrap!` implements toroidal screen-wrap and
|
|
8
|
-
# `offscreen?` the despawn test. Pure logic; no graphics.
|
|
9
|
-
#
|
|
10
|
-
# Angle is in radians, 0 = pointing right (+x), increasing clockwise on screen
|
|
11
|
-
# (since y grows downward). A heading's unit vector is therefore (cos, sin).
|
|
12
|
-
class Body
|
|
13
|
-
attr_accessor :x, :y, :vx, :vy, :angle, :spin
|
|
14
|
-
|
|
15
|
-
def initialize(x: 0.0, y: 0.0, vx: 0.0, vy: 0.0, angle: 0.0, spin: 0.0)
|
|
16
|
-
@x = x
|
|
17
|
-
@y = y
|
|
18
|
-
@vx = vx
|
|
19
|
-
@vy = vy
|
|
20
|
-
@angle = angle
|
|
21
|
-
@spin = spin
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
def integrate(dt)
|
|
25
|
-
@x += @vx * dt
|
|
26
|
-
@y += @vy * dt
|
|
27
|
-
@angle += @spin * dt
|
|
28
|
-
end
|
|
29
|
-
|
|
30
|
-
# Toroidal wrap: once the centre passes `margin` beyond an edge it reappears on
|
|
31
|
-
# the opposite side. Using margin = the entity's radius means an object spawned
|
|
32
|
-
# flush against an edge (centre at -radius) is exactly *at* the threshold, not
|
|
33
|
-
# past it, so it never wraps on the frame it spawns.
|
|
34
|
-
def wrap!(width, height, margin)
|
|
35
|
-
span_x = width + (2 * margin)
|
|
36
|
-
span_y = height + (2 * margin)
|
|
37
|
-
@x += span_x while @x < -margin
|
|
38
|
-
@x -= span_x while @x > width + margin
|
|
39
|
-
@y += span_y while @y < -margin
|
|
40
|
-
@y -= span_y while @y > height + margin
|
|
41
|
-
end
|
|
42
|
-
|
|
43
|
-
# Fully past an edge by `margin` (e.g. a bullet that left the screen).
|
|
44
|
-
def offscreen?(width, height, margin)
|
|
45
|
-
@x < -margin || @x > width + margin || @y < -margin || @y > height + margin
|
|
46
|
-
end
|
|
47
|
-
end
|
|
48
|
-
end
|
|
49
|
-
end
|