rgame 0.1.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 +7 -0
- data/LICENSE +26 -0
- data/README.md +406 -0
- data/docs/api/README.md +167 -0
- data/docs/api/app.md +192 -0
- data/docs/api/assets.md +426 -0
- data/docs/api/audio.md +208 -0
- data/docs/api/components.md +321 -0
- data/docs/api/drawing.md +330 -0
- data/docs/api/game.md +99 -0
- data/docs/api/images.md +118 -0
- data/docs/api/input.md +179 -0
- data/docs/api/internals.md +110 -0
- data/docs/api/scene_graph.md +159 -0
- data/docs/api/signals.md +142 -0
- data/docs/api/systems.md +98 -0
- data/docs/api/text.md +116 -0
- data/docs/api/toolbox.md +240 -0
- data/docs/api/values.md +101 -0
- data/ext/README.md +225 -0
- data/ext/rgame_core/app/app.c +721 -0
- data/ext/rgame_core/app/app_gl.h +64 -0
- data/ext/rgame_core/app/frame_loop.c +42 -0
- data/ext/rgame_core/app/frame_loop.h +54 -0
- data/ext/rgame_core/audio/audio.c +466 -0
- data/ext/rgame_core/audio/audio_internal.h +45 -0
- data/ext/rgame_core/audio/vorbis_decoder.c +282 -0
- data/ext/rgame_core/audio/vorbis_decoder.h +45 -0
- data/ext/rgame_core/example.rb +188 -0
- data/ext/rgame_core/extconf.rb +167 -0
- data/ext/rgame_core/graphics/backend.c +52 -0
- data/ext/rgame_core/graphics/backend.h +64 -0
- data/ext/rgame_core/graphics/canvas.c +247 -0
- data/ext/rgame_core/graphics/canvas.h +143 -0
- data/ext/rgame_core/graphics/clip.c +87 -0
- data/ext/rgame_core/graphics/clip.h +89 -0
- data/ext/rgame_core/graphics/draw_queue.c +216 -0
- data/ext/rgame_core/graphics/draw_queue.h +174 -0
- data/ext/rgame_core/graphics/gl_backend.c +122 -0
- data/ext/rgame_core/graphics/gl_backend.h +43 -0
- data/ext/rgame_core/graphics/image.c +304 -0
- data/ext/rgame_core/graphics/image_internal.h +30 -0
- data/ext/rgame_core/graphics/primitives.c +189 -0
- data/ext/rgame_core/graphics/primitives.h +111 -0
- data/ext/rgame_core/graphics/recording.c +119 -0
- data/ext/rgame_core/graphics/recording.h +88 -0
- data/ext/rgame_core/graphics/texture.c +181 -0
- data/ext/rgame_core/graphics/texture.h +165 -0
- data/ext/rgame_core/graphics/transform.c +128 -0
- data/ext/rgame_core/graphics/transform.h +106 -0
- data/ext/rgame_core/include/rgame/core.h +577 -0
- data/ext/rgame_core/input/device_slots.c +103 -0
- data/ext/rgame_core/input/device_slots.h +93 -0
- data/ext/rgame_core/input/gamepad.c +145 -0
- data/ext/rgame_core/input/gamepad.h +63 -0
- data/ext/rgame_core/input/input.c +109 -0
- data/ext/rgame_core/input/input.h +99 -0
- data/ext/rgame_core/ruby/audio_ext.c +321 -0
- data/ext/rgame_core/ruby/core_ext.c +513 -0
- data/ext/rgame_core/ruby/core_ext.h +51 -0
- data/ext/rgame_core/ruby/font_ext.c +168 -0
- data/ext/rgame_core/ruby/image_ext.c +230 -0
- data/ext/rgame_core/ruby/recording_ext.c +186 -0
- data/ext/rgame_core/ruby/renderer_ext.c +376 -0
- data/ext/rgame_core/text/atlas.c +59 -0
- data/ext/rgame_core/text/atlas.h +85 -0
- data/ext/rgame_core/text/font.c +281 -0
- data/ext/rgame_core/text/font.h +139 -0
- data/ext/rgame_core/text/font_atlas.c +385 -0
- data/ext/rgame_core/text/font_internal.h +47 -0
- data/ext/rgame_core/text/glyph_cache.c +142 -0
- data/ext/rgame_core/text/glyph_cache.h +89 -0
- data/ext/rgame_core/vendor/README.md +159 -0
- data/ext/rgame_core/vendor/miniaudio.h +95864 -0
- data/ext/rgame_core/vendor/miniaudio_impl.c +62 -0
- data/ext/rgame_core/vendor/stb_image.h +7988 -0
- data/ext/rgame_core/vendor/stb_image_impl.c +31 -0
- data/ext/rgame_core/vendor/stb_truetype.h +5079 -0
- data/ext/rgame_core/vendor/stb_truetype_impl.c +23 -0
- data/ext/rgame_core/vendor/stb_vorbis.c +5584 -0
- data/ext/rgame_core/vendor/stb_vorbis_impl.c +29 -0
- data/ext/rgame_util/color.c +19 -0
- data/ext/rgame_util/color.h +60 -0
- data/ext/rgame_util/color_ext.c +156 -0
- data/ext/rgame_util/extconf.rb +27 -0
- data/ext/rgame_util/tensor.c +186 -0
- data/ext/rgame_util/util_ext.c +27 -0
- data/ext/rgame_util/util_ext.h +16 -0
- data/lib/rgame/boot.rb +13 -0
- data/lib/rgame/core/app.rb +82 -0
- data/lib/rgame/core/asset_manager.rb +224 -0
- data/lib/rgame/core/audio.rb +124 -0
- data/lib/rgame/core/font.rb +49 -0
- data/lib/rgame/core/gamepad.rb +55 -0
- data/lib/rgame/core/image.rb +55 -0
- data/lib/rgame/core/input.rb +77 -0
- data/lib/rgame/core/nine_slice.rb +163 -0
- data/lib/rgame/core/recording.rb +52 -0
- data/lib/rgame/core/renderer.rb +363 -0
- data/lib/rgame/core/sprite_sheet.rb +108 -0
- data/lib/rgame/core/tile_map_renderer.rb +160 -0
- data/lib/rgame/core/ui_atlas.rb +86 -0
- data/lib/rgame/core.rb +24 -0
- data/lib/rgame/engine/actor.rb +53 -0
- data/lib/rgame/engine/animation_set.rb +49 -0
- data/lib/rgame/engine/animator.rb +44 -0
- data/lib/rgame/engine/audio_bus.rb +24 -0
- data/lib/rgame/engine/audio_director.rb +29 -0
- data/lib/rgame/engine/body.rb +49 -0
- data/lib/rgame/engine/cached_label.rb +33 -0
- data/lib/rgame/engine/camera.rb +33 -0
- data/lib/rgame/engine/camera_view.rb +28 -0
- data/lib/rgame/engine/circle_collider.rb +32 -0
- data/lib/rgame/engine/collision_box.rb +34 -0
- data/lib/rgame/engine/collision_system.rb +44 -0
- data/lib/rgame/engine/component.rb +30 -0
- data/lib/rgame/engine/components/action_trigger.rb +41 -0
- data/lib/rgame/engine/components/animated_sprite.rb +63 -0
- data/lib/rgame/engine/components/character_body.rb +70 -0
- data/lib/rgame/engine/components/circle_collider.rb +44 -0
- data/lib/rgame/engine/components/collision_world.rb +103 -0
- data/lib/rgame/engine/components/despawn_offscreen.rb +26 -0
- data/lib/rgame/engine/components/path_follow.rb +84 -0
- data/lib/rgame/engine/components/player_controller.rb +24 -0
- data/lib/rgame/engine/components/pool.rb +53 -0
- data/lib/rgame/engine/components/screen_wrap.rb +27 -0
- data/lib/rgame/engine/components/sprite.rb +31 -0
- data/lib/rgame/engine/components/targeting.rb +54 -0
- data/lib/rgame/engine/components/thrust_controller.rb +65 -0
- data/lib/rgame/engine/components/tile_world.rb +68 -0
- data/lib/rgame/engine/components/timer.rb +75 -0
- data/lib/rgame/engine/components/velocity.rb +27 -0
- data/lib/rgame/engine/components/wander_controller.rb +60 -0
- data/lib/rgame/engine/debug_overlay.rb +106 -0
- data/lib/rgame/engine/i18n.rb +97 -0
- data/lib/rgame/engine/input/action_mapper.rb +46 -0
- data/lib/rgame/engine/input/actions.rb +41 -0
- data/lib/rgame/engine/input/player_controller.rb +14 -0
- data/lib/rgame/engine/matrix.rb +32 -0
- data/lib/rgame/engine/node2d.rb +271 -0
- data/lib/rgame/engine/path.rb +78 -0
- data/lib/rgame/engine/pool.rb +51 -0
- data/lib/rgame/engine/resettable.rb +67 -0
- data/lib/rgame/engine/scene/scene_stack.rb +65 -0
- data/lib/rgame/engine/signal.rb +75 -0
- data/lib/rgame/engine/spatial_hash.rb +71 -0
- data/lib/rgame/engine/tile_collision.rb +78 -0
- data/lib/rgame/engine/tile_map.rb +149 -0
- data/lib/rgame/engine/tileset.rb +101 -0
- data/lib/rgame/engine/timer.rb +51 -0
- data/lib/rgame/engine.rb +68 -0
- data/lib/rgame/fonts/LiberationSans-Regular.ttf +0 -0
- data/lib/rgame/fonts/OFL.txt +102 -0
- data/lib/rgame/game.rb +129 -0
- data/lib/rgame/util/color.rb +27 -0
- data/lib/rgame/util/controls.rb +107 -0
- data/lib/rgame/util/tensor.rb +12 -0
- data/lib/rgame/util.rb +8 -0
- data/lib/rgame/version.rb +12 -0
- data/lib/rgame.rb +20 -0
- metadata +215 -0
data/ext/README.md
ADDED
|
@@ -0,0 +1,225 @@
|
|
|
1
|
+
# ext/
|
|
2
|
+
|
|
3
|
+
The project's two Ruby C extensions. They are split by **dependency**, and that
|
|
4
|
+
split is the rule for deciding where new code goes:
|
|
5
|
+
|
|
6
|
+
| | `rgame_core` | `rgame_util` |
|
|
7
|
+
|---|---|---|
|
|
8
|
+
| Ruby namespace | `RGame::Core` | `RGame::Util` |
|
|
9
|
+
| Required as | `rgame/core_ext` | `rgame/util_ext` |
|
|
10
|
+
| Entry point | `Init_core_ext` | `Init_util_ext` |
|
|
11
|
+
| Links | SDL2 + OpenGL + libm + pthread + libdl | nothing but Ruby |
|
|
12
|
+
| Holds | `App` (window, GL context, main loop), `Image`, `Renderer`, `Recording`, `Font`, `Audio`, `Sample`, `Song` | `Tensor`, `Color` |
|
|
13
|
+
|
|
14
|
+
Anything that depends on SDL/OpenGL — or on something that does — belongs in
|
|
15
|
+
`rgame_core`. Everything else belongs in `rgame_util`. The point of the
|
|
16
|
+
split is that `RGame::Util` can be required, and its specs run, in a process
|
|
17
|
+
with no graphics libraries loaded and no display available:
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
ext/rgame_core/
|
|
21
|
+
extconf.rb # mkmf script -> Makefile; pkg_config("sdl2"), -lGL
|
|
22
|
+
include/rgame/core.h # the public C API
|
|
23
|
+
example.rb # manual/visual smoke test (opens a real window)
|
|
24
|
+
app/
|
|
25
|
+
app.c # engine: SDL window/GL context + main loop
|
|
26
|
+
app_gl.h # private: the GL context behind the opaque app handle
|
|
27
|
+
frame_loop.c/.h # pure fixed-timestep + FPS logic (unit-tested)
|
|
28
|
+
graphics/
|
|
29
|
+
transform.c/.h # pure 2D affine transform stack (unit-tested)
|
|
30
|
+
clip.c/.h # pure rects + intersecting clip stack (unit-tested)
|
|
31
|
+
draw_queue.c/.h # pure z-sort + batching of draw commands (unit-tested)
|
|
32
|
+
canvas.c/.h # pure transform+clip+queue composition (unit-tested)
|
|
33
|
+
backend.h/.c # the GL seam: function-pointer table + submit loop
|
|
34
|
+
texture.c/.h # pure texture sheets, sub-rects and UVs (unit-tested)
|
|
35
|
+
primitives.c/.h # pure rects/lines/circles/sprites -> canvas (unit-tested)
|
|
36
|
+
recording.c/.h # pure baked draws, replayed cheaply (unit-tested)
|
|
37
|
+
gl_backend.c/.h # the real GL calls: the only gl* on the draw path
|
|
38
|
+
image.c # decode a PNG + upload it: the thin GL shim
|
|
39
|
+
image_internal.h # what the draw path needs from inside an image
|
|
40
|
+
text/
|
|
41
|
+
atlas.c/.h # pure glyph-atlas shelf packing (unit-tested)
|
|
42
|
+
glyph_cache.c/.h # pure codepoint -> glyph table (unit-tested)
|
|
43
|
+
font.c/.h # pure typeface: metrics, kerning, UTF-8 (unit-tested)
|
|
44
|
+
font_atlas.c # glyph atlas pages on the GPU: the impure quarter
|
|
45
|
+
font_internal.h # what the draw path needs from inside a font
|
|
46
|
+
input/
|
|
47
|
+
input.c/.h # pure button-id space + input snapshot (unit-tested)
|
|
48
|
+
device_slots.c/.h # pure controller-slot table, no SDL (unit-tested)
|
|
49
|
+
gamepad.c/.h # thin SDL_GameController shim (open/close/poll)
|
|
50
|
+
audio/
|
|
51
|
+
audio.c # sound device, samples and songs (unit-tested)
|
|
52
|
+
audio_internal.h # the live-sound counter, for tests
|
|
53
|
+
vorbis_decoder.c/.h # ogg for miniaudio, over stb_vorbis (unit-tested)
|
|
54
|
+
ruby/ # the only C here that includes ruby.h
|
|
55
|
+
core_ext.c # Ruby-facing glue: VALUE wrappers + trampolines
|
|
56
|
+
core_ext.h # one init function per Ruby-visible class here
|
|
57
|
+
image_ext.c # RGame::Core::Image — the Ruby binding
|
|
58
|
+
font_ext.c # RGame::Core::Font — the Ruby binding
|
|
59
|
+
audio_ext.c # RGame::Core::Audio, Sample and Song — the bindings
|
|
60
|
+
renderer_ext.c # RGame::Core::Renderer — the drawing primitives
|
|
61
|
+
recording_ext.c # RGame::Core::Recording — baked, replayable draws
|
|
62
|
+
vendor/ # third-party sources + licences (stb_image,
|
|
63
|
+
# stb_truetype, stb_vorbis, miniaudio)
|
|
64
|
+
*_impl.c # one per vendored library, built with warnings off
|
|
65
|
+
|
|
66
|
+
ext/rgame_util/
|
|
67
|
+
extconf.rb # mkmf script -> Makefile; no pkg_config, no -lGL
|
|
68
|
+
util_ext.c # entry point; calls each class's init
|
|
69
|
+
tensor.c # RGame::Util::Tensor — flat-array 3D grid
|
|
70
|
+
color.c/.h # pure RGBA packing, no ruby.h (unit-tested)
|
|
71
|
+
color_ext.c # RGame::Util::Color — the Ruby binding
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Why the engine lives here and not in `src/`
|
|
75
|
+
|
|
76
|
+
A gem's C extension is built by `gem install` running `extconf.rb` from
|
|
77
|
+
*inside its own directory* — it can't reach up to a sibling `src/`. Putting
|
|
78
|
+
the engine sources here means one copy serves both the gem and the standalone
|
|
79
|
+
binary the root `Makefile` builds. `src/` keeps only `main.c`, which stays out
|
|
80
|
+
of this directory precisely so mkmf doesn't compile its `main()` into the
|
|
81
|
+
extension.
|
|
82
|
+
|
|
83
|
+
## How it's wired
|
|
84
|
+
|
|
85
|
+
`extconf.rb` runs `mkmf` to generate a Makefile. Every `.c` becomes one loadable
|
|
86
|
+
`.so`, linked against SDL2 + OpenGL the same way the root `Makefile` links the
|
|
87
|
+
standalone binary. No prebuilt `librgame_core.a` in the middle, so there's one
|
|
88
|
+
build step.
|
|
89
|
+
|
|
90
|
+
mkmf's default is to compile every `.c` in the extension's own directory and
|
|
91
|
+
nothing deeper, so `rgame_core`'s subsystem folders are named in its
|
|
92
|
+
`extconf.rb` — one `SOURCE_DIRS` list feeding `$srcs` (what to compile) and
|
|
93
|
+
`$VPATH` (where make looks for a source named by basename). Within a listed
|
|
94
|
+
folder nothing has to be remembered: dropping a `.c` into `graphics/` is all it
|
|
95
|
+
takes to get it compiled and linked. Adding a *folder* is one entry in that
|
|
96
|
+
list, and forgetting it fails loudly — the file is simply never compiled, and
|
|
97
|
+
the first call into it is an undefined symbol at `require` time.
|
|
98
|
+
|
|
99
|
+
Two consequences of how mkmf does this are worth knowing:
|
|
100
|
+
|
|
101
|
+
- **Objects land flat**, named after the source's basename, whatever folder it
|
|
102
|
+
came from. So basenames have to be unique across the tree — and that rule
|
|
103
|
+
enforces itself, because mkmf aborts with `source files duplication` rather
|
|
104
|
+
than silently overwriting one object with another.
|
|
105
|
+
- **Header dependencies need help.** mkmf emits `$(OBJS): $(HDRS)` but builds
|
|
106
|
+
`HDRS` by globbing the extension's own directory only, which is now empty of
|
|
107
|
+
headers. `extconf.rb` appends the real list, or editing a header would
|
|
108
|
+
rebuild nothing and link objects compiled against the old struct.
|
|
109
|
+
|
|
110
|
+
The vendored translation units are the exception, and are built with warnings
|
|
111
|
+
off. mkmf has no per-file flag setting, so `extconf.rb` appends an explicit rule
|
|
112
|
+
per entry in its `VENDORED` table to the Makefile it just generated — an
|
|
113
|
+
explicit rule beats mkmf's generic `.c.o` one, so it applies to those files and
|
|
114
|
+
nothing else. The `_impl.c` suffix is what marks a file as one of them, and it
|
|
115
|
+
is reserved for that: the project stays `-Wall -Wextra`-clean everywhere we
|
|
116
|
+
wrote the code. See `rgame_core/vendor/README.md`.
|
|
117
|
+
|
|
118
|
+
Not everything in a namespace comes from its extension: `RGame::Core::Input`,
|
|
119
|
+
`RGame::Core::Gamepad` and `RGame::Util::Controls` are pure Ruby in `lib/`,
|
|
120
|
+
layered on top, and `RGame::Core::Image` is C with a few sheet-slicing methods
|
|
121
|
+
added in `lib/rgame/core/image.rb`. The tables above list what each *extension*
|
|
122
|
+
provides.
|
|
123
|
+
|
|
124
|
+
Both extensions name themselves under `rgame/` in `create_makefile`, which
|
|
125
|
+
namespaces them on the load path and leaves the bare name `rgame` to
|
|
126
|
+
`lib/rgame.rb`, the pure-Ruby entry point. Each `Init_` function calls
|
|
127
|
+
`rb_define_module("RGame")` — idempotent, so it returns the same module
|
|
128
|
+
whichever extension loads first.
|
|
129
|
+
|
|
130
|
+
The glue only ever calls the public API — the `rgame_app` struct stays opaque
|
|
131
|
+
here exactly as it does for `src/main.c`. The one interesting part is the
|
|
132
|
+
callback bridge: `rgame_app_run` owns the loop and calls C function pointers,
|
|
133
|
+
so `core_ext.c` installs small **trampolines** that call back into Ruby
|
|
134
|
+
procs (stashed as instance variables, which also keeps them alive for the GC).
|
|
135
|
+
See the comments in `core_ext.c` for the details and the current
|
|
136
|
+
exception-safety caveat.
|
|
137
|
+
|
|
138
|
+
## Build & run
|
|
139
|
+
|
|
140
|
+
From the project root:
|
|
141
|
+
|
|
142
|
+
```
|
|
143
|
+
make ext # both extensions, each copied to lib/rgame/
|
|
144
|
+
make ext-core # just this one
|
|
145
|
+
make ext-util # just this one
|
|
146
|
+
|
|
147
|
+
ruby ext/rgame_core/example.rb # opens a window; Esc or close to quit
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
`make ext-*` copies each built `.so` into `lib/rgame/`, which is where
|
|
151
|
+
`require "rgame/core_ext"` / `require "rgame/util_ext"` find it — mirroring
|
|
152
|
+
how rake-compiler installs a compiled extension into `lib/<gem>/`.
|
|
153
|
+
|
|
154
|
+
## Ruby API
|
|
155
|
+
|
|
156
|
+
```ruby
|
|
157
|
+
require "rgame" # RGame::Util only — no SDL/GL loaded
|
|
158
|
+
require "rgame/core" # adds RGame::Core, pulls in SDL2 + OpenGL
|
|
159
|
+
|
|
160
|
+
class MyGame < RGame::Core::App
|
|
161
|
+
def initialize = super(width: 800, height: 600, caption: "title")
|
|
162
|
+
|
|
163
|
+
def update(dt); end # one fixed simulation tick
|
|
164
|
+
def draw; end # render one frame
|
|
165
|
+
def needs_redraw?; end # false skips the draw
|
|
166
|
+
def button_down(id); end # discrete key press
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
app = MyGame.new
|
|
170
|
+
app.run # loops until #close or the window is closed
|
|
171
|
+
app.ticks_ms # => Integer, monotonic ms since startup
|
|
172
|
+
app.fps # => Float, most recent FPS reading
|
|
173
|
+
|
|
174
|
+
# Symbolic actions, resolved through Input's binding table. The id vocabulary
|
|
175
|
+
# lives in RGame::Util::Controls — ids are values, so a game (or the engine
|
|
176
|
+
# layer, which may not name Core) can name one:
|
|
177
|
+
controls = RGame::Util::Controls
|
|
178
|
+
input = RGame::Core::Input.new(app)
|
|
179
|
+
input.down?(:fire) # keyboard (the default)
|
|
180
|
+
input.down?(:fire, device: controls.gamepad(0))
|
|
181
|
+
input.axis(:move_x, device: controls.gamepad(0)) # => Float
|
|
182
|
+
|
|
183
|
+
# Rebinding is just a different table:
|
|
184
|
+
RGame::Core::Input.new(app, bindings: controls::DEFAULT_KEYBOARD.merge(fire: controls::KEY_RETURN))
|
|
185
|
+
|
|
186
|
+
# Which controllers are plugged in — a readout for menus, not the frame path:
|
|
187
|
+
pads = RGame::Core::Gamepad.new(app)
|
|
188
|
+
pads.count # => 1
|
|
189
|
+
pads.each_connected { |slot, name| ... } # "Player 2: <name>"
|
|
190
|
+
|
|
191
|
+
# Images: one decode and one upload, sliced into as many views as you like.
|
|
192
|
+
sheet = RGame::Core::Image.new(app, "tiles.png")
|
|
193
|
+
sheet.width; sheet.height
|
|
194
|
+
sheet.subimage(16, 0, 16, 16) # a view, not a copy
|
|
195
|
+
RGame::Core::Image.load_tiles(app, "tiles.png", 16, 16) # => [Image, ...]
|
|
196
|
+
|
|
197
|
+
# Drawing, from inside App#draw only. Nothing is immediate: the frame is
|
|
198
|
+
# z-sorted and batched once, after #draw returns.
|
|
199
|
+
renderer = RGame::Core::Renderer.new(app)
|
|
200
|
+
renderer.rect(10, 10, 100, 40, color: RGame::Util::Color::WHITE)
|
|
201
|
+
renderer.circle(200, 200, 30, color: [255, 0, 0])
|
|
202
|
+
renderer.line(0, 0, 100, 100, thickness: 4)
|
|
203
|
+
renderer.image(sheet, 400, 300, angle: 45, scale: 2) # centred, clockwise
|
|
204
|
+
renderer.rotated(30, 400, 300) { renderer.rect(380, 280, 40, 40) }
|
|
205
|
+
renderer.clipped(0, 0, 400, 600) { renderer.background(sheet) }
|
|
206
|
+
|
|
207
|
+
# Text. The renderer has a font already; Font.new(app, size) makes another.
|
|
208
|
+
renderer.text("Score: 1200", 10, 10)
|
|
209
|
+
renderer.text_width("Score: 1200") # => Float, and what #text actually draws
|
|
210
|
+
|
|
211
|
+
# Bake a block of drawing once, replay it for one call per texture.
|
|
212
|
+
ground = renderer.record { 100.times { |i| renderer.rect(i * 8, 0, 6, 6) } }
|
|
213
|
+
ground.draw(-camera_x, -camera_y)
|
|
214
|
+
|
|
215
|
+
# Sound. The device owns no window, so it takes no app.
|
|
216
|
+
audio = RGame::Core::Audio.new
|
|
217
|
+
audio.sample("hit.ogg").play # another voice each time
|
|
218
|
+
audio.song("theme.ogg").play(looping: true) # streamed, one voice, stoppable
|
|
219
|
+
|
|
220
|
+
grid = RGame::Util::Tensor.new(width, height, depth, initial: nil)
|
|
221
|
+
grid[x, y, z] = value
|
|
222
|
+
|
|
223
|
+
colour = RGame::Util::Color.new(255, 128, 0) # frozen, compares by value
|
|
224
|
+
RGame::Util::Color.coerce([255, 128, 0]) # nil / [r,g,b] / [r,g,b,a] / Color
|
|
225
|
+
```
|