rgame 0.1.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 +228 -0
- data/README.md +142 -243
- data/docs/api/README.md +141 -90
- data/docs/api/app.md +125 -68
- data/docs/api/assets.md +203 -166
- data/docs/api/audio.md +130 -89
- data/docs/api/cli.md +259 -0
- data/docs/api/components.md +1045 -254
- data/docs/api/drawing.md +187 -119
- data/docs/api/examples.md +263 -0
- data/docs/api/game.md +165 -45
- data/docs/api/images.md +39 -39
- data/docs/api/input.md +344 -85
- data/docs/api/internals.md +241 -62
- data/docs/api/localization.md +285 -0
- data/docs/api/scene_graph.md +503 -123
- data/docs/api/signals.md +81 -76
- data/docs/api/systems.md +197 -64
- data/docs/api/text.md +58 -41
- data/docs/api/tile_maps.md +237 -0
- data/docs/api/toolbox.md +400 -147
- data/docs/api/ui.md +927 -0
- data/docs/api/values.md +234 -19
- 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/README.md +6 -5
- data/ext/rgame_core/app/app.c +215 -11
- 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 +113 -2
- data/ext/rgame_core/example.rb +18 -56
- data/ext/rgame_core/extconf.rb +16 -113
- data/ext/rgame_core/graphics/canvas.c +45 -4
- data/ext/rgame_core/graphics/canvas.h +65 -10
- data/ext/rgame_core/graphics/clip.c +22 -13
- data/ext/rgame_core/include/rgame/core.h +151 -5
- data/ext/rgame_core/input/gamepad.c +57 -3
- data/ext/rgame_core/ruby/audio_ext.c +10 -5
- data/ext/rgame_core/ruby/core_ext.c +46 -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 +42 -19
- data/ext/rgame_util/color_ext.c +12 -3
- 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 -42
- 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/input.rb +35 -41
- data/lib/rgame/core/locale.rb +22 -0
- data/lib/rgame/core/nine_slice.rb +0 -21
- data/lib/rgame/core/recording.rb +3 -1
- data/lib/rgame/core/renderer.rb +75 -84
- data/lib/rgame/core/sprite_sheet.rb +0 -3
- data/lib/rgame/core/tile_map_renderer.rb +77 -65
- 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 +55 -10
- 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 +35 -1
- data/lib/rgame/engine/components/action_trigger.rb +0 -1
- data/lib/rgame/engine/components/animated_sprite.rb +31 -23
- data/lib/rgame/engine/components/box_collider.rb +99 -0
- data/lib/rgame/engine/components/camera_follow.rb +45 -0
- data/lib/rgame/engine/components/character_body.rb +21 -41
- 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 +22 -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 +70 -29
- 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 +45 -0
- data/lib/rgame/engine/debug_overlay.rb +23 -18
- 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 +76 -22
- data/lib/rgame/engine/input/actions.rb +63 -12
- data/lib/rgame/engine/input/input_map.rb +196 -0
- data/lib/rgame/engine/layout.rb +82 -0
- data/lib/rgame/engine/nav_grid.rb +87 -0
- data/lib/rgame/engine/node2d.rb +364 -80
- data/lib/rgame/engine/path.rb +4 -6
- data/lib/rgame/engine/player.rb +69 -0
- data/lib/rgame/engine/player_layer.rb +70 -0
- data/lib/rgame/engine/players.rb +205 -0
- data/lib/rgame/engine/presentation.rb +171 -0
- data/lib/rgame/engine/scene/scene_stack.rb +29 -7
- data/lib/rgame/engine/sealed_privates.rb +54 -0
- data/lib/rgame/engine/spatial_hash.rb +53 -8
- 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 +82 -0
- 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 +290 -0
- 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/view.rb +76 -0
- data/lib/rgame/engine/viewports.rb +171 -0
- data/lib/rgame/engine/world_view.rb +71 -0
- data/lib/rgame/engine.rb +43 -25
- data/lib/rgame/game.rb +164 -22
- 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 +106 -44
- 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 +123 -0
- data/lib/rgame/util.rb +5 -3
- data/lib/rgame/version.rb +1 -1
- data/lib/rgame.rb +0 -15
- metadata +176 -20
- 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/camera_view.rb +0 -28
- 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
metadata
CHANGED
|
@@ -1,56 +1,130 @@
|
|
|
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: []
|
|
12
12
|
description: |
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
RGame is a small 2D game engine for Ruby, written in Ruby and C. It's build
|
|
14
|
+
on top of SDL2, OpenGL and miniaudio. It's built with testability and
|
|
15
|
+
performance in mind, and aims to be an engine where you can write your whole
|
|
16
|
+
game code in Ruby, test it as usual with RSpec (or Minitest, or another test
|
|
17
|
+
framework) and still have acceptable performance.
|
|
17
18
|
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
at all, so `require "rgame"` gives you the pure half with no SDL or OpenGL in
|
|
22
|
-
the process and pure-logic code stays testable with no display.
|
|
19
|
+
While still a work in progress, RGame aims to be more than a SDL/OpenGL
|
|
20
|
+
binding - it ships with high level features like a scene graph, sprites,
|
|
21
|
+
collision systems, debugging tools and an UI toolkit.
|
|
23
22
|
email:
|
|
24
23
|
- 2452696+psuessenb@users.noreply.github.com
|
|
25
|
-
executables:
|
|
24
|
+
executables:
|
|
25
|
+
- rgame
|
|
26
26
|
extensions:
|
|
27
27
|
- ext/rgame_core/extconf.rb
|
|
28
28
|
- ext/rgame_util/extconf.rb
|
|
29
29
|
extra_rdoc_files: []
|
|
30
30
|
files:
|
|
31
|
+
- CHANGELOG.md
|
|
31
32
|
- LICENSE
|
|
32
33
|
- README.md
|
|
33
34
|
- docs/api/README.md
|
|
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
|
|
53
|
+
- docs/api/ui.md
|
|
48
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
|
|
49
121
|
- ext/README.md
|
|
50
122
|
- ext/rgame_core/app/app.c
|
|
51
123
|
- ext/rgame_core/app/app_gl.h
|
|
52
124
|
- ext/rgame_core/app/frame_loop.c
|
|
53
125
|
- ext/rgame_core/app/frame_loop.h
|
|
126
|
+
- ext/rgame_core/app/locale.c
|
|
127
|
+
- ext/rgame_core/app/locale.h
|
|
54
128
|
- ext/rgame_core/audio/audio.c
|
|
55
129
|
- ext/rgame_core/audio/audio_internal.h
|
|
56
130
|
- ext/rgame_core/audio/vorbis_decoder.c
|
|
@@ -89,6 +163,7 @@ files:
|
|
|
89
163
|
- ext/rgame_core/ruby/core_ext.h
|
|
90
164
|
- ext/rgame_core/ruby/font_ext.c
|
|
91
165
|
- ext/rgame_core/ruby/image_ext.c
|
|
166
|
+
- ext/rgame_core/ruby/locale_ext.c
|
|
92
167
|
- ext/rgame_core/ruby/recording_ext.c
|
|
93
168
|
- ext/rgame_core/ruby/renderer_ext.c
|
|
94
169
|
- ext/rgame_core/text/atlas.c
|
|
@@ -112,11 +187,36 @@ files:
|
|
|
112
187
|
- ext/rgame_util/color.h
|
|
113
188
|
- ext/rgame_util/color_ext.c
|
|
114
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
|
|
115
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
|
|
116
200
|
- ext/rgame_util/util_ext.c
|
|
117
201
|
- ext/rgame_util/util_ext.h
|
|
118
202
|
- lib/rgame.rb
|
|
119
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
|
|
120
220
|
- lib/rgame/core.rb
|
|
121
221
|
- lib/rgame/core/app.rb
|
|
122
222
|
- lib/rgame/core/asset_manager.rb
|
|
@@ -125,6 +225,7 @@ files:
|
|
|
125
225
|
- lib/rgame/core/gamepad.rb
|
|
126
226
|
- lib/rgame/core/image.rb
|
|
127
227
|
- lib/rgame/core/input.rb
|
|
228
|
+
- lib/rgame/core/locale.rb
|
|
128
229
|
- lib/rgame/core/nine_slice.rb
|
|
129
230
|
- lib/rgame/core/recording.rb
|
|
130
231
|
- lib/rgame/core/renderer.rb
|
|
@@ -132,25 +233,30 @@ files:
|
|
|
132
233
|
- lib/rgame/core/tile_map_renderer.rb
|
|
133
234
|
- lib/rgame/core/ui_atlas.rb
|
|
134
235
|
- lib/rgame/engine.rb
|
|
135
|
-
- lib/rgame/engine/
|
|
236
|
+
- lib/rgame/engine/actor_blockers.rb
|
|
136
237
|
- lib/rgame/engine/animation_set.rb
|
|
137
238
|
- lib/rgame/engine/animator.rb
|
|
138
239
|
- lib/rgame/engine/audio_bus.rb
|
|
139
240
|
- lib/rgame/engine/audio_director.rb
|
|
140
|
-
- lib/rgame/engine/
|
|
141
|
-
- lib/rgame/engine/cached_label.rb
|
|
241
|
+
- lib/rgame/engine/bounds_blockers.rb
|
|
142
242
|
- lib/rgame/engine/camera.rb
|
|
143
|
-
- lib/rgame/engine/camera_view.rb
|
|
144
243
|
- lib/rgame/engine/circle_collider.rb
|
|
145
244
|
- lib/rgame/engine/collision_box.rb
|
|
146
245
|
- lib/rgame/engine/collision_system.rb
|
|
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
|
|
250
|
+
- lib/rgame/engine/components/camera_follow.rb
|
|
150
251
|
- lib/rgame/engine/components/character_body.rb
|
|
151
252
|
- lib/rgame/engine/components/circle_collider.rb
|
|
152
253
|
- lib/rgame/engine/components/collision_world.rb
|
|
153
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
|
|
154
260
|
- lib/rgame/engine/components/path_follow.rb
|
|
155
261
|
- lib/rgame/engine/components/player_controller.rb
|
|
156
262
|
- lib/rgame/engine/components/pool.rb
|
|
@@ -162,30 +268,79 @@ files:
|
|
|
162
268
|
- lib/rgame/engine/components/timer.rb
|
|
163
269
|
- lib/rgame/engine/components/velocity.rb
|
|
164
270
|
- lib/rgame/engine/components/wander_controller.rb
|
|
271
|
+
- lib/rgame/engine/components/world.rb
|
|
272
|
+
- lib/rgame/engine/contact_set.rb
|
|
273
|
+
- lib/rgame/engine/culling.rb
|
|
165
274
|
- lib/rgame/engine/debug_overlay.rb
|
|
166
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
|
|
167
279
|
- lib/rgame/engine/input/action_mapper.rb
|
|
168
280
|
- lib/rgame/engine/input/actions.rb
|
|
169
|
-
- lib/rgame/engine/input/
|
|
170
|
-
- lib/rgame/engine/
|
|
281
|
+
- lib/rgame/engine/input/input_map.rb
|
|
282
|
+
- lib/rgame/engine/layout.rb
|
|
283
|
+
- lib/rgame/engine/nav_grid.rb
|
|
171
284
|
- lib/rgame/engine/node2d.rb
|
|
172
285
|
- lib/rgame/engine/path.rb
|
|
286
|
+
- lib/rgame/engine/player.rb
|
|
287
|
+
- lib/rgame/engine/player_layer.rb
|
|
288
|
+
- lib/rgame/engine/players.rb
|
|
173
289
|
- lib/rgame/engine/pool.rb
|
|
174
|
-
- lib/rgame/engine/
|
|
290
|
+
- lib/rgame/engine/presentation.rb
|
|
175
291
|
- lib/rgame/engine/scene/scene_stack.rb
|
|
292
|
+
- lib/rgame/engine/sealed_privates.rb
|
|
176
293
|
- lib/rgame/engine/signal.rb
|
|
177
294
|
- lib/rgame/engine/spatial_hash.rb
|
|
178
|
-
- lib/rgame/engine/
|
|
295
|
+
- lib/rgame/engine/text.rb
|
|
296
|
+
- lib/rgame/engine/tile_blockers.rb
|
|
179
297
|
- lib/rgame/engine/tile_map.rb
|
|
298
|
+
- lib/rgame/engine/tile_map_layer.rb
|
|
180
299
|
- lib/rgame/engine/tileset.rb
|
|
181
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
|
|
304
|
+
- lib/rgame/engine/ui/menu.rb
|
|
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
|
|
318
|
+
- lib/rgame/engine/view.rb
|
|
319
|
+
- lib/rgame/engine/viewports.rb
|
|
320
|
+
- lib/rgame/engine/world_view.rb
|
|
182
321
|
- lib/rgame/fonts/LiberationSans-Regular.ttf
|
|
183
322
|
- lib/rgame/fonts/OFL.txt
|
|
184
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
|
|
185
335
|
- lib/rgame/util.rb
|
|
186
336
|
- lib/rgame/util/color.rb
|
|
187
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
|
|
188
341
|
- lib/rgame/util/tensor.rb
|
|
342
|
+
- lib/rgame/util/tile_sweep.rb
|
|
343
|
+
- lib/rgame/util/z.rb
|
|
189
344
|
- lib/rgame/version.rb
|
|
190
345
|
homepage: https://github.com/psuessenb/rgame
|
|
191
346
|
licenses:
|
|
@@ -194,6 +349,7 @@ metadata:
|
|
|
194
349
|
source_code_uri: https://github.com/psuessenb/rgame
|
|
195
350
|
bug_tracker_uri: https://github.com/psuessenb/rgame/issues
|
|
196
351
|
documentation_uri: https://github.com/psuessenb/rgame/blob/main/docs/api/README.md
|
|
352
|
+
changelog_uri: https://github.com/psuessenb/rgame/blob/main/CHANGELOG.md
|
|
197
353
|
rubygems_mfa_required: 'true'
|
|
198
354
|
rdoc_options: []
|
|
199
355
|
require_paths:
|
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
|
|
@@ -1,33 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RGame
|
|
4
|
-
module Engine
|
|
5
|
-
# Holds a display string and rebuilds it only when its source value changes, so a
|
|
6
|
-
# per-frame draw can show the cached copy without interpolating (allocating) a String
|
|
7
|
-
# every frame. The format block runs only on an actual change.
|
|
8
|
-
#
|
|
9
|
-
# @score_label = Engine::CachedLabel.new { |score| "Score: #{score}" } # build the block once
|
|
10
|
-
# renderer.text(@score_label[@score], 12, 10) # in on_draw: cached, no alloc
|
|
11
|
-
#
|
|
12
|
-
# `@score_label[value]` returns the cached string when `value` is unchanged, and
|
|
13
|
-
# otherwise rebuilds it through the block. Construct it (and its block) outside the
|
|
14
|
-
# per-frame path — e.g. in `on_add` — so the interpolation isn't itself a per-frame cost.
|
|
15
|
-
class CachedLabel
|
|
16
|
-
def initialize(&format)
|
|
17
|
-
raise ArgumentError, 'CachedLabel needs a format block' unless format
|
|
18
|
-
|
|
19
|
-
@format = format
|
|
20
|
-
@value = nil
|
|
21
|
-
@text = nil
|
|
22
|
-
end
|
|
23
|
-
|
|
24
|
-
# The cached string for `value`, rebuilt only when `value` differs from last time.
|
|
25
|
-
def [](value)
|
|
26
|
-
return @text if !@text.nil? && value == @value
|
|
27
|
-
|
|
28
|
-
@value = value
|
|
29
|
-
@text = @format.call(value)
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
33
|
-
end
|
|
@@ -1,28 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RGame
|
|
4
|
-
module Engine
|
|
5
|
-
# A node whose children live in *world* space and are drawn through a Camera: it
|
|
6
|
-
# wraps their draw in renderer.translated(-camera.x, -camera.y), so the camera's
|
|
7
|
-
# offset maps the world onto the screen. The children never know about the camera —
|
|
8
|
-
# they draw at their own absolute (world) origin, and the view transform does the
|
|
9
|
-
# rest. The owning scene drives the camera (e.g. centring it on the player); this
|
|
10
|
-
# node only applies it.
|
|
11
|
-
#
|
|
12
|
-
# The offset is a draw-time transform, not a position baked into a node, so the same
|
|
13
|
-
# world can later be drawn through several cameras (split-screen) by repeating the
|
|
14
|
-
# pass under different offsets/clips.
|
|
15
|
-
class CameraView < Node2D
|
|
16
|
-
def initialize(camera:, **)
|
|
17
|
-
super(**)
|
|
18
|
-
@camera = camera
|
|
19
|
-
end
|
|
20
|
-
|
|
21
|
-
private
|
|
22
|
-
|
|
23
|
-
def draw_children(renderer)
|
|
24
|
-
renderer.translated(-@camera.x, -@camera.y) { super }
|
|
25
|
-
end
|
|
26
|
-
end
|
|
27
|
-
end
|
|
28
|
-
end
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RGame
|
|
4
|
-
module Engine
|
|
5
|
-
# Drives an Actor from player input: turns the move_x/move_y actions into a
|
|
6
|
-
# movement intent. NPC controllers implement the same `intent(dt, input)` seam
|
|
7
|
-
# and ignore `input`.
|
|
8
|
-
class PlayerController
|
|
9
|
-
def intent(_dt, input)
|
|
10
|
-
[input.axis(:move_x), input.axis(:move_y)]
|
|
11
|
-
end
|
|
12
|
-
end
|
|
13
|
-
end
|
|
14
|
-
end
|
data/lib/rgame/engine/matrix.rb
DELETED
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RGame
|
|
4
|
-
module Engine
|
|
5
|
-
# A fixed-size 2-D grid backed by a single flat (row-major) array, addressed as
|
|
6
|
-
# [x, y]. The flat backing keeps the whole grid in one contiguous allocation —
|
|
7
|
-
# cheaper than an array-of-arrays and a straightforward shape to later move into a
|
|
8
|
-
# C-level buffer. Pure; no bounds checking on the hot path (callers stay in range).
|
|
9
|
-
#
|
|
10
|
-
# This stays Ruby, unlike the engine's old `Tensor`, which was deleted in
|
|
11
|
-
# favour of the C `RGame::Util::Tensor`. The reason is only that there is no
|
|
12
|
-
# C `Util::Matrix` to swap to — `Util` holds `Tensor`, `Controls` and
|
|
13
|
-
# `Color`. If one is ever written, this is the caller to point at it.
|
|
14
|
-
class Matrix
|
|
15
|
-
attr_reader :width, :height
|
|
16
|
-
|
|
17
|
-
def initialize(width, height, initial: nil)
|
|
18
|
-
@width = width
|
|
19
|
-
@height = height
|
|
20
|
-
@data = Array.new(width * height, initial)
|
|
21
|
-
end
|
|
22
|
-
|
|
23
|
-
def [](x, y)
|
|
24
|
-
@data[(y * @width) + x]
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def []=(x, y, value)
|
|
28
|
-
@data[(y * @width) + x] = value
|
|
29
|
-
end
|
|
30
|
-
end
|
|
31
|
-
end
|
|
32
|
-
end
|
|
@@ -1,67 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RGame
|
|
4
|
-
module Engine
|
|
5
|
-
# Builds value-object classes for pooling. Like `Data.define`, instances expose
|
|
6
|
-
# read-only accessors and carry their fields as a unit — but where a `Data` value
|
|
7
|
-
# is fully immutable (every change means a fresh allocation), these add exactly
|
|
8
|
-
# one mutation: `reset`, which overwrites all fields at once and returns self.
|
|
9
|
-
#
|
|
10
|
-
# That is the only mutability a pool needs: acquire a recycled instance and
|
|
11
|
-
# `reset` it, without exposing the per-field setters a `Struct` would. The methods
|
|
12
|
-
# are generated fixed-arity with direct ivar assignment (as Struct/Data do), so
|
|
13
|
-
# `reset` is allocation-free and recycling stays zero-allocation in steady state.
|
|
14
|
-
#
|
|
15
|
-
# Positional by default; pass `keyword_init: true` for keyword fields. Keywords
|
|
16
|
-
# are *also* allocation-free here because they are generated as named parameters
|
|
17
|
-
# (`reset(x:, y:)`), not a `**kwargs` splat — the splat is the one form that builds
|
|
18
|
-
# a Hash per call.
|
|
19
|
-
#
|
|
20
|
-
# Point = Engine::Resettable.define(:x, :y)
|
|
21
|
-
# p = Point.new(3, 4); p.x # => 3
|
|
22
|
-
# p.reset(5, 6) # same object, new values; returns p
|
|
23
|
-
#
|
|
24
|
-
# Event = Engine::Resettable.define(:type, :payload, keyword_init: true)
|
|
25
|
-
# e = Event.new(type: :hit, payload: 10)
|
|
26
|
-
# e.reset(type: :lose, payload: nil) # same object; returns e
|
|
27
|
-
# e.respond_to?(:type=) # => false (no setters)
|
|
28
|
-
#
|
|
29
|
-
# Field names are generated into real methods, so they must be plain identifiers.
|
|
30
|
-
module Resettable
|
|
31
|
-
IDENTIFIER = /\A[a-z_][a-zA-Z0-9_]*\z/
|
|
32
|
-
|
|
33
|
-
def self.define(*fields, keyword_init: false)
|
|
34
|
-
fields.each do |field|
|
|
35
|
-
raise ArgumentError, "invalid field name: #{field.inspect}" unless field.to_s.match?(IDENTIFIER)
|
|
36
|
-
end
|
|
37
|
-
|
|
38
|
-
params = fields.map { |f| keyword_init ? "#{f}:" : f.to_s }.join(', ')
|
|
39
|
-
assign = fields.map { |f| "@#{f} = #{f}" }.join("\n")
|
|
40
|
-
|
|
41
|
-
Class.new do
|
|
42
|
-
class_eval(<<~RUBY, __FILE__, __LINE__ + 1)
|
|
43
|
-
# For fields [:x, :y] this generates (keyword_init makes `x, y` -> `x:, y:`):
|
|
44
|
-
# attr_reader :x, :y
|
|
45
|
-
# def initialize(x, y)
|
|
46
|
-
# @x = x; @y = y
|
|
47
|
-
# end
|
|
48
|
-
# def reset(x, y)
|
|
49
|
-
# @x = x; @y = y
|
|
50
|
-
# self
|
|
51
|
-
# end
|
|
52
|
-
attr_reader #{fields.map { |f| ":#{f}" }.join(', ')}
|
|
53
|
-
|
|
54
|
-
def initialize(#{params})
|
|
55
|
-
#{assign}
|
|
56
|
-
end
|
|
57
|
-
|
|
58
|
-
def reset(#{params})
|
|
59
|
-
#{assign}
|
|
60
|
-
self
|
|
61
|
-
end
|
|
62
|
-
RUBY
|
|
63
|
-
end
|
|
64
|
-
end
|
|
65
|
-
end
|
|
66
|
-
end
|
|
67
|
-
end
|
|
@@ -1,78 +0,0 @@
|
|
|
1
|
-
# frozen_string_literal: true
|
|
2
|
-
|
|
3
|
-
module RGame
|
|
4
|
-
module Engine
|
|
5
|
-
# Axis-separated AABB-vs-tile collision resolution (pure). `solid` is a callable
|
|
6
|
-
# `solid.call(col, row) -> bool`. Resolve X then Y (with the X result) to get
|
|
7
|
-
# wall-sliding. Assumes per-step movement smaller than a tile (no tunneling),
|
|
8
|
-
# which holds for our speeds.
|
|
9
|
-
class TileCollision
|
|
10
|
-
EPS = 1e-9
|
|
11
|
-
|
|
12
|
-
def initialize(tile_width:, tile_height:, solid:)
|
|
13
|
-
@tile_width = tile_width
|
|
14
|
-
@tile_height = tile_height
|
|
15
|
-
@solid = solid
|
|
16
|
-
end
|
|
17
|
-
|
|
18
|
-
# Move an AABB (top-left x, y; size w, h) by dx, snapping flush against solids.
|
|
19
|
-
def resolve_x(x, y, w, h, dx)
|
|
20
|
-
nx = x + dx
|
|
21
|
-
return nx if dx.zero?
|
|
22
|
-
|
|
23
|
-
first_row = (y / @tile_height).floor
|
|
24
|
-
last_row = ((y + h - EPS) / @tile_height).floor
|
|
25
|
-
|
|
26
|
-
if dx.positive?
|
|
27
|
-
col = ((nx + w - EPS) / @tile_width).floor
|
|
28
|
-
return col * @tile_width - w if solid_in_rows?(col, first_row, last_row)
|
|
29
|
-
else
|
|
30
|
-
col = (nx / @tile_width).floor
|
|
31
|
-
return (col + 1) * @tile_width if solid_in_rows?(col, first_row, last_row)
|
|
32
|
-
end
|
|
33
|
-
nx
|
|
34
|
-
end
|
|
35
|
-
|
|
36
|
-
def resolve_y(x, y, w, h, dy)
|
|
37
|
-
ny = y + dy
|
|
38
|
-
return ny if dy.zero?
|
|
39
|
-
|
|
40
|
-
first_col = (x / @tile_width).floor
|
|
41
|
-
last_col = ((x + w - EPS) / @tile_width).floor
|
|
42
|
-
|
|
43
|
-
if dy.positive?
|
|
44
|
-
row = ((ny + h - EPS) / @tile_height).floor
|
|
45
|
-
return row * @tile_height - h if solid_in_cols?(row, first_col, last_col)
|
|
46
|
-
else
|
|
47
|
-
row = (ny / @tile_height).floor
|
|
48
|
-
return (row + 1) * @tile_height if solid_in_cols?(row, first_col, last_col)
|
|
49
|
-
end
|
|
50
|
-
ny
|
|
51
|
-
end
|
|
52
|
-
|
|
53
|
-
private
|
|
54
|
-
|
|
55
|
-
# Plain integer loops rather than (a..b).any? { ... }: the Range literal would
|
|
56
|
-
# allocate on this per-frame collision path.
|
|
57
|
-
def solid_in_rows?(col, first_row, last_row)
|
|
58
|
-
row = first_row
|
|
59
|
-
while row <= last_row
|
|
60
|
-
return true if @solid.call(col, row)
|
|
61
|
-
|
|
62
|
-
row += 1
|
|
63
|
-
end
|
|
64
|
-
false
|
|
65
|
-
end
|
|
66
|
-
|
|
67
|
-
def solid_in_cols?(row, first_col, last_col)
|
|
68
|
-
col = first_col
|
|
69
|
-
while col <= last_col
|
|
70
|
-
return true if @solid.call(col, row)
|
|
71
|
-
|
|
72
|
-
col += 1
|
|
73
|
-
end
|
|
74
|
-
false
|
|
75
|
-
end
|
|
76
|
-
end
|
|
77
|
-
end
|
|
78
|
-
end
|