ruby2d 0.12.0 → 1.0.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/LICENSE.md +7 -0
- data/README.md +141 -0
- data/USAGE.md +2435 -0
- data/assets/Rakefile +637 -0
- data/assets/build_support/CMakeLists.txt +94 -0
- data/assets/build_support/mruby/build_config.rb +34 -0
- data/assets/build_support/mruby/build_config_wasm.rb +30 -0
- data/assets/build_support/sdl_test.c +174 -0
- data/assets/deps.yaml +16 -0
- data/assets/platform/include/SDL3/SDL.h +91 -0
- data/assets/platform/include/SDL3/SDL_assert.h +705 -0
- data/assets/platform/include/SDL3/SDL_asyncio.h +550 -0
- data/assets/platform/include/SDL3/SDL_atomic.h +692 -0
- data/assets/platform/include/SDL3/SDL_audio.h +2370 -0
- data/assets/platform/include/SDL3/SDL_begin_code.h +553 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_bits.h +47 -27
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_blendmode.h +59 -55
- data/assets/platform/include/SDL3/SDL_camera.h +535 -0
- data/assets/platform/include/SDL3/SDL_clipboard.h +331 -0
- data/assets/{include/SDL2/close_code.h → platform/include/SDL3/SDL_close_code.h} +9 -8
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_copying.h +3 -1
- data/assets/platform/include/SDL3/SDL_cpuinfo.h +374 -0
- data/assets/platform/include/SDL3/SDL_dialog.h +343 -0
- data/assets/platform/include/SDL3/SDL_dlopennote.h +234 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_egl.h +11 -8
- data/assets/platform/include/SDL3/SDL_endian.h +645 -0
- data/assets/platform/include/SDL3/SDL_error.h +226 -0
- data/assets/platform/include/SDL3/SDL_events.h +1645 -0
- data/assets/platform/include/SDL3/SDL_filesystem.h +537 -0
- data/assets/platform/include/SDL3/SDL_gamepad.h +1656 -0
- data/assets/platform/include/SDL3/SDL_gpu.h +4608 -0
- data/assets/platform/include/SDL3/SDL_guid.h +106 -0
- data/assets/platform/include/SDL3/SDL_haptic.h +1461 -0
- data/assets/platform/include/SDL3/SDL_hidapi.h +571 -0
- data/assets/platform/include/SDL3/SDL_hints.h +5001 -0
- data/assets/platform/include/SDL3/SDL_init.h +507 -0
- data/assets/platform/include/SDL3/SDL_intrin.h +410 -0
- data/assets/platform/include/SDL3/SDL_iostream.h +1379 -0
- data/assets/platform/include/SDL3/SDL_joystick.h +1385 -0
- data/assets/platform/include/SDL3/SDL_keyboard.h +608 -0
- data/assets/platform/include/SDL3/SDL_keycode.h +347 -0
- data/assets/platform/include/SDL3/SDL_loadso.h +145 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_locale.h +40 -24
- data/assets/platform/include/SDL3/SDL_log.h +541 -0
- data/assets/platform/include/SDL3/SDL_main.h +704 -0
- data/assets/platform/include/SDL3/SDL_main_impl.h +151 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_messagebox.h +85 -48
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_metal.h +29 -29
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_misc.h +13 -12
- data/assets/platform/include/SDL3/SDL_mouse.h +813 -0
- data/assets/platform/include/SDL3/SDL_mutex.h +1117 -0
- data/assets/platform/include/SDL3/SDL_oldnames.h +1339 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_opengl.h +1247 -278
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_opengl_glext.h +5 -1
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_opengles.h +6 -7
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_opengles2.h +10 -11
- data/assets/platform/include/SDL3/SDL_pen.h +198 -0
- data/assets/platform/include/SDL3/SDL_pixels.h +1441 -0
- data/assets/{include/SDL2/SDL_test_log.h → platform/include/SDL3/SDL_platform.h} +25 -26
- data/assets/platform/include/SDL3/SDL_platform_defines.h +497 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_power.h +40 -20
- data/assets/platform/include/SDL3/SDL_process.h +441 -0
- data/assets/platform/include/SDL3/SDL_properties.h +572 -0
- data/assets/platform/include/SDL3/SDL_rect.h +528 -0
- data/assets/platform/include/SDL3/SDL_render.h +3028 -0
- data/assets/platform/include/SDL3/SDL_revision.h +59 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_scancode.h +59 -68
- data/assets/platform/include/SDL3/SDL_sensor.h +321 -0
- data/assets/platform/include/SDL3/SDL_stdinc.h +6186 -0
- data/assets/platform/include/SDL3/SDL_storage.h +686 -0
- data/assets/platform/include/SDL3/SDL_surface.h +1769 -0
- data/assets/platform/include/SDL3/SDL_system.h +840 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test.h +16 -22
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_assert.h +27 -34
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_common.h +109 -52
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_compare.h +22 -14
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_crc32.h +27 -30
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_font.h +50 -49
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_fuzzer.h +64 -79
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_harness.h +47 -30
- data/assets/platform/include/SDL3/SDL_test_log.h +83 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_md5.h +21 -28
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_memory.h +19 -16
- data/assets/platform/include/SDL3/SDL_thread.h +602 -0
- data/assets/platform/include/SDL3/SDL_time.h +249 -0
- data/assets/platform/include/SDL3/SDL_timer.h +454 -0
- data/assets/platform/include/SDL3/SDL_touch.h +184 -0
- data/assets/platform/include/SDL3/SDL_tray.h +544 -0
- data/assets/platform/include/SDL3/SDL_version.h +198 -0
- data/assets/platform/include/SDL3/SDL_video.h +3497 -0
- data/assets/platform/include/SDL3/SDL_vulkan.h +287 -0
- data/assets/platform/include/SDL3_image/SDL_image.h +3328 -0
- data/assets/platform/include/SDL3_mixer/SDL_mixer.h +3369 -0
- data/assets/platform/include/SDL3_ttf/SDL_textengine.h +181 -0
- data/assets/platform/include/SDL3_ttf/SDL_ttf.h +2833 -0
- data/assets/{include → platform/include}/mrbconf.h +42 -31
- data/assets/{include → platform/include}/mruby/array.h +3 -4
- data/assets/{include → platform/include}/mruby/boxing_nan.h +10 -0
- data/assets/platform/include/mruby/boxing_no.h +59 -0
- data/assets/{include → platform/include}/mruby/boxing_word.h +72 -26
- data/assets/platform/include/mruby/class.h +157 -0
- data/assets/{include → platform/include}/mruby/common.h +30 -1
- data/assets/{include → platform/include}/mruby/compile.h +52 -74
- data/assets/{include → platform/include}/mruby/data.h +2 -2
- data/assets/{include → platform/include}/mruby/debug.h +12 -5
- data/assets/{include → platform/include}/mruby/dump.h +7 -9
- data/assets/{include → platform/include}/mruby/endian.h +1 -1
- data/assets/platform/include/mruby/error.h +173 -0
- data/assets/platform/include/mruby/gc.h +79 -0
- data/assets/{include → platform/include}/mruby/hash.h +1 -7
- data/assets/platform/include/mruby/internal.h +282 -0
- data/assets/platform/include/mruby/irep.h +143 -0
- data/assets/{include → platform/include}/mruby/istruct.h +1 -1
- data/assets/platform/include/mruby/khash.h +455 -0
- data/assets/platform/include/mruby/mempool.h +19 -0
- data/assets/{include → platform/include}/mruby/numeric.h +7 -10
- data/assets/platform/include/mruby/object.h +51 -0
- data/assets/{include → platform/include}/mruby/opcode.h +5 -5
- data/assets/{include → platform/include}/mruby/ops.h +19 -6
- data/assets/platform/include/mruby/presym/id.h +1447 -0
- data/assets/{include → platform/include}/mruby/presym/scanning.h +10 -7
- data/assets/platform/include/mruby/presym/table.h +2893 -0
- data/assets/platform/include/mruby/presym.h +65 -0
- data/assets/platform/include/mruby/proc.h +184 -0
- data/assets/{include → platform/include}/mruby/range.h +0 -2
- data/assets/{include → platform/include}/mruby/string.h +33 -53
- data/assets/platform/include/mruby/throw.h +81 -0
- data/assets/{include → platform/include}/mruby/value.h +64 -29
- data/assets/{include → platform/include}/mruby/variable.h +6 -23
- data/assets/{include → platform/include}/mruby/version.h +7 -7
- data/assets/{include → platform/include}/mruby.h +238 -116
- data/assets/platform/macos-arm64/bin/mrbc +0 -0
- data/assets/platform/macos-arm64/lib/libSDL3.a +0 -0
- data/assets/platform/macos-arm64/lib/libSDL3_image.a +0 -0
- data/assets/platform/macos-arm64/lib/libSDL3_mixer.a +0 -0
- data/assets/platform/macos-arm64/lib/libSDL3_ttf.a +0 -0
- data/assets/platform/macos-arm64/lib/libmruby.a +0 -0
- data/assets/platform/wasm/lib/libFLAC.a +0 -0
- data/assets/platform/wasm/lib/libSDL3.a +0 -0
- data/assets/platform/wasm/lib/libSDL3_image.a +0 -0
- data/assets/platform/wasm/lib/libSDL3_mixer.a +0 -0
- data/assets/platform/wasm/lib/libSDL3_ttf.a +0 -0
- data/assets/platform/wasm/lib/libfreetype.a +0 -0
- data/assets/platform/wasm/lib/libharfbuzz.a +0 -0
- data/assets/platform/wasm/lib/libmruby.a +0 -0
- data/assets/platform/wasm/lib/libogg.a +0 -0
- data/assets/platform/wasm/lib/libplutosvg.a +0 -0
- data/assets/platform/wasm/lib/libplutovg.a +0 -0
- data/assets/platform/wasm/lib/libpng.a +0 -0
- data/assets/platform/wasm/lib/libpng16.a +0 -0
- data/assets/platform/wasm/lib/libvorbis.a +0 -0
- data/assets/platform/wasm/lib/libvorbisfile.a +0 -0
- data/assets/platform/wasm/lib/libzlibstatic.a +0 -0
- data/assets/platform/windows-arm64-mingw-ucrt/bin/mrbc.exe +0 -0
- data/assets/platform/windows-arm64-mingw-ucrt/lib/libSDL3.a +0 -0
- data/assets/platform/windows-arm64-mingw-ucrt/lib/libSDL3_image.a +0 -0
- data/assets/platform/windows-arm64-mingw-ucrt/lib/libSDL3_mixer.a +0 -0
- data/assets/platform/windows-arm64-mingw-ucrt/lib/libSDL3_ttf.a +0 -0
- data/assets/platform/windows-arm64-mingw-ucrt/lib/libmruby.a +0 -0
- data/assets/platform/windows-x86_64-mingw-ucrt/bin/mrbc.exe +0 -0
- data/assets/platform/windows-x86_64-mingw-ucrt/lib/libSDL3.a +0 -0
- data/assets/platform/windows-x86_64-mingw-ucrt/lib/libSDL3_image.a +0 -0
- data/assets/platform/windows-x86_64-mingw-ucrt/lib/libSDL3_mixer.a +0 -0
- data/assets/platform/windows-x86_64-mingw-ucrt/lib/libSDL3_ttf.a +0 -0
- data/assets/platform/windows-x86_64-mingw-ucrt/lib/libmruby.a +0 -0
- data/assets/resources/fonts/outfit/OFL.txt +93 -0
- data/assets/resources/fonts/outfit/outfit.ttf +0 -0
- data/assets/resources/fonts/roboto_mono/OFL.txt +91 -0
- data/assets/resources/fonts/roboto_mono/roboto_mono.ttf +0 -0
- data/assets/resources/icons/icon.icns +0 -0
- data/assets/resources/icons/icon.png +0 -0
- data/assets/resources/spritesheets/License.txt +28 -0
- data/assets/resources/spritesheets/spritesheet-backgrounds.png +0 -0
- data/assets/resources/spritesheets/spritesheet-backgrounds.xml +16 -0
- data/assets/resources/spritesheets/spritesheet-characters.png +0 -0
- data/assets/resources/spritesheets/spritesheet-characters.xml +47 -0
- data/assets/resources/spritesheets/spritesheet-enemies.png +0 -0
- data/assets/resources/spritesheets/spritesheet-enemies.xml +62 -0
- data/assets/resources/spritesheets/spritesheet-tiles.png +0 -0
- data/assets/resources/spritesheets/spritesheet-tiles.xml +316 -0
- data/assets/{wasm → resources/web}/template.html +1 -1
- data/assets/target.rb +131 -0
- data/bin/ruby2d +281 -82
- data/examples/astar.rb +269 -0
- data/examples/asteroids.rb +403 -0
- data/examples/bezier_editor.rb +96 -0
- data/examples/boids.rb +191 -0
- data/examples/bouncing_balls.rb +119 -0
- data/examples/breakout.rb +186 -0
- data/examples/constellations.rb +100 -0
- data/examples/dashboard.rb +133 -0
- data/examples/double_pendulum.rb +254 -0
- data/examples/falling_sand.rb +291 -0
- data/examples/fireworks.rb +110 -0
- data/examples/fluid_dynamics.rb +340 -0
- data/examples/fourier_epicycles.rb +142 -0
- data/examples/fractal_tree.rb +326 -0
- data/examples/game_of_life.rb +148 -0
- data/examples/gamepads.rb +333 -0
- data/examples/hill_driver.rb +613 -0
- data/examples/logo_animation.rb +251 -0
- data/examples/lorenz_attractor.rb +115 -0
- data/examples/mandelbrot.rb +207 -0
- data/examples/marching_squares.rb +200 -0
- data/examples/maze.rb +323 -0
- data/examples/nbody.rb +338 -0
- data/examples/outrun.rb +391 -0
- data/examples/pixel_paint.rb +313 -0
- data/examples/platformer.rb +335 -0
- data/examples/ray_casting_maze.rb +175 -0
- data/examples/shadow_casting.rb +151 -0
- data/examples/shape_recognizer.rb +908 -0
- data/examples/snake.rb +144 -0
- data/examples/sprite_sheets.rb +246 -0
- data/examples/swarm.rb +206 -0
- data/examples/tsp_annealing.rb +104 -0
- data/examples/ui_controls.rb +163 -0
- data/examples/wireframe_3d.rb +139 -0
- data/ext/ruby2d/audio.c +324 -0
- data/ext/ruby2d/canvas.c +1715 -494
- data/ext/ruby2d/ext.c +541 -0
- data/ext/ruby2d/extconf.rb +122 -145
- data/ext/ruby2d/font.c +566 -20
- data/ext/ruby2d/fps.c +92 -0
- data/ext/ruby2d/image.c +466 -41
- data/ext/ruby2d/ruby2d.c +374 -1890
- data/ext/ruby2d/ruby2d.h +840 -460
- data/ext/ruby2d/shapes.c +931 -101
- data/ext/ruby2d/text.c +586 -21
- data/ext/ruby2d/window.c +1693 -283
- data/lib/ruby2d/atlas_parser.rb +194 -0
- data/lib/ruby2d/audio.rb +73 -0
- data/lib/ruby2d/benchmark.rb +259 -0
- data/lib/ruby2d/bitmap_text.rb +155 -0
- data/lib/ruby2d/button.rb +402 -0
- data/lib/ruby2d/canvas.rb +703 -279
- data/lib/ruby2d/circle.rb +206 -29
- data/lib/ruby2d/cli/browser.rb +314 -0
- data/lib/ruby2d/cli/build.rb +471 -257
- data/lib/ruby2d/cli/colorize.rb +7 -5
- data/lib/ruby2d/cli/examples.rb +127 -0
- data/lib/ruby2d/cli/launch.rb +24 -39
- data/lib/ruby2d/cli/lib_files.rb +48 -0
- data/lib/ruby2d/cli/messages.rb +40 -0
- data/lib/ruby2d/cli/setup.rb +273 -0
- data/lib/ruby2d/cli/static_server.rb +160 -0
- data/lib/ruby2d/cli/usage.rb +255 -0
- data/lib/ruby2d/color.rb +191 -69
- data/lib/ruby2d/core.rb +37 -19
- data/lib/ruby2d/deps_help.rb +89 -0
- data/lib/ruby2d/dsl.rb +51 -12
- data/lib/ruby2d/ellipse.rb +228 -0
- data/lib/ruby2d/exceptions.rb +0 -2
- data/lib/ruby2d/font.rb +34 -74
- data/lib/ruby2d/gamepad.rb +323 -0
- data/lib/ruby2d/gem_paths.rb +19 -0
- data/lib/ruby2d/image.rb +155 -52
- data/lib/ruby2d/interactive.rb +103 -0
- data/lib/ruby2d/json_parser.rb +268 -0
- data/lib/ruby2d/line.rb +194 -85
- data/lib/ruby2d/mruby_compat.rb +12 -0
- data/lib/ruby2d/polygon.rb +297 -0
- data/lib/ruby2d/polyline.rb +368 -0
- data/lib/ruby2d/quad.rb +358 -94
- data/lib/ruby2d/rectangle.rb +77 -19
- data/lib/ruby2d/renderable.rb +411 -11
- data/lib/ruby2d/sprite.rb +471 -180
- data/lib/ruby2d/sprite_sheet.rb +64 -0
- data/lib/ruby2d/square.rb +29 -17
- data/lib/ruby2d/text.rb +196 -65
- data/lib/ruby2d/tileset.rb +139 -81
- data/lib/ruby2d/triangle.rb +324 -89
- data/lib/ruby2d/version.rb +1 -3
- data/lib/ruby2d/vertices.rb +62 -85
- data/lib/ruby2d/warnings.rb +29 -0
- data/lib/ruby2d/window/class_methods.rb +218 -0
- data/lib/ruby2d/window/gamepad_events.rb +141 -0
- data/lib/ruby2d/window/key_events.rb +74 -0
- data/lib/ruby2d/window/mouse_events.rb +171 -0
- data/lib/ruby2d/window/object_events.rb +168 -0
- data/lib/ruby2d/window.rb +632 -585
- data/lib/ruby2d.rb +14 -19
- metadata +275 -428
- data/assets/app.icns +0 -0
- data/assets/include/GLES2/gl2.h +0 -656
- data/assets/include/GLES2/gl2ext.h +0 -3949
- data/assets/include/GLES2/gl2ext_angle.h +0 -701
- data/assets/include/GLES2/gl2platform.h +0 -27
- data/assets/include/GLES3/gl3.h +0 -1192
- data/assets/include/GLES3/gl31.h +0 -1507
- data/assets/include/GLES3/gl32.h +0 -1808
- data/assets/include/GLES3/gl3platform.h +0 -27
- data/assets/include/KHR/khrplatform.h +0 -290
- data/assets/include/SDL2/SDL.h +0 -233
- data/assets/include/SDL2/SDL_assert.h +0 -326
- data/assets/include/SDL2/SDL_atomic.h +0 -415
- data/assets/include/SDL2/SDL_audio.h +0 -1500
- data/assets/include/SDL2/SDL_clipboard.h +0 -141
- data/assets/include/SDL2/SDL_config.h +0 -61
- data/assets/include/SDL2/SDL_config_android.h +0 -194
- data/assets/include/SDL2/SDL_config_emscripten.h +0 -218
- data/assets/include/SDL2/SDL_config_iphoneos.h +0 -217
- data/assets/include/SDL2/SDL_config_macosx.h +0 -277
- data/assets/include/SDL2/SDL_config_minimal.h +0 -95
- data/assets/include/SDL2/SDL_config_ngage.h +0 -89
- data/assets/include/SDL2/SDL_config_os2.h +0 -207
- data/assets/include/SDL2/SDL_config_pandora.h +0 -141
- data/assets/include/SDL2/SDL_config_windows.h +0 -331
- data/assets/include/SDL2/SDL_config_wingdk.h +0 -253
- data/assets/include/SDL2/SDL_config_winrt.h +0 -220
- data/assets/include/SDL2/SDL_config_xbox.h +0 -235
- data/assets/include/SDL2/SDL_cpuinfo.h +0 -594
- data/assets/include/SDL2/SDL_endian.h +0 -348
- data/assets/include/SDL2/SDL_error.h +0 -163
- data/assets/include/SDL2/SDL_events.h +0 -1166
- data/assets/include/SDL2/SDL_filesystem.h +0 -149
- data/assets/include/SDL2/SDL_gamecontroller.h +0 -1074
- data/assets/include/SDL2/SDL_gesture.h +0 -117
- data/assets/include/SDL2/SDL_guid.h +0 -100
- data/assets/include/SDL2/SDL_haptic.h +0 -1341
- data/assets/include/SDL2/SDL_hidapi.h +0 -451
- data/assets/include/SDL2/SDL_hints.h +0 -2569
- data/assets/include/SDL2/SDL_image.h +0 -2173
- data/assets/include/SDL2/SDL_joystick.h +0 -1066
- data/assets/include/SDL2/SDL_keyboard.h +0 -353
- data/assets/include/SDL2/SDL_keycode.h +0 -358
- data/assets/include/SDL2/SDL_loadso.h +0 -115
- data/assets/include/SDL2/SDL_log.h +0 -404
- data/assets/include/SDL2/SDL_main.h +0 -275
- data/assets/include/SDL2/SDL_mixer.h +0 -2784
- data/assets/include/SDL2/SDL_mouse.h +0 -465
- data/assets/include/SDL2/SDL_mutex.h +0 -471
- data/assets/include/SDL2/SDL_name.h +0 -33
- data/assets/include/SDL2/SDL_pixels.h +0 -644
- data/assets/include/SDL2/SDL_platform.h +0 -261
- data/assets/include/SDL2/SDL_quit.h +0 -58
- data/assets/include/SDL2/SDL_rect.h +0 -376
- data/assets/include/SDL2/SDL_render.h +0 -1919
- data/assets/include/SDL2/SDL_revision.h +0 -6
- data/assets/include/SDL2/SDL_rwops.h +0 -841
- data/assets/include/SDL2/SDL_sensor.h +0 -322
- data/assets/include/SDL2/SDL_shape.h +0 -155
- data/assets/include/SDL2/SDL_stdinc.h +0 -830
- data/assets/include/SDL2/SDL_surface.h +0 -997
- data/assets/include/SDL2/SDL_system.h +0 -623
- data/assets/include/SDL2/SDL_syswm.h +0 -386
- data/assets/include/SDL2/SDL_test_images.h +0 -78
- data/assets/include/SDL2/SDL_test_random.h +0 -115
- data/assets/include/SDL2/SDL_thread.h +0 -464
- data/assets/include/SDL2/SDL_timer.h +0 -222
- data/assets/include/SDL2/SDL_touch.h +0 -150
- data/assets/include/SDL2/SDL_ttf.h +0 -2316
- data/assets/include/SDL2/SDL_types.h +0 -29
- data/assets/include/SDL2/SDL_version.h +0 -204
- data/assets/include/SDL2/SDL_video.h +0 -2150
- data/assets/include/SDL2/SDL_vulkan.h +0 -215
- data/assets/include/SDL2/begin_code.h +0 -187
- data/assets/include/mruby/boxing_no.h +0 -58
- data/assets/include/mruby/class.h +0 -108
- data/assets/include/mruby/error.h +0 -147
- data/assets/include/mruby/gc.h +0 -94
- data/assets/include/mruby/irep.h +0 -147
- data/assets/include/mruby/khash.h +0 -284
- data/assets/include/mruby/object.h +0 -43
- data/assets/include/mruby/presym/disable.h +0 -70
- data/assets/include/mruby/presym/enable.h +0 -37
- data/assets/include/mruby/presym.h +0 -40
- data/assets/include/mruby/proc.h +0 -211
- data/assets/include/mruby/throw.h +0 -66
- data/assets/macos/universal/bin/mrbc +0 -0
- data/assets/macos/universal/lib/libFLAC.a +0 -0
- data/assets/macos/universal/lib/libSDL2.a +0 -0
- data/assets/macos/universal/lib/libSDL2_image.a +0 -0
- data/assets/macos/universal/lib/libSDL2_mixer.a +0 -0
- data/assets/macos/universal/lib/libSDL2_ttf.a +0 -0
- data/assets/macos/universal/lib/libavif.a +0 -0
- data/assets/macos/universal/lib/libbrotlicommon-static.a +0 -0
- data/assets/macos/universal/lib/libbrotlidec-static.a +0 -0
- data/assets/macos/universal/lib/libfreetype.a +0 -0
- data/assets/macos/universal/lib/libgraphite2.a +0 -0
- data/assets/macos/universal/lib/libharfbuzz.a +0 -0
- data/assets/macos/universal/lib/libhwy.a +0 -0
- data/assets/macos/universal/lib/libjpeg.a +0 -0
- data/assets/macos/universal/lib/libjxl.a +0 -0
- data/assets/macos/universal/lib/libmodplug.a +0 -0
- data/assets/macos/universal/lib/libmpg123.a +0 -0
- data/assets/macos/universal/lib/libmruby.a +0 -0
- data/assets/macos/universal/lib/libogg.a +0 -0
- data/assets/macos/universal/lib/libpng.a +0 -0
- data/assets/macos/universal/lib/libtiff.a +0 -0
- data/assets/macos/universal/lib/libvorbis.a +0 -0
- data/assets/macos/universal/lib/libvorbisfile.a +0 -0
- data/assets/macos/universal/lib/libwebp.a +0 -0
- data/assets/macos/universal/lib/libzstd.a +0 -0
- data/assets/test_media/README.md +0 -3
- data/assets/test_media/bitstream_vera/COPYRIGHT.txt +0 -124
- data/assets/test_media/bitstream_vera/vera.ttf +0 -0
- data/assets/test_media/boom.png +0 -0
- data/assets/test_media/coin.png +0 -0
- data/assets/test_media/colors.png +0 -0
- data/assets/test_media/controller.png +0 -0
- data/assets/test_media/dial.wav +0 -0
- data/assets/test_media/hero.png +0 -0
- data/assets/test_media/image.bmp +0 -0
- data/assets/test_media/image.jpg +0 -0
- data/assets/test_media/image.png +0 -0
- data/assets/test_media/music.flac +0 -0
- data/assets/test_media/music.mp3 +0 -0
- data/assets/test_media/music.ogg +0 -0
- data/assets/test_media/music.wav +0 -0
- data/assets/test_media/originals/boom.pxm +0 -0
- data/assets/test_media/originals/coin.pxm +0 -0
- data/assets/test_media/originals/controller.sketch +0 -0
- data/assets/test_media/originals/hero.pxm +0 -0
- data/assets/test_media/originals/image.pxm +0 -0
- data/assets/test_media/originals/music.caf +0 -0
- data/assets/test_media/originals/texture_atlas.pxm +0 -0
- data/assets/test_media/rondo_alla_turka.ogg +0 -0
- data/assets/test_media/sound.flac +0 -0
- data/assets/test_media/sound.mp3 +0 -0
- data/assets/test_media/sound.ogg +0 -0
- data/assets/test_media/sound.wav +0 -0
- data/assets/test_media/sprite_sheet.png +0 -0
- data/assets/test_media/texture_atlas.png +0 -0
- data/assets/wasm/libmruby.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/bin/mrbc.exe +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libFLAC.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libLerc.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_image.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_mixer.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_ttf.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libbrotlicommon.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libbrotlidec.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libbz2.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libdeflate.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libfreetype.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libglew32.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libgraphite2.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libharfbuzz.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libhwy.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libjbig.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libjpeg.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libjxl.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/liblzma.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libmodplug.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libmpg123.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libmruby.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libogg.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libopus.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libopusfile.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libpng.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libsndfile.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libssp.a +0 -1
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libstdc++.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libtiff.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libvorbis.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libvorbisfile.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libwebp.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libz.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libzstd.a +0 -0
- data/assets/windows/mingw-w64-x86_64/bin/mrbc.exe +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libFLAC.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libLerc.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libSDL2.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libSDL2_image.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libSDL2_mixer.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libSDL2_ttf.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libbrotlicommon.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libbrotlidec.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libbz2.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libdeflate.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libfreetype.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libglew32.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libgraphite2.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libharfbuzz.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libhwy.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libjbig.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libjpeg.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libjxl.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/liblzma.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libmodplug.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libmpg123.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libmruby.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libogg.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libopus.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libopusfile.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libpng.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libsndfile.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libssp.a +0 -1
- data/assets/windows/mingw-w64-x86_64/lib/libstdc++.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libtiff.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libvorbis.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libvorbisfile.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libwebp.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libz.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libzstd.a +0 -0
- data/assets/xcode/ios/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -98
- data/assets/xcode/ios/Assets.xcassets/Contents.json +0 -6
- data/assets/xcode/ios/Base.lproj/LaunchScreen.storyboard +0 -27
- data/assets/xcode/ios/Info.plist +0 -43
- data/assets/xcode/ios/MRuby.framework/Headers/mrbconf.h +0 -143
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/array.h +0 -280
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/boxing_nan.h +0 -102
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/boxing_no.h +0 -56
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/boxing_word.h +0 -144
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/class.h +0 -97
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/common.h +0 -77
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/compile.h +0 -195
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/data.h +0 -75
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/debug.h +0 -67
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/dump.h +0 -196
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/error.h +0 -75
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/gc.h +0 -91
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/hash.h +0 -215
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/irep.h +0 -75
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/istruct.h +0 -47
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/khash.h +0 -274
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/numeric.h +0 -161
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/object.h +0 -44
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/opcode.h +0 -69
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/ops.h +0 -117
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/proc.h +0 -131
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/range.h +0 -49
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/re.h +0 -16
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/string.h +0 -444
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/throw.h +0 -55
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/value.h +0 -309
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/variable.h +0 -136
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/version.h +0 -110
- data/assets/xcode/ios/MRuby.framework/Headers/mruby.h +0 -1282
- data/assets/xcode/ios/MRuby.framework/Info.plist +0 -20
- data/assets/xcode/ios/MRuby.framework/MRuby +0 -0
- data/assets/xcode/ios/MyApp.xcodeproj/project.pbxproj +0 -368
- data/assets/xcode/ios/MyApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- data/assets/xcode/ios/MyApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- data/assets/xcode/ios/MyApp.xcodeproj/project.xcworkspace/xcshareddata/MyApp.xcscmblueprint +0 -30
- data/assets/xcode/ios/main.c +0 -1
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json +0 -16
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Contents.json +0 -6
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Contents.json +0 -17
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Contents.json +0 -16
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Contents.json +0 -6
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json +0 -16
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Contents.json +0 -6
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json +0 -16
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Contents.json +0 -6
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Contents.json +0 -17
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Contents.json +0 -16
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Contents.json +0 -6
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json +0 -16
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Contents.json +0 -6
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json +0 -32
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json +0 -16
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json +0 -16
- data/assets/xcode/tvos/Assets.xcassets/Contents.json +0 -6
- data/assets/xcode/tvos/Assets.xcassets/LaunchImage.launchimage/Contents.json +0 -22
- data/assets/xcode/tvos/Info.plist +0 -30
- data/assets/xcode/tvos/MRuby.framework/Headers/mrbconf.h +0 -143
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/array.h +0 -280
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/boxing_nan.h +0 -102
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/boxing_no.h +0 -56
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/boxing_word.h +0 -144
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/class.h +0 -97
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/common.h +0 -77
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/compile.h +0 -195
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/data.h +0 -75
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/debug.h +0 -67
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/dump.h +0 -196
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/error.h +0 -75
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/gc.h +0 -91
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/hash.h +0 -215
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/irep.h +0 -75
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/istruct.h +0 -47
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/khash.h +0 -274
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/numeric.h +0 -161
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/object.h +0 -44
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/opcode.h +0 -69
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/ops.h +0 -117
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/proc.h +0 -131
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/range.h +0 -49
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/re.h +0 -16
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/string.h +0 -444
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/throw.h +0 -55
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/value.h +0 -309
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/variable.h +0 -136
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/version.h +0 -110
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby.h +0 -1282
- data/assets/xcode/tvos/MRuby.framework/Info.plist +0 -20
- data/assets/xcode/tvos/MRuby.framework/MRuby +0 -0
- data/assets/xcode/tvos/MyApp.xcodeproj/project.pbxproj +0 -350
- data/assets/xcode/tvos/MyApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- data/assets/xcode/tvos/MyApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- data/assets/xcode/tvos/MyApp.xcodeproj/project.xcworkspace/xcshareddata/MyApp.xcscmblueprint +0 -30
- data/assets/xcode/tvos/main.c +0 -1
- data/ext/ruby2d/common.c +0 -185
- data/ext/ruby2d/controllers.c +0 -110
- data/ext/ruby2d/gl.c +0 -398
- data/ext/ruby2d/gl2.c +0 -86
- data/ext/ruby2d/gl3.c +0 -304
- data/ext/ruby2d/gles.c +0 -302
- data/ext/ruby2d/input.c +0 -48
- data/ext/ruby2d/music.c +0 -127
- data/ext/ruby2d/sound.c +0 -132
- data/lib/ruby2d/cli/console.rb +0 -65
- data/lib/ruby2d/cli/enable_console.rb +0 -7
- data/lib/ruby2d/cli/platform.rb +0 -17
- data/lib/ruby2d/music.rb +0 -77
- data/lib/ruby2d/pixel.rb +0 -18
- data/lib/ruby2d/pixmap.rb +0 -39
- data/lib/ruby2d/pixmap_atlas.rb +0 -56
- data/lib/ruby2d/sound.rb +0 -61
- data/lib/ruby2d/texture.rb +0 -38
- /data/assets/{include/SDL2 → platform/include/SDL3}/SDL_opengles2_gl2.h +0 -0
- /data/assets/{include/SDL2 → platform/include/SDL3}/SDL_opengles2_gl2ext.h +0 -0
- /data/assets/{include/SDL2 → platform/include/SDL3}/SDL_opengles2_gl2platform.h +0 -0
- /data/assets/{include/SDL2 → platform/include/SDL3}/SDL_opengles2_khrplatform.h +0 -0
- /data/assets/{include → platform/include}/mruby/re.h +0 -0
data/examples/outrun.rb
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
# Out Run
|
|
2
|
+
# A pseudo-3D arcade racer, classic Sega-style — a rollercoaster of big hills and near-constant curves.
|
|
3
|
+
#
|
|
4
|
+
# Up throttles, down brakes, left/right steer. Stay on the asphalt —
|
|
5
|
+
# the grass will bog you down. Press `r` to restart. The course is laid
|
|
6
|
+
# out as discrete pieces (straights, curves, hills) joined end to end,
|
|
7
|
+
# each easing its bend in and out so the road flows without kinks.
|
|
8
|
+
|
|
9
|
+
require 'ruby2d'
|
|
10
|
+
|
|
11
|
+
# === Tunables ===
|
|
12
|
+
|
|
13
|
+
WIDTH = 900 # window width in pixels
|
|
14
|
+
HEIGHT = 540 # window height in pixels
|
|
15
|
+
ROAD_WIDTH = 2000 # half-width of the road in world units
|
|
16
|
+
SEGMENT_LENGTH = 200 # depth of each road slice (world units)
|
|
17
|
+
RUMBLE_LENGTH = 3 # segments per rumble color block
|
|
18
|
+
LANES = 3 # lanes between the rumble strips
|
|
19
|
+
DRAW_DISTANCE = 220 # segments rendered ahead of the camera
|
|
20
|
+
FIELD_OF_VIEW = 100 # vertical FOV in degrees
|
|
21
|
+
CAMERA_HEIGHT = 1000 # camera height above the road (world units)
|
|
22
|
+
MAX_SPEED = 12000.0 # top speed (world units/sec)
|
|
23
|
+
ACCEL = MAX_SPEED / 4.5 # throttle acceleration (units/sec²)
|
|
24
|
+
BRAKING = -MAX_SPEED # brake deceleration (units/sec²)
|
|
25
|
+
DECEL = -MAX_SPEED / 5.5 # passive coast deceleration (units/sec²)
|
|
26
|
+
OFF_ROAD_DECEL = -MAX_SPEED # extra deceleration on grass (units/sec²)
|
|
27
|
+
OFF_ROAD_LIMIT = MAX_SPEED * 0.25 # speed cap with both wheels on grass
|
|
28
|
+
CENTRIFUGAL = 0.28 # outward pull on curves at top speed (1/sec)
|
|
29
|
+
STEER_RATE = 1.8 # max road-widths/sec lateral movement at full speed
|
|
30
|
+
|
|
31
|
+
# Road-piece vocabulary. A piece is `len` slices long in each of its three
|
|
32
|
+
# phases (ease in, hold, ease out); curve is the bend, hill the rise/fall.
|
|
33
|
+
SEG_SHORT = 25 # slices per phase in a short piece
|
|
34
|
+
SEG_MEDIUM = 50 # slices per phase in a medium piece
|
|
35
|
+
SEG_LONG = 100 # slices per phase in a long piece
|
|
36
|
+
CURVE_EASY = 2.0 # gentle bend
|
|
37
|
+
CURVE_MED = 4.0 # sweeping bend
|
|
38
|
+
CURVE_HARD = 6.0 # tight bend
|
|
39
|
+
HILL_LOW = 2500 # low crest (world y units)
|
|
40
|
+
HILL_MED = 5000 # medium crest
|
|
41
|
+
HILL_HIGH = 8000 # tall crest — you crest it blind
|
|
42
|
+
|
|
43
|
+
# Sunset Outrun palette
|
|
44
|
+
SKY_TOP = '#1e1148'
|
|
45
|
+
SKY_HORIZON = '#ed7d3a'
|
|
46
|
+
SUN = '#fde68a'
|
|
47
|
+
SUN_GLOW = '#f97316'
|
|
48
|
+
ROAD_LIGHT = '#6b6b6b'
|
|
49
|
+
ROAD_DARK = '#5a5a5a'
|
|
50
|
+
GRASS_LIGHT = '#1a8c50'
|
|
51
|
+
GRASS_DARK = '#137d44'
|
|
52
|
+
RUMBLE_LIGHT = '#fafafa'
|
|
53
|
+
RUMBLE_DARK = '#dc2626'
|
|
54
|
+
LANE_COLOR = '#fafafa'
|
|
55
|
+
|
|
56
|
+
# Car palette
|
|
57
|
+
CAR_RED = '#e11d2a' # bodywork
|
|
58
|
+
CAR_RED_LO = '#8f1418' # shaded lower body / bumper
|
|
59
|
+
CAR_GLASS = '#0b1220' # rear window
|
|
60
|
+
CAR_TIRE = '#0a0a0d' # tires
|
|
61
|
+
TAIL_ON = '#ff3b3b' # taillights
|
|
62
|
+
TAIL_BRAKE = '#ffd0d0' # taillights under braking (hot)
|
|
63
|
+
|
|
64
|
+
# === Window ===
|
|
65
|
+
|
|
66
|
+
set title: 'Ruby 2D ▸ Examples ▸ Out Run',
|
|
67
|
+
width: WIDTH, height: HEIGHT, background: SKY_TOP
|
|
68
|
+
set close_on_esc: true
|
|
69
|
+
|
|
70
|
+
# === Helpers ===
|
|
71
|
+
|
|
72
|
+
CAMERA_DEPTH = 1.0 / Math.tan((FIELD_OF_VIEW / 2.0) * Math::PI / 180.0)
|
|
73
|
+
PLAYER_Z = CAMERA_HEIGHT * CAMERA_DEPTH
|
|
74
|
+
|
|
75
|
+
def lerp(a, b, t)
|
|
76
|
+
a + (b - a) * t
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
# Quadratic ease from a to b (slow start), and a cosine ease-in-out (slow
|
|
80
|
+
# at both ends). Used to ramp a piece's curve and elevation smoothly.
|
|
81
|
+
def ease_in(a, b, t)
|
|
82
|
+
a + (b - a) * t * t
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
def ease_in_out(a, b, t)
|
|
86
|
+
a + (b - a) * (0.5 - Math.cos(t * Math::PI) / 2.0)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Pinhole projection: turn a world point (x, y, z) into screen coords plus the
|
|
90
|
+
# road's projected half-width at that depth. Returns [sx, sy, sw, scale, rel_z].
|
|
91
|
+
def project(world_x, world_y, world_z, cam_x, cam_y, cam_z)
|
|
92
|
+
rel_z = world_z - cam_z
|
|
93
|
+
rel_z = 0.0001 if rel_z < 0.0001
|
|
94
|
+
scale = CAMERA_DEPTH / rel_z
|
|
95
|
+
sx = WIDTH * 0.5 + scale * (world_x - cam_x) * WIDTH * 0.5
|
|
96
|
+
sy = HEIGHT * 0.5 - scale * (world_y - cam_y) * HEIGHT * 0.5
|
|
97
|
+
sw = scale * ROAD_WIDTH * WIDTH * 0.5
|
|
98
|
+
[sx, sy, sw, scale, rel_z]
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
# The player's car, drawn rear-on from a few stacked rectangles — enough to
|
|
102
|
+
# read as a car without stealing the show from the road. The body leans by
|
|
103
|
+
# `lean` into a turn while the tires stay planted; the taillights flare
|
|
104
|
+
# near-white while `braking`.
|
|
105
|
+
def draw_car(cx, base_y, lean, braking)
|
|
106
|
+
bw = 124 # body width
|
|
107
|
+
bh = 34 # body height
|
|
108
|
+
cw = 80 # cabin width
|
|
109
|
+
ch = 26 # cabin height
|
|
110
|
+
tw = 24 # tire width
|
|
111
|
+
th = 18 # tire height showing below the body
|
|
112
|
+
body_top = base_y - th - bh
|
|
113
|
+
cabin_top = body_top - ch
|
|
114
|
+
lc = cx + lean # body leans; tires and shadow stay planted
|
|
115
|
+
|
|
116
|
+
# Ground shadow.
|
|
117
|
+
Rectangle.render(x: cx - bw / 2 - 6, y: base_y - 5, width: bw + 12, height: 9,
|
|
118
|
+
color: [0, 0, 0, 0.30])
|
|
119
|
+
|
|
120
|
+
# Rear tires at the corners.
|
|
121
|
+
Rectangle.render(x: cx - bw / 2 - 2, y: base_y - th - 4, width: tw, height: th + 8, color: CAR_TIRE)
|
|
122
|
+
Rectangle.render(x: cx + bw / 2 - tw + 2, y: base_y - th - 4, width: tw, height: th + 8, color: CAR_TIRE)
|
|
123
|
+
|
|
124
|
+
# Cabin with a dark rear window.
|
|
125
|
+
Rectangle.render(x: lc - cw / 2, y: cabin_top, width: cw, height: ch, color: CAR_RED)
|
|
126
|
+
Rectangle.render(x: lc - cw / 2 + 9, y: cabin_top + 6, width: cw - 18, height: ch - 11, color: CAR_GLASS)
|
|
127
|
+
|
|
128
|
+
# Body with a darker bumper band.
|
|
129
|
+
Rectangle.render(x: lc - bw / 2, y: body_top, width: bw, height: bh, color: CAR_RED)
|
|
130
|
+
Rectangle.render(x: lc - bw / 2, y: body_top + bh - 9, width: bw, height: 9, color: CAR_RED_LO)
|
|
131
|
+
|
|
132
|
+
# Taillights (flare white under braking).
|
|
133
|
+
lamp = braking ? TAIL_BRAKE : TAIL_ON
|
|
134
|
+
Rectangle.render(x: lc - bw / 2 + 10, y: body_top + bh - 22, width: 26, height: 11, color: lamp)
|
|
135
|
+
Rectangle.render(x: lc + bw / 2 - 36, y: body_top + bh - 22, width: 26, height: 11, color: lamp)
|
|
136
|
+
end
|
|
137
|
+
|
|
138
|
+
# === Track ===
|
|
139
|
+
#
|
|
140
|
+
# The course is assembled from discrete pieces — straights, curves and hills —
|
|
141
|
+
# rather than one endless wave, so the drive has a rhythm: open straights to
|
|
142
|
+
# wind out the throttle, then a sweeper or a crest, then room to settle before
|
|
143
|
+
# the next feature. `add_road` eases each piece's curve in and out and its
|
|
144
|
+
# elevation from the current height to the next, so pieces join without kinks.
|
|
145
|
+
|
|
146
|
+
segments = []
|
|
147
|
+
|
|
148
|
+
# Append one road slice; `color` alternates every RUMBLE_LENGTH slices to paint
|
|
149
|
+
# the rumble strips and grass stripes.
|
|
150
|
+
add_segment = lambda do |curve, y|
|
|
151
|
+
segments << { curve: curve, y: y,
|
|
152
|
+
color: (segments.length / RUMBLE_LENGTH).even? ? :light : :dark }
|
|
153
|
+
end
|
|
154
|
+
|
|
155
|
+
# Lay a piece `len` slices long in each phase: ease the curve up from straight,
|
|
156
|
+
# hold it, then ease back to straight, while the elevation eases from the
|
|
157
|
+
# current height by `hill` world units across the whole piece.
|
|
158
|
+
add_road = lambda do |len, curve, hill|
|
|
159
|
+
start_y = segments.empty? ? 0.0 : segments.last[:y]
|
|
160
|
+
end_y = start_y + hill
|
|
161
|
+
total = 3.0 * len
|
|
162
|
+
(0...len).each { |n| add_segment.call(ease_in(0, curve, n / len.to_f), ease_in_out(start_y, end_y, n / total)) }
|
|
163
|
+
(0...len).each { |n| add_segment.call(curve, ease_in_out(start_y, end_y, (len + n) / total)) }
|
|
164
|
+
(0...len).each { |n| add_segment.call(ease_in_out(curve, 0, n / len.to_f), ease_in_out(start_y, end_y, (2 * len + n) / total)) }
|
|
165
|
+
end
|
|
166
|
+
|
|
167
|
+
# The lap, piece by piece: [slices, curve, hill]. Features come thick and
|
|
168
|
+
# fast with only brief straights to punctuate. Each climb is paired with an
|
|
169
|
+
# equal descent of the same length, so the hill deltas cancel and the loop
|
|
170
|
+
# closes flat; both ends are straight so there's no seam.
|
|
171
|
+
TRACK = [
|
|
172
|
+
[SEG_SHORT, 0, 0], # brief straight off the line
|
|
173
|
+
[SEG_MEDIUM, CURVE_MED, HILL_HIGH], # right-hander up a big hill
|
|
174
|
+
[SEG_MEDIUM, -CURVE_MED, -HILL_HIGH], # left-hander back down
|
|
175
|
+
[SEG_SHORT, CURVE_HARD, HILL_MED], # tight right, climbing
|
|
176
|
+
[SEG_SHORT, -CURVE_HARD, -HILL_MED], # tight left, descending
|
|
177
|
+
[SEG_MEDIUM, 0, HILL_HIGH], # straight up a blind crest
|
|
178
|
+
[SEG_MEDIUM, CURVE_EASY, -HILL_HIGH], # over the top, ease right, drop
|
|
179
|
+
[SEG_MEDIUM, -CURVE_MED, HILL_MED], # left sweeper up
|
|
180
|
+
[SEG_MEDIUM, CURVE_MED, -HILL_MED], # right sweeper down
|
|
181
|
+
[SEG_SHORT, -CURVE_HARD, HILL_LOW], # tight left, small rise
|
|
182
|
+
[SEG_SHORT, CURVE_HARD, -HILL_LOW], # tight right, small drop
|
|
183
|
+
[SEG_MEDIUM, CURVE_MED, HILL_HIGH], # sweeping right up the last big hill
|
|
184
|
+
[SEG_MEDIUM, -CURVE_MED, -HILL_HIGH], # sweeping left, back to flat
|
|
185
|
+
[SEG_SHORT, 0, 0] # settle into the loop
|
|
186
|
+
].freeze
|
|
187
|
+
|
|
188
|
+
TRACK.each { |len, curve, hill| add_road.call(len, curve, hill) }
|
|
189
|
+
|
|
190
|
+
TRACK_SEGMENTS = segments.length
|
|
191
|
+
TRACK_LENGTH = TRACK_SEGMENTS * SEGMENT_LENGTH
|
|
192
|
+
|
|
193
|
+
# === Persistent renderables ===
|
|
194
|
+
|
|
195
|
+
# Sky: vertical gradient from deep purple at the top to sunset orange at the
|
|
196
|
+
# horizon. Drawn at z:-10 so the render block's road quads (z:0) stack on top.
|
|
197
|
+
Quad.new(
|
|
198
|
+
x1: 0, y1: 0, x2: WIDTH, y2: 0,
|
|
199
|
+
x3: WIDTH, y3: HEIGHT * 0.55, x4: 0, y4: HEIGHT * 0.55,
|
|
200
|
+
color: [SKY_TOP, SKY_TOP, SKY_HORIZON, SKY_HORIZON],
|
|
201
|
+
z: -10
|
|
202
|
+
)
|
|
203
|
+
|
|
204
|
+
# Distant ground: a haze band from the horizon down to the bottom, continuing
|
|
205
|
+
# the gradient into grass. The road's grass quads cover it during normal
|
|
206
|
+
# driving; it only shows through where a big hill crest leaves the far road out
|
|
207
|
+
# of view, so those gaps read as distant haze instead of the bare background.
|
|
208
|
+
Quad.new(
|
|
209
|
+
x1: 0, y1: HEIGHT * 0.55, x2: WIDTH, y2: HEIGHT * 0.55,
|
|
210
|
+
x3: WIDTH, y3: HEIGHT, x4: 0, y4: HEIGHT,
|
|
211
|
+
color: [SKY_HORIZON, SKY_HORIZON, GRASS_DARK, GRASS_DARK],
|
|
212
|
+
z: -10
|
|
213
|
+
)
|
|
214
|
+
|
|
215
|
+
sun_glow = Circle.new(x: WIDTH * 0.7, y: HEIGHT * 0.32,
|
|
216
|
+
radius: 130, color: SUN_GLOW, opacity: 0.45, z: -9)
|
|
217
|
+
sun = Circle.new(x: WIDTH * 0.7, y: HEIGHT * 0.32,
|
|
218
|
+
radius: 75, color: SUN, z: -8)
|
|
219
|
+
|
|
220
|
+
speed_label = Text.new('Speed: 0 km/h', x: 16, y: 12,
|
|
221
|
+
size: 18, color: '#ffffff', z: 30)
|
|
222
|
+
Text.new('↑ throttle ↓ brake ←/→ steer R restart',
|
|
223
|
+
x: 16, y: HEIGHT - 28, size: 13,
|
|
224
|
+
color: '#ffffff', z: 30, opacity: 0.75)
|
|
225
|
+
|
|
226
|
+
# === Mutable state ===
|
|
227
|
+
|
|
228
|
+
position = 0.0 # camera z along the track (player is PLAYER_Z ahead)
|
|
229
|
+
player_x = 0.0 # lateral offset; -1 = left rumble, +1 = right rumble
|
|
230
|
+
speed = 0.0
|
|
231
|
+
throttle = false
|
|
232
|
+
brake = false
|
|
233
|
+
steer = 0
|
|
234
|
+
sun_offset = 0.0
|
|
235
|
+
|
|
236
|
+
reset = lambda do
|
|
237
|
+
position = 0.0
|
|
238
|
+
player_x = 0.0
|
|
239
|
+
speed = 0.0
|
|
240
|
+
throttle = false
|
|
241
|
+
brake = false
|
|
242
|
+
steer = 0
|
|
243
|
+
sun_offset = 0.0
|
|
244
|
+
sun.x = WIDTH * 0.7
|
|
245
|
+
sun_glow.x = WIDTH * 0.7
|
|
246
|
+
end
|
|
247
|
+
reset.call
|
|
248
|
+
|
|
249
|
+
# === Input ===
|
|
250
|
+
|
|
251
|
+
on :key_down do |event|
|
|
252
|
+
case event.key
|
|
253
|
+
when 'up' then throttle = true
|
|
254
|
+
when 'down' then brake = true
|
|
255
|
+
when 'left' then steer = -1
|
|
256
|
+
when 'right' then steer = 1
|
|
257
|
+
when 'r' then reset.call
|
|
258
|
+
end
|
|
259
|
+
end
|
|
260
|
+
|
|
261
|
+
on :key_up do |event|
|
|
262
|
+
case event.key
|
|
263
|
+
when 'up' then throttle = false
|
|
264
|
+
when 'down' then brake = false
|
|
265
|
+
when 'left' then steer = 0 if steer == -1
|
|
266
|
+
when 'right' then steer = 0 if steer == 1
|
|
267
|
+
end
|
|
268
|
+
end
|
|
269
|
+
|
|
270
|
+
# === Per-frame update ===
|
|
271
|
+
|
|
272
|
+
update do |dt|
|
|
273
|
+
if throttle
|
|
274
|
+
speed += ACCEL * dt
|
|
275
|
+
elsif brake
|
|
276
|
+
speed += BRAKING * dt
|
|
277
|
+
else
|
|
278
|
+
speed += DECEL * dt
|
|
279
|
+
end
|
|
280
|
+
|
|
281
|
+
if player_x.abs > 1.0 && speed > OFF_ROAD_LIMIT
|
|
282
|
+
speed += OFF_ROAD_DECEL * dt
|
|
283
|
+
end
|
|
284
|
+
|
|
285
|
+
speed = speed.clamp(0, MAX_SPEED)
|
|
286
|
+
speed_pct = speed / MAX_SPEED
|
|
287
|
+
|
|
288
|
+
player_x += STEER_RATE * speed_pct * steer * dt
|
|
289
|
+
|
|
290
|
+
# Centrifugal pull uses the curve under the player (not the camera),
|
|
291
|
+
# interpolated across the segment boundary so the auto-turn drifts smoothly
|
|
292
|
+
# instead of stepping once per segment.
|
|
293
|
+
ahead = position + PLAYER_Z
|
|
294
|
+
player_idx = (ahead / SEGMENT_LENGTH).floor % TRACK_SEGMENTS
|
|
295
|
+
next_idx = (player_idx + 1) % TRACK_SEGMENTS
|
|
296
|
+
player_frac = (ahead % SEGMENT_LENGTH) / SEGMENT_LENGTH
|
|
297
|
+
curve_here = lerp(segments[player_idx][:curve], segments[next_idx][:curve], player_frac)
|
|
298
|
+
player_x -= dt * speed_pct * curve_here * CENTRIFUGAL
|
|
299
|
+
|
|
300
|
+
position = (position + speed * dt) % TRACK_LENGTH
|
|
301
|
+
|
|
302
|
+
# Sun parallax: drift opposite to the road's heading so curves "feel" like
|
|
303
|
+
# they're carrying the world past the camera.
|
|
304
|
+
sun_offset -= curve_here * speed_pct * dt * 28
|
|
305
|
+
sun.x = WIDTH * 0.7 + sun_offset
|
|
306
|
+
sun_glow.x = sun.x
|
|
307
|
+
|
|
308
|
+
speed_text = "Speed: #{(speed_pct * 280).round} km/h"
|
|
309
|
+
speed_label.content = speed_text unless speed_label.content == speed_text
|
|
310
|
+
end
|
|
311
|
+
|
|
312
|
+
# === Render ===
|
|
313
|
+
|
|
314
|
+
# The road draws at z:0 — above the sky/sun (z:-10..-8) and below the HUD (z:30).
|
|
315
|
+
render z: 0 do
|
|
316
|
+
base_idx = (position / SEGMENT_LENGTH).floor % TRACK_SEGMENTS
|
|
317
|
+
base_percent = (position % SEGMENT_LENGTH) / SEGMENT_LENGTH
|
|
318
|
+
|
|
319
|
+
player_idx = ((position + PLAYER_Z) / SEGMENT_LENGTH).floor % TRACK_SEGMENTS
|
|
320
|
+
player_percent = ((position + PLAYER_Z) % SEGMENT_LENGTH) / SEGMENT_LENGTH
|
|
321
|
+
player_y = lerp(segments[(player_idx - 1) % TRACK_SEGMENTS][:y],
|
|
322
|
+
segments[player_idx][:y], player_percent)
|
|
323
|
+
|
|
324
|
+
cam_x = player_x * ROAD_WIDTH
|
|
325
|
+
cam_y = CAMERA_HEIGHT + player_y
|
|
326
|
+
|
|
327
|
+
x = 0.0
|
|
328
|
+
# Pre-load the curve accumulator with the slice of the base segment already
|
|
329
|
+
# behind the camera. Without it the road's bend snaps by a whole segment's
|
|
330
|
+
# curve each time the camera crosses a boundary — the "jerk" on turns.
|
|
331
|
+
dx = -(segments[base_idx][:curve] * base_percent)
|
|
332
|
+
maxy = HEIGHT.to_f
|
|
333
|
+
|
|
334
|
+
# Walk segments near→far, accumulating curve via `x`/`dx`. `maxy` tracks the
|
|
335
|
+
# highest screen-y already drawn so hill crests can hide segments behind them.
|
|
336
|
+
DRAW_DISTANCE.times do |n|
|
|
337
|
+
i = (base_idx + n) % TRACK_SEGMENTS
|
|
338
|
+
seg = segments[i]
|
|
339
|
+
near_z = (base_idx + n) * SEGMENT_LENGTH
|
|
340
|
+
far_z = near_z + SEGMENT_LENGTH
|
|
341
|
+
near_y = segments[(i - 1) % TRACK_SEGMENTS][:y]
|
|
342
|
+
far_y = seg[:y]
|
|
343
|
+
|
|
344
|
+
p1 = project(x, near_y, near_z, cam_x, cam_y, position)
|
|
345
|
+
p2 = project(x + dx, far_y, far_z, cam_x, cam_y, position)
|
|
346
|
+
|
|
347
|
+
x += dx
|
|
348
|
+
dx += seg[:curve]
|
|
349
|
+
|
|
350
|
+
next if p1[4] <= CAMERA_DEPTH # behind the camera plane
|
|
351
|
+
next if p2[1] >= maxy # hidden behind a closer hill crest
|
|
352
|
+
|
|
353
|
+
grass = seg[:color] == :dark ? GRASS_DARK : GRASS_LIGHT
|
|
354
|
+
Quad.render(x1: 0, y1: p2[1], x2: WIDTH, y2: p2[1],
|
|
355
|
+
x3: WIDTH, y3: p1[1], x4: 0, y4: p1[1], color: grass)
|
|
356
|
+
|
|
357
|
+
rumble = seg[:color] == :dark ? RUMBLE_DARK : RUMBLE_LIGHT
|
|
358
|
+
rw1 = p1[2] * 1.18
|
|
359
|
+
rw2 = p2[2] * 1.18
|
|
360
|
+
Quad.render(x1: p2[0] - rw2, y1: p2[1], x2: p2[0] + rw2, y2: p2[1],
|
|
361
|
+
x3: p1[0] + rw1, y3: p1[1], x4: p1[0] - rw1, y4: p1[1],
|
|
362
|
+
color: rumble)
|
|
363
|
+
|
|
364
|
+
road = seg[:color] == :dark ? ROAD_DARK : ROAD_LIGHT
|
|
365
|
+
Quad.render(x1: p2[0] - p2[2], y1: p2[1], x2: p2[0] + p2[2], y2: p2[1],
|
|
366
|
+
x3: p1[0] + p1[2], y3: p1[1], x4: p1[0] - p1[2], y4: p1[1],
|
|
367
|
+
color: road)
|
|
368
|
+
|
|
369
|
+
if seg[:color] == :light
|
|
370
|
+
lw1 = p1[2] * 0.025
|
|
371
|
+
lw2 = p2[2] * 0.025
|
|
372
|
+
(1...LANES).each do |l|
|
|
373
|
+
offset = -1.0 + 2.0 * l / LANES
|
|
374
|
+
Quad.render(
|
|
375
|
+
x1: p2[0] + offset * p2[2] - lw2, y1: p2[1],
|
|
376
|
+
x2: p2[0] + offset * p2[2] + lw2, y2: p2[1],
|
|
377
|
+
x3: p1[0] + offset * p1[2] + lw1, y3: p1[1],
|
|
378
|
+
x4: p1[0] + offset * p1[2] - lw1, y4: p1[1],
|
|
379
|
+
color: LANE_COLOR
|
|
380
|
+
)
|
|
381
|
+
end
|
|
382
|
+
end
|
|
383
|
+
|
|
384
|
+
maxy = p2[1]
|
|
385
|
+
end
|
|
386
|
+
|
|
387
|
+
# Player car, centered on screen; steering leans it into the turn.
|
|
388
|
+
draw_car(WIDTH / 2.0, HEIGHT - 8, steer * 7, brake)
|
|
389
|
+
end
|
|
390
|
+
|
|
391
|
+
show
|
|
@@ -0,0 +1,313 @@
|
|
|
1
|
+
# Pixel paint
|
|
2
|
+
# An interactive painting app built with Canvas, with a full tool palette.
|
|
3
|
+
#
|
|
4
|
+
# Toolbar offers color swatches, shape selectors (square, circle,
|
|
5
|
+
# triangle), brush sizes, an eraser, and a clear button. Click and drag
|
|
6
|
+
# on the canvas area to paint. Tests Canvas drawing primitives, partial
|
|
7
|
+
# clears, and mouse interaction.
|
|
8
|
+
|
|
9
|
+
require 'ruby2d'
|
|
10
|
+
|
|
11
|
+
# === Tunables ===
|
|
12
|
+
|
|
13
|
+
WINDOW_W = 640 # window width in pixels
|
|
14
|
+
WINDOW_H = 580 # window height in pixels
|
|
15
|
+
TOOLBAR_H = 90 # toolbar strip height in pixels
|
|
16
|
+
CANVAS_Y = TOOLBAR_H # derived: canvas starts below the toolbar
|
|
17
|
+
CANVAS_W = WINDOW_W # derived: canvas spans the full width
|
|
18
|
+
CANVAS_H = WINDOW_H - TOOLBAR_H # derived: canvas fills remaining height
|
|
19
|
+
|
|
20
|
+
# === Window ===
|
|
21
|
+
|
|
22
|
+
set title: 'Ruby 2D ▸ Examples ▸ Pixel paint', width: WINDOW_W, height: WINDOW_H, background: [0.1, 0.1, 0.15, 1]
|
|
23
|
+
set close_on_esc: true
|
|
24
|
+
set render_mode: :on_demand
|
|
25
|
+
|
|
26
|
+
# === Canvases ===
|
|
27
|
+
#
|
|
28
|
+
# Toolbar is drawn with its own Canvas so every icon is pixel-art consistent
|
|
29
|
+
# with the painting surface below it.
|
|
30
|
+
|
|
31
|
+
tb = Canvas.new(x: 0, y: 0, width: WINDOW_W, height: TOOLBAR_H, fill: [0.12, 0.12, 0.18, 1], z: 10)
|
|
32
|
+
tb.clear
|
|
33
|
+
|
|
34
|
+
canvas = Canvas.new(x: 0, y: CANVAS_Y, width: CANVAS_W, height: CANVAS_H, fill: [0.95, 0.93, 0.88, 1])
|
|
35
|
+
canvas.clear
|
|
36
|
+
|
|
37
|
+
# === State ===
|
|
38
|
+
|
|
39
|
+
COLORS = [
|
|
40
|
+
[0.07, 0.07, 0.07, 1], # black
|
|
41
|
+
[1.0, 0.25, 0.2, 1], # red
|
|
42
|
+
[1.0, 0.52, 0.1, 1], # orange
|
|
43
|
+
[1.0, 0.86, 0.0, 1], # yellow
|
|
44
|
+
[0.18, 0.8, 0.25, 1], # green
|
|
45
|
+
[0.0, 0.45, 0.85, 1], # blue
|
|
46
|
+
[0.69, 0.05, 0.79, 1], # purple
|
|
47
|
+
[0.94, 0.07, 0.75, 1], # fuchsia
|
|
48
|
+
[0.95, 0.93, 0.88, 1] # cream (canvas bg)
|
|
49
|
+
]
|
|
50
|
+
SHAPES = %i[square circle triangle]
|
|
51
|
+
SIZES = [4, 10, 20, 40]
|
|
52
|
+
|
|
53
|
+
current_color_idx = 0
|
|
54
|
+
current_shape_idx = 0
|
|
55
|
+
current_size_idx = 1
|
|
56
|
+
eraser_on = false
|
|
57
|
+
drawing = false
|
|
58
|
+
|
|
59
|
+
# === Toolbar icon drawing helpers ===
|
|
60
|
+
#
|
|
61
|
+
# All draw onto the `tb` canvas.
|
|
62
|
+
|
|
63
|
+
def px_rect(tb, x, y, w, h, color)
|
|
64
|
+
tb.fill_rectangle(x: x, y: y, width: w, height: h, color: color)
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
# --- Color swatches (row 1) ---
|
|
68
|
+
SWATCH_X0 = 12
|
|
69
|
+
SWATCH_Y = 10
|
|
70
|
+
SWATCH_SZ = 26
|
|
71
|
+
SWATCH_GAP = 6
|
|
72
|
+
|
|
73
|
+
def draw_color_swatches(tb, selected)
|
|
74
|
+
COLORS.each_with_index do |c, i|
|
|
75
|
+
sx = SWATCH_X0 + i * (SWATCH_SZ + SWATCH_GAP)
|
|
76
|
+
border = i == selected ? [1.0, 1.0, 1.0, 1.0] : [0.3, 0.3, 0.4, 1]
|
|
77
|
+
px_rect(tb, sx - 3, SWATCH_Y - 3, SWATCH_SZ + 6, SWATCH_SZ + 6, border)
|
|
78
|
+
px_rect(tb, sx, SWATCH_Y, SWATCH_SZ, SWATCH_SZ, c)
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
# --- Shape icons (row 2) ---
|
|
83
|
+
SHAPE_X0 = 12
|
|
84
|
+
SHAPE_Y = 50
|
|
85
|
+
SHAPE_BTN_W = 36
|
|
86
|
+
SHAPE_BTN_H = 30
|
|
87
|
+
SHAPE_GAP = 8
|
|
88
|
+
|
|
89
|
+
def draw_shape_icons(tb, selected)
|
|
90
|
+
SHAPES.each_with_index do |s, i|
|
|
91
|
+
bx = SHAPE_X0 + i * (SHAPE_BTN_W + SHAPE_GAP)
|
|
92
|
+
bg = i == selected ? [0.3, 0.3, 0.5, 1] : [0.18, 0.18, 0.25, 1]
|
|
93
|
+
px_rect(tb, bx, SHAPE_Y, SHAPE_BTN_W, SHAPE_BTN_H, bg)
|
|
94
|
+
|
|
95
|
+
ic = [0.8, 0.85, 0.9, 1]
|
|
96
|
+
cx = bx + SHAPE_BTN_W / 2
|
|
97
|
+
cy = SHAPE_Y + SHAPE_BTN_H / 2
|
|
98
|
+
case s
|
|
99
|
+
when :square
|
|
100
|
+
px_rect(tb, cx - 8, cy - 8, 16, 16, ic)
|
|
101
|
+
when :circle
|
|
102
|
+
tb.fill_circle(x: cx, y: cy, radius: 10, color: ic)
|
|
103
|
+
when :triangle
|
|
104
|
+
tb.fill_triangle(x1: cx, y1: cy - 10, x2: cx - 10, y2: cy + 9, x3: cx + 10, y3: cy + 9, color: ic)
|
|
105
|
+
end
|
|
106
|
+
end
|
|
107
|
+
end
|
|
108
|
+
|
|
109
|
+
# --- Size icons (row 2, after shapes) ---
|
|
110
|
+
SIZE_X0 = 148
|
|
111
|
+
SIZE_Y = 50
|
|
112
|
+
SIZE_BTN_W = 36
|
|
113
|
+
SIZE_BTN_H = 30
|
|
114
|
+
SIZE_GAP = 6
|
|
115
|
+
|
|
116
|
+
def draw_size_icons(tb, selected)
|
|
117
|
+
SIZES.each_with_index do |sz, i|
|
|
118
|
+
bx = SIZE_X0 + i * (SIZE_BTN_W + SIZE_GAP)
|
|
119
|
+
bg = i == selected ? [0.3, 0.3, 0.5, 1] : [0.18, 0.18, 0.25, 1]
|
|
120
|
+
px_rect(tb, bx, SIZE_Y, SIZE_BTN_W, SIZE_BTN_H, bg)
|
|
121
|
+
|
|
122
|
+
cx = bx + SIZE_BTN_W / 2
|
|
123
|
+
cy = SIZE_Y + SIZE_BTN_H / 2
|
|
124
|
+
r = [2 + sz / 5, 11].min
|
|
125
|
+
tb.fill_circle(x: cx, y: cy, radius: r, color: [0.8, 0.85, 0.9, 1])
|
|
126
|
+
end
|
|
127
|
+
end
|
|
128
|
+
|
|
129
|
+
# --- Eraser icon (row 2) ---
|
|
130
|
+
ERASER_X = 324
|
|
131
|
+
ERASER_Y = 50
|
|
132
|
+
ERASER_W = 40
|
|
133
|
+
ERASER_H = 30
|
|
134
|
+
|
|
135
|
+
def draw_eraser_icon(tb, active)
|
|
136
|
+
bg = active ? [0.2, 0.75, 0.3, 1] : [0.18, 0.18, 0.25, 1]
|
|
137
|
+
px_rect(tb, ERASER_X, ERASER_Y, ERASER_W, ERASER_H, bg)
|
|
138
|
+
|
|
139
|
+
ic = active ? [1.0, 1.0, 1.0, 1.0] : [0.5, 0.5, 0.6, 1]
|
|
140
|
+
# Pixel "E"
|
|
141
|
+
ex = ERASER_X + 12
|
|
142
|
+
ey = ERASER_Y + 5
|
|
143
|
+
px_rect(tb, ex, ey, 3, 20, ic) # vertical bar
|
|
144
|
+
px_rect(tb, ex, ey, 16, 3, ic) # top
|
|
145
|
+
px_rect(tb, ex, ey + 8, 12, 3, ic) # middle
|
|
146
|
+
px_rect(tb, ex, ey + 17, 16, 3, ic) # bottom
|
|
147
|
+
end
|
|
148
|
+
|
|
149
|
+
# --- Clear icon (row 2) ---
|
|
150
|
+
CLEAR_X = 372
|
|
151
|
+
CLEAR_Y = 50
|
|
152
|
+
CLEAR_W = 40
|
|
153
|
+
CLEAR_H = 30
|
|
154
|
+
|
|
155
|
+
def draw_clear_icon(tb)
|
|
156
|
+
bg = [0.55, 0.12, 0.12, 1]
|
|
157
|
+
px_rect(tb, CLEAR_X, CLEAR_Y, CLEAR_W, CLEAR_H, bg)
|
|
158
|
+
|
|
159
|
+
ic = [1, 0.8, 0.8, 1]
|
|
160
|
+
cx = CLEAR_X + CLEAR_W / 2
|
|
161
|
+
# Lid
|
|
162
|
+
px_rect(tb, cx - 10, CLEAR_Y + 4, 20, 3, ic)
|
|
163
|
+
px_rect(tb, cx - 4, CLEAR_Y + 2, 8, 2, ic)
|
|
164
|
+
# Body
|
|
165
|
+
px_rect(tb, cx - 7, CLEAR_Y + 7, 14, 18, ic)
|
|
166
|
+
# Stripes inside (dark)
|
|
167
|
+
stripe = [0.55, 0.12, 0.12, 1]
|
|
168
|
+
px_rect(tb, cx - 3, CLEAR_Y + 10, 2, 12, stripe)
|
|
169
|
+
px_rect(tb, cx + 1, CLEAR_Y + 10, 2, 12, stripe)
|
|
170
|
+
end
|
|
171
|
+
|
|
172
|
+
# --- Separator line ---
|
|
173
|
+
def draw_separators(tb)
|
|
174
|
+
px_rect(tb, 0, TOOLBAR_H - 3, WINDOW_W, 3, [0.3, 0.3, 0.4, 1])
|
|
175
|
+
end
|
|
176
|
+
|
|
177
|
+
# Redraw the whole toolbar
|
|
178
|
+
def redraw_toolbar(tb, color_idx, shape_idx, size_idx, eraser)
|
|
179
|
+
tb.clear
|
|
180
|
+
draw_separators(tb)
|
|
181
|
+
draw_color_swatches(tb, color_idx)
|
|
182
|
+
draw_shape_icons(tb, shape_idx)
|
|
183
|
+
draw_size_icons(tb, size_idx)
|
|
184
|
+
draw_eraser_icon(tb, eraser)
|
|
185
|
+
draw_clear_icon(tb)
|
|
186
|
+
end
|
|
187
|
+
|
|
188
|
+
redraw_toolbar(tb, current_color_idx, current_shape_idx, current_size_idx, eraser_on)
|
|
189
|
+
|
|
190
|
+
# === Toolbar hit areas ===
|
|
191
|
+
#
|
|
192
|
+
# Transparent overlays at z:11 sit above the toolbar canvas (z:10).
|
|
193
|
+
|
|
194
|
+
COLORS.each_with_index do |_c, i|
|
|
195
|
+
sx = SWATCH_X0 + i * (SWATCH_SZ + SWATCH_GAP)
|
|
196
|
+
Button.new(x: sx, y: SWATCH_Y, width: SWATCH_SZ, height: SWATCH_SZ, z: 11) do
|
|
197
|
+
current_color_idx = i
|
|
198
|
+
eraser_on = false
|
|
199
|
+
redraw_toolbar(tb, current_color_idx, current_shape_idx, current_size_idx, eraser_on)
|
|
200
|
+
end
|
|
201
|
+
end
|
|
202
|
+
|
|
203
|
+
SHAPES.each_index do |i|
|
|
204
|
+
bx = SHAPE_X0 + i * (SHAPE_BTN_W + SHAPE_GAP)
|
|
205
|
+
Button.new(x: bx, y: SHAPE_Y, width: SHAPE_BTN_W, height: SHAPE_BTN_H, z: 11) do
|
|
206
|
+
current_shape_idx = i
|
|
207
|
+
redraw_toolbar(tb, current_color_idx, current_shape_idx, current_size_idx, eraser_on)
|
|
208
|
+
end
|
|
209
|
+
end
|
|
210
|
+
|
|
211
|
+
SIZES.each_index do |i|
|
|
212
|
+
bx = SIZE_X0 + i * (SIZE_BTN_W + SIZE_GAP)
|
|
213
|
+
Button.new(x: bx, y: SIZE_Y, width: SIZE_BTN_W, height: SIZE_BTN_H, z: 11) do
|
|
214
|
+
current_size_idx = i
|
|
215
|
+
redraw_toolbar(tb, current_color_idx, current_shape_idx, current_size_idx, eraser_on)
|
|
216
|
+
end
|
|
217
|
+
end
|
|
218
|
+
|
|
219
|
+
Button.new(x: ERASER_X, y: ERASER_Y, width: ERASER_W, height: ERASER_H, z: 11) do
|
|
220
|
+
eraser_on = !eraser_on
|
|
221
|
+
redraw_toolbar(tb, current_color_idx, current_shape_idx, current_size_idx, eraser_on)
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
CANVAS_FILL = [0.95, 0.93, 0.88, 1]
|
|
225
|
+
|
|
226
|
+
Button.new(x: CLEAR_X, y: CLEAR_Y, width: CLEAR_W, height: CLEAR_H, z: 11) do
|
|
227
|
+
canvas.clear(CANVAS_FILL)
|
|
228
|
+
end
|
|
229
|
+
|
|
230
|
+
# === Drawing helpers ===
|
|
231
|
+
|
|
232
|
+
def stamp(canvas, shape, x, y, size, color)
|
|
233
|
+
half = size / 2.0
|
|
234
|
+
case shape
|
|
235
|
+
when :square
|
|
236
|
+
canvas.fill_square(x: x - half, y: y - half, size: size, color: color)
|
|
237
|
+
when :circle
|
|
238
|
+
canvas.fill_circle(x: x, y: y, radius: half, color: color)
|
|
239
|
+
when :triangle
|
|
240
|
+
canvas.fill_triangle(
|
|
241
|
+
x1: x, y1: y - half,
|
|
242
|
+
x2: x - half, y2: y + half,
|
|
243
|
+
x3: x + half, y3: y + half,
|
|
244
|
+
color: color
|
|
245
|
+
)
|
|
246
|
+
end
|
|
247
|
+
end
|
|
248
|
+
|
|
249
|
+
def erase(canvas, x, y, size)
|
|
250
|
+
half = size / 2.0
|
|
251
|
+
canvas.clear(CANVAS_FILL, x: (x - half).to_i, y: (y - half).to_i,
|
|
252
|
+
width: size.to_i, height: size.to_i)
|
|
253
|
+
end
|
|
254
|
+
|
|
255
|
+
# Yield evenly-spaced points along the segment (x0,y0)→(x1,y1), skipping the
|
|
256
|
+
# start. Mouse-move deltas can be chunky, so each move stamps the whole
|
|
257
|
+
# segment rather than just the endpoint.
|
|
258
|
+
def stroke(x0, y0, x1, y1, size)
|
|
259
|
+
dx = x1 - x0
|
|
260
|
+
dy = y1 - y0
|
|
261
|
+
step = [size / 4.0, 1.0].max
|
|
262
|
+
steps = [(Math.sqrt(dx * dx + dy * dy) / step).ceil, 1].max
|
|
263
|
+
steps.times do |i|
|
|
264
|
+
t = (i + 1).to_f / steps
|
|
265
|
+
yield(x0 + dx * t, y0 + dy * t)
|
|
266
|
+
end
|
|
267
|
+
end
|
|
268
|
+
|
|
269
|
+
# === Events ===
|
|
270
|
+
|
|
271
|
+
last_x = nil
|
|
272
|
+
last_y = nil
|
|
273
|
+
|
|
274
|
+
on :mouse_down do |event|
|
|
275
|
+
next unless event.button?(:left) && event.y >= CANVAS_Y
|
|
276
|
+
|
|
277
|
+
drawing = true
|
|
278
|
+
cx = event.x
|
|
279
|
+
cy = event.y - CANVAS_Y
|
|
280
|
+
sz = SIZES[current_size_idx]
|
|
281
|
+
if eraser_on
|
|
282
|
+
erase(canvas, cx, cy, sz)
|
|
283
|
+
else
|
|
284
|
+
stamp(canvas, SHAPES[current_shape_idx], cx, cy, sz, COLORS[current_color_idx])
|
|
285
|
+
end
|
|
286
|
+
last_x = cx
|
|
287
|
+
last_y = cy
|
|
288
|
+
end
|
|
289
|
+
|
|
290
|
+
on :mouse_up do
|
|
291
|
+
drawing = false
|
|
292
|
+
last_x = nil
|
|
293
|
+
last_y = nil
|
|
294
|
+
end
|
|
295
|
+
|
|
296
|
+
on :mouse_move do |event|
|
|
297
|
+
next unless drawing && event.y >= CANVAS_Y
|
|
298
|
+
|
|
299
|
+
cx = event.x
|
|
300
|
+
cy = event.y - CANVAS_Y
|
|
301
|
+
sz = SIZES[current_size_idx]
|
|
302
|
+
stroke(last_x, last_y, cx, cy, sz) do |x, y|
|
|
303
|
+
if eraser_on
|
|
304
|
+
erase(canvas, x, y, sz)
|
|
305
|
+
else
|
|
306
|
+
stamp(canvas, SHAPES[current_shape_idx], x, y, sz, COLORS[current_color_idx])
|
|
307
|
+
end
|
|
308
|
+
end
|
|
309
|
+
last_x = cx
|
|
310
|
+
last_y = cy
|
|
311
|
+
end
|
|
312
|
+
|
|
313
|
+
show
|