ruby2d 0.12.1 → 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 -443
- data/assets/app.icns +0 -0
- data/assets/include/GL/glew.h +0 -26427
- 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
|
@@ -0,0 +1,613 @@
|
|
|
1
|
+
# Hill driver
|
|
2
|
+
# Drive across rolling hills, catch air off the crests, and grab fuel cans
|
|
3
|
+
# before you run dry.
|
|
4
|
+
#
|
|
5
|
+
# Right/RT accelerates, left/LT brakes or reverses, hold accelerate with space
|
|
6
|
+
# (or X) to turbo-boost, and up/down or left stick tilts the car while
|
|
7
|
+
# airborne. Press `r` (or Start) to restart.
|
|
8
|
+
|
|
9
|
+
require 'ruby2d'
|
|
10
|
+
|
|
11
|
+
# === Tunables ===
|
|
12
|
+
|
|
13
|
+
WIDTH = 900 # window width in pixels
|
|
14
|
+
HEIGHT = 540 # window height in pixels
|
|
15
|
+
WORLD_W = 12600 # total world width in pixels
|
|
16
|
+
FINISH_X = WORLD_W - 360 # finish flag x, set inside the world edge so the
|
|
17
|
+
# camera can scroll past it and frame the whole flag
|
|
18
|
+
GROUND_BASE = 380 # mean ground y in world space (px)
|
|
19
|
+
HILL_AMP1 = 92 # primary hill amplitude (px)
|
|
20
|
+
HILL_FREQ1 = 0.0042 # primary hill frequency (rad/px)
|
|
21
|
+
HILL_AMP2 = 34 # secondary hill amplitude (px)
|
|
22
|
+
HILL_FREQ2 = 0.0119 # secondary hill frequency (rad/px)
|
|
23
|
+
HILL_PHASE2 = 1.7 # secondary hill phase offset (rad)
|
|
24
|
+
GRAVITY = 1900 # downward acceleration (px/sec²)
|
|
25
|
+
ENGINE = 860 # forward thrust along slope (px/sec²)
|
|
26
|
+
TURBO_ENGINE = 1500 # extra forward thrust while turbo-boosting (px/sec²)
|
|
27
|
+
BRAKE = 1300 # opposing force when pressing left (px/sec²)
|
|
28
|
+
REVERSE_MAX = 240 # cap on reverse speed (px/sec)
|
|
29
|
+
ROLL_FRICTION = 0.42 # rolling drag rate while grounded (per-sec)
|
|
30
|
+
AIR_DRAG = 0.08 # horizontal drag while airborne (per-sec)
|
|
31
|
+
TILT_TORQUE = 7.5 # angular accel from tilt input (rad/sec²)
|
|
32
|
+
TILT_DAMP = 1.4 # angular velocity damping in air (per-sec)
|
|
33
|
+
GROUND_ALIGN = 16.0 # angle ease rate toward slope when grounded (per-sec)
|
|
34
|
+
WHEEL_RADIUS = 13 # wheel radius (px)
|
|
35
|
+
CHASSIS_W = 60 # chassis width (px)
|
|
36
|
+
CHASSIS_H = 18 # chassis height (px)
|
|
37
|
+
WHEEL_DX = 21 # half-distance between wheels (px)
|
|
38
|
+
WHEEL_DY = 10 # wheel y offset below chassis center (px)
|
|
39
|
+
CAMERA_SMOOTHING = 5.5 # camera lerp toward car (per-sec)
|
|
40
|
+
START_FUEL = 12.0 # starting fuel (seconds of throttle)
|
|
41
|
+
MAX_FUEL = 20.0 # fuel tank cap (sec)
|
|
42
|
+
CAN_FUEL = 4.0 # fuel granted per can (sec)
|
|
43
|
+
CAN_SPACING = 560 # world-space gap between fuel cans (px)
|
|
44
|
+
ENGINE_FUEL = 1.5 # fuel burn rate while accelerating (per-sec)
|
|
45
|
+
TURBO_FUEL = 3.5 # fuel burn rate while turbo-boosting (per-sec)
|
|
46
|
+
TERRAIN_STEP = 14 # column spacing when rendering hills (px)
|
|
47
|
+
GRASS_THICK = 34 # depth of the green grass band above the soil (px)
|
|
48
|
+
CAN_HOVER = 22 # height a fuel can floats above the ground (px)
|
|
49
|
+
SPARK_LIFE = 0.55 # fuel-can pickup spark lifetime (sec)
|
|
50
|
+
EMBER_LIFE = 0.22 # turbo exhaust ember lifetime (sec)
|
|
51
|
+
FUEL_FLASH = 0.35 # fuel-bar flash duration on pickup (sec)
|
|
52
|
+
PX_PER_M = 12 # world px shown as one meter in the HUD
|
|
53
|
+
|
|
54
|
+
# Daytime sky, sun, and clouds. The sky, sun, and clouds are static backdrop
|
|
55
|
+
# objects living behind the HUD; the world scrolls past in the render block.
|
|
56
|
+
SKY_TOP = '#4a9fe0' # sky color at the top of the window
|
|
57
|
+
SKY_HORIZON = '#cfeafc' # sky color near the horizon
|
|
58
|
+
SUN_X = WIDTH - 130 # sun center x (screen space)
|
|
59
|
+
SUN_Y = 96 # sun center y (screen space)
|
|
60
|
+
CLOUDS = [ # [x, y (screen), scale]
|
|
61
|
+
[130, 78, 1.0], [360, 132, 0.7], [560, 62, 1.2],
|
|
62
|
+
[740, 112, 0.9], [850, 156, 0.6]
|
|
63
|
+
].freeze
|
|
64
|
+
|
|
65
|
+
GROUND_OFFSET = WHEEL_RADIUS + WHEEL_DY # distance from chassis center down to wheel bottom
|
|
66
|
+
|
|
67
|
+
# === Window ===
|
|
68
|
+
|
|
69
|
+
set title: 'Ruby 2D ▸ Examples ▸ Hill driver',
|
|
70
|
+
width: WIDTH, height: HEIGHT, background: SKY_HORIZON
|
|
71
|
+
set close_on_esc: true
|
|
72
|
+
|
|
73
|
+
# === Helpers ===
|
|
74
|
+
|
|
75
|
+
# Smooth procedural terrain as a sum of two sines. `terrain_y` returns the
|
|
76
|
+
# ground y in world space; `terrain_slope` is its analytic derivative dy/dx.
|
|
77
|
+
|
|
78
|
+
def terrain_y(x)
|
|
79
|
+
GROUND_BASE +
|
|
80
|
+
HILL_AMP1 * Math.sin(x * HILL_FREQ1) +
|
|
81
|
+
HILL_AMP2 * Math.sin(x * HILL_FREQ2 + HILL_PHASE2)
|
|
82
|
+
end
|
|
83
|
+
|
|
84
|
+
def terrain_slope(x)
|
|
85
|
+
HILL_AMP1 * HILL_FREQ1 * Math.cos(x * HILL_FREQ1) +
|
|
86
|
+
HILL_AMP2 * HILL_FREQ2 * Math.cos(x * HILL_FREQ2 + HILL_PHASE2)
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# A soft cloud: four overlapping white puffs, added to the scene graph at low
|
|
90
|
+
# z so the HUD stays on top of it.
|
|
91
|
+
|
|
92
|
+
def build_cloud(cx, cy, s)
|
|
93
|
+
white = [1.0, 1.0, 1.0, 0.92]
|
|
94
|
+
Circle.new(x: cx, y: cy, radius: 26 * s, color: white, z: 1)
|
|
95
|
+
Circle.new(x: cx - 30 * s, y: cy + 8 * s, radius: 20 * s, color: white, z: 1)
|
|
96
|
+
Circle.new(x: cx + 32 * s, y: cy + 6 * s, radius: 22 * s, color: white, z: 1)
|
|
97
|
+
Circle.new(x: cx + 4 * s, y: cy + 14 * s, radius: 24 * s, color: white, z: 1)
|
|
98
|
+
end
|
|
99
|
+
|
|
100
|
+
# A little amber jerry can — body, top handle, spout, and a highlight — sitting
|
|
101
|
+
# above a soft ground shadow. `sx`/`sy` are its screen position; the can floats
|
|
102
|
+
# CAN_HOVER above the ground, so the shadow drops to `sy + CAN_HOVER`. `gslope`
|
|
103
|
+
# is the ground slope under the can, used to rotate the shadow onto the hill.
|
|
104
|
+
|
|
105
|
+
def draw_can(sx, sy, gslope)
|
|
106
|
+
gy = sy + CAN_HOVER # ground surface just below the can
|
|
107
|
+
Ellipse.render(x: sx, y: gy, xradius: 9, yradius: 3,
|
|
108
|
+
rotate: Math.atan(gslope) * 180.0 / Math::PI,
|
|
109
|
+
color: [0.0, 0.0, 0.0, 0.14])
|
|
110
|
+
Rectangle.render(x: sx - 8, y: sy - 20, width: 16, height: 22, color: '#f2b01e')
|
|
111
|
+
Rectangle.render(x: sx - 4, y: sy - 16, width: 9, height: 14, color: '#ffd257')
|
|
112
|
+
Rectangle.render(x: sx - 7, y: sy - 24, width: 14, height: 4, color: '#a16207')
|
|
113
|
+
Rectangle.render(x: sx + 3, y: sy - 27, width: 4, height: 4, color: '#a16207')
|
|
114
|
+
Line.render(x1: sx - 2, y1: sy - 3, x2: sx + 2, y2: sy - 14,
|
|
115
|
+
stroke_width: 2, color: [1.0, 1.0, 1.0, 0.5])
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
# === Level ===
|
|
119
|
+
|
|
120
|
+
can_data = []
|
|
121
|
+
can_x = 360
|
|
122
|
+
while can_x <= FINISH_X - 260
|
|
123
|
+
can_data << [can_x, terrain_y(can_x) - CAN_HOVER]
|
|
124
|
+
can_x += CAN_SPACING
|
|
125
|
+
end
|
|
126
|
+
|
|
127
|
+
# === Backdrop ===
|
|
128
|
+
#
|
|
129
|
+
# Static sky, sun, and clouds at z:0-1. The scrolling world renders at z:10 and
|
|
130
|
+
# the HUD at z:19-21, so the three layers stack backdrop → world → HUD.
|
|
131
|
+
|
|
132
|
+
Quad.new(x1: 0, y1: 0, x2: WIDTH, y2: 0, x3: WIDTH, y3: HEIGHT, x4: 0, y4: HEIGHT,
|
|
133
|
+
color: [SKY_TOP, SKY_TOP, SKY_HORIZON, SKY_HORIZON], z: 0)
|
|
134
|
+
|
|
135
|
+
Circle.new(x: SUN_X, y: SUN_Y, radius: 62, color: [1.0, 0.95, 0.7, 0.18], z: 0)
|
|
136
|
+
Circle.new(x: SUN_X, y: SUN_Y, radius: 42, color: [1.0, 0.96, 0.75, 0.28], z: 0)
|
|
137
|
+
Circle.new(x: SUN_X, y: SUN_Y, radius: 30, color: '#fff2b0', z: 0)
|
|
138
|
+
|
|
139
|
+
CLOUDS.each { |cx, cy, s| build_cloud(cx, cy, s) }
|
|
140
|
+
|
|
141
|
+
# === HUD ===
|
|
142
|
+
|
|
143
|
+
fuel_label = Text.new('', x: 16, y: 12, size: 16, color: '#1e293b', z: 20)
|
|
144
|
+
score_label = Text.new('', x: 16, y: 34, size: 16, color: '#1e293b', z: 20)
|
|
145
|
+
Rectangle.new(x: 16, y: 60, width: 220, height: 8, color: '#1e293b', z: 19)
|
|
146
|
+
fuel_bar = Rectangle.new(x: 16, y: 60, width: 0, height: 8, color: '#fbbf24', z: 20)
|
|
147
|
+
dist_label = Text.new('', x: WIDTH - 128, y: 12, size: 16, color: '#1e293b', z: 20)
|
|
148
|
+
|
|
149
|
+
# End-of-run banner — hidden until the run finishes. `x: :center` re-resolves
|
|
150
|
+
# against the live viewport, and the dark panel keeps the text readable over
|
|
151
|
+
# the bright daytime scene.
|
|
152
|
+
banner_panel = Rectangle.new(x: 0, y: HEIGHT / 2 - 68, width: WIDTH, height: 136,
|
|
153
|
+
color: [0.05, 0.07, 0.11, 0.55], z: 20, visible: false)
|
|
154
|
+
banner_title = Text.new('', x: :center, y: HEIGHT / 2 - 52, size: 40,
|
|
155
|
+
color: '#fde047', z: 21, visible: false)
|
|
156
|
+
banner_subtitle = Text.new('Press R to restart', x: :center, y: HEIGHT / 2 + 8,
|
|
157
|
+
size: 20, color: '#f8fafc', z: 21, visible: false)
|
|
158
|
+
|
|
159
|
+
# === Mutable state ===
|
|
160
|
+
|
|
161
|
+
world_x = 80.0
|
|
162
|
+
world_y = 0.0
|
|
163
|
+
vx = 0.0
|
|
164
|
+
vy = 0.0
|
|
165
|
+
angle = 0.0
|
|
166
|
+
ang_vel = 0.0
|
|
167
|
+
wheel_spin = 0.0
|
|
168
|
+
on_ground = true
|
|
169
|
+
gas = false
|
|
170
|
+
brake = false
|
|
171
|
+
turbo = false
|
|
172
|
+
tilt = 0
|
|
173
|
+
# Effective inputs, recombined each frame from the keyboard latches above and
|
|
174
|
+
# the live gamepad (see the top of `update`). Declared here so both `update`
|
|
175
|
+
# and `render` close over the same variables.
|
|
176
|
+
accel = false
|
|
177
|
+
braking = false
|
|
178
|
+
boosting = false
|
|
179
|
+
tilt_dir = 0
|
|
180
|
+
camera_x = 0.0
|
|
181
|
+
camera_y = 0.0
|
|
182
|
+
fuel = START_FUEL
|
|
183
|
+
score = 0
|
|
184
|
+
sparks = []
|
|
185
|
+
embers = []
|
|
186
|
+
fuel_flash = 0.0
|
|
187
|
+
can_collected = Array.new(can_data.length, false)
|
|
188
|
+
finished = false
|
|
189
|
+
|
|
190
|
+
reset = lambda do
|
|
191
|
+
world_x = 80.0
|
|
192
|
+
world_y = terrain_y(80.0) - GROUND_OFFSET
|
|
193
|
+
vx = 0.0; vy = 0.0
|
|
194
|
+
angle = Math.atan(terrain_slope(80.0))
|
|
195
|
+
ang_vel = 0.0
|
|
196
|
+
wheel_spin = 0.0
|
|
197
|
+
on_ground = true
|
|
198
|
+
gas = false; brake = false; turbo = false; tilt = 0
|
|
199
|
+
fuel = START_FUEL
|
|
200
|
+
score = 0
|
|
201
|
+
sparks.clear
|
|
202
|
+
embers.clear
|
|
203
|
+
fuel_flash = 0.0
|
|
204
|
+
can_collected.fill(false)
|
|
205
|
+
finished = false
|
|
206
|
+
banner_panel.hide
|
|
207
|
+
banner_title.hide
|
|
208
|
+
banner_subtitle.hide
|
|
209
|
+
dist_label.show
|
|
210
|
+
end
|
|
211
|
+
reset.call
|
|
212
|
+
|
|
213
|
+
# End the run and raise the banner. Closes over the locals above, so assigning
|
|
214
|
+
# `finished` here flips the same flag the update loop reads.
|
|
215
|
+
finish_with = lambda do |message|
|
|
216
|
+
finished = true
|
|
217
|
+
banner_title.content = message
|
|
218
|
+
banner_panel.show
|
|
219
|
+
banner_title.show
|
|
220
|
+
banner_subtitle.show
|
|
221
|
+
dist_label.hide
|
|
222
|
+
end
|
|
223
|
+
|
|
224
|
+
# === Input ===
|
|
225
|
+
|
|
226
|
+
on :key_down do |event|
|
|
227
|
+
case event.key
|
|
228
|
+
when 'right' then gas = true
|
|
229
|
+
when 'left' then brake = true
|
|
230
|
+
when 'up' then tilt = -1
|
|
231
|
+
when 'down' then tilt = 1
|
|
232
|
+
when 'space' then turbo = true
|
|
233
|
+
when 'r' then reset.call
|
|
234
|
+
end
|
|
235
|
+
end
|
|
236
|
+
|
|
237
|
+
on :key_up do |event|
|
|
238
|
+
case event.key
|
|
239
|
+
when 'right' then gas = false
|
|
240
|
+
when 'left' then brake = false
|
|
241
|
+
when 'up', 'down' then tilt = 0
|
|
242
|
+
when 'space' then turbo = false
|
|
243
|
+
end
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
on gamepad_button_down: :start do
|
|
247
|
+
reset.call
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
# === Per-frame update ===
|
|
251
|
+
#
|
|
252
|
+
# Velocity is in world space (px/sec). When grounded, engine, turbo, and brake
|
|
253
|
+
# push along the surface tangent so thrust climbs hills naturally; gravity is
|
|
254
|
+
# left to act in world space and is handled by the ground-clamp step below.
|
|
255
|
+
# When airborne the car free-flies and the up/down keys spin it via `ang_vel`.
|
|
256
|
+
|
|
257
|
+
update do |dt|
|
|
258
|
+
# Combine the keyboard latches (set by key events) with the live gamepad
|
|
259
|
+
# state each frame, so releasing a gamepad control actually stops the action.
|
|
260
|
+
accel = gas
|
|
261
|
+
braking = brake
|
|
262
|
+
boosting = turbo
|
|
263
|
+
tilt_dir = tilt
|
|
264
|
+
gamepads.each do |pad|
|
|
265
|
+
accel ||= pad.axis(:right_trigger) > 0.1 || pad.held?(:south) || pad.held?(:dpad_right)
|
|
266
|
+
braking ||= pad.axis(:left_trigger) > 0.1 || pad.held?(:dpad_left)
|
|
267
|
+
boosting ||= pad.held?(:west)
|
|
268
|
+
if tilt_dir.zero?
|
|
269
|
+
ly = pad.axis(:left_y)
|
|
270
|
+
tilt_dir = -1 if ly < -0.3 || pad.held?(:dpad_up)
|
|
271
|
+
tilt_dir = 1 if ly > 0.3 || pad.held?(:dpad_down)
|
|
272
|
+
end
|
|
273
|
+
end
|
|
274
|
+
|
|
275
|
+
vy += GRAVITY * dt
|
|
276
|
+
|
|
277
|
+
if on_ground
|
|
278
|
+
slope = terrain_slope(world_x)
|
|
279
|
+
inv_len = 1.0 / Math.sqrt(1 + slope * slope)
|
|
280
|
+
tx = inv_len
|
|
281
|
+
ty = slope * inv_len
|
|
282
|
+
|
|
283
|
+
if accel && fuel.positive?
|
|
284
|
+
vx += ENGINE * tx * dt
|
|
285
|
+
vy += ENGINE * ty * dt
|
|
286
|
+
fuel -= ENGINE_FUEL * dt
|
|
287
|
+
end
|
|
288
|
+
|
|
289
|
+
# Turbo: a hard forward shove along the slope, but only while accelerating
|
|
290
|
+
# and grounded — the wheels need traction. Held on its own it's like
|
|
291
|
+
# neutral: it still burns fuel and flares the exhaust (handled after the
|
|
292
|
+
# branch), just without driving the car.
|
|
293
|
+
if boosting && accel && fuel.positive?
|
|
294
|
+
vx += TURBO_ENGINE * tx * dt
|
|
295
|
+
vy += TURBO_ENGINE * ty * dt
|
|
296
|
+
end
|
|
297
|
+
|
|
298
|
+
if braking
|
|
299
|
+
forward = vx * tx + vy * ty
|
|
300
|
+
if forward > -REVERSE_MAX
|
|
301
|
+
vx -= BRAKE * tx * dt
|
|
302
|
+
vy -= BRAKE * ty * dt
|
|
303
|
+
end
|
|
304
|
+
end
|
|
305
|
+
|
|
306
|
+
# Collapse velocity onto the tangent every frame so the gravity we just
|
|
307
|
+
# added acts as the standard "along-slope" component, and the normal
|
|
308
|
+
# component (which would otherwise drive the car through the ground) is
|
|
309
|
+
# cancelled by the ground-clamp below.
|
|
310
|
+
v_t = vx * tx + vy * ty
|
|
311
|
+
vx = v_t * tx
|
|
312
|
+
vy = v_t * ty
|
|
313
|
+
|
|
314
|
+
drag = Math.exp(-ROLL_FRICTION * dt)
|
|
315
|
+
vx *= drag; vy *= drag
|
|
316
|
+
|
|
317
|
+
target = Math.atan(slope)
|
|
318
|
+
a = 1 - Math.exp(-GROUND_ALIGN * dt)
|
|
319
|
+
angle += (target - angle) * a
|
|
320
|
+
ang_vel = 0.0
|
|
321
|
+
else
|
|
322
|
+
vx *= Math.exp(-AIR_DRAG * dt)
|
|
323
|
+
ang_vel += TILT_TORQUE * tilt_dir * dt
|
|
324
|
+
ang_vel *= Math.exp(-TILT_DAMP * dt)
|
|
325
|
+
angle += ang_vel * dt
|
|
326
|
+
end
|
|
327
|
+
|
|
328
|
+
# Turbo burns fuel fast and throws embers out the tailpipe, grounded or not.
|
|
329
|
+
if boosting && fuel.positive?
|
|
330
|
+
fuel -= TURBO_FUEL * dt
|
|
331
|
+
pipe = -(CHASSIS_W / 2.0 + 4)
|
|
332
|
+
exx = world_x + pipe * Math.cos(angle)
|
|
333
|
+
exy = world_y + pipe * Math.sin(angle)
|
|
334
|
+
3.times do
|
|
335
|
+
dir = angle + Math::PI + (rand - 0.5) * 0.3
|
|
336
|
+
spd = 250 + rand * 150
|
|
337
|
+
embers << [exx, exy, Math.cos(dir) * spd, Math.sin(dir) * spd, EMBER_LIFE * (0.6 + rand * 0.4)]
|
|
338
|
+
end
|
|
339
|
+
end
|
|
340
|
+
|
|
341
|
+
world_x += vx * dt
|
|
342
|
+
world_y += vy * dt
|
|
343
|
+
|
|
344
|
+
# Wheel-spin visual: arc length along chassis-forward direction over radius.
|
|
345
|
+
forward_speed = vx * Math.cos(angle) + vy * Math.sin(angle)
|
|
346
|
+
wheel_spin += forward_speed / WHEEL_RADIUS * dt
|
|
347
|
+
|
|
348
|
+
# Ground-clamp: if the chassis center is below the local ground line, snap
|
|
349
|
+
# to the surface and project velocity onto the tangent (kill normal motion).
|
|
350
|
+
ground_y = terrain_y(world_x) - GROUND_OFFSET
|
|
351
|
+
if world_y >= ground_y
|
|
352
|
+
if !on_ground
|
|
353
|
+
slope = terrain_slope(world_x)
|
|
354
|
+
inv_len = 1.0 / Math.sqrt(1 + slope * slope)
|
|
355
|
+
tx = inv_len; ty = slope * inv_len
|
|
356
|
+
v_t = vx * tx + vy * ty
|
|
357
|
+
vx = v_t * tx
|
|
358
|
+
vy = v_t * ty
|
|
359
|
+
ang_vel = 0.0
|
|
360
|
+
end
|
|
361
|
+
on_ground = true
|
|
362
|
+
world_y = ground_y
|
|
363
|
+
else
|
|
364
|
+
on_ground = false
|
|
365
|
+
end
|
|
366
|
+
|
|
367
|
+
# World edges keep the car in the level; crossing the finish line raises the
|
|
368
|
+
# banner once but leaves the car free to keep driving around.
|
|
369
|
+
if world_x < 40
|
|
370
|
+
world_x = 40
|
|
371
|
+
vx = 0 if vx < 0
|
|
372
|
+
elsif world_x > WORLD_W - 40
|
|
373
|
+
world_x = WORLD_W - 40
|
|
374
|
+
vx = 0 if vx > 0
|
|
375
|
+
end
|
|
376
|
+
finish_with.call('You reached the end!') if !finished && world_x >= FINISH_X
|
|
377
|
+
|
|
378
|
+
# Camera leads slightly in the direction of travel; the tall lower bound
|
|
379
|
+
# leaves headroom to follow the car through a big jump.
|
|
380
|
+
target_cx = (world_x - WIDTH * 0.4 + vx * 0.25).clamp(0, WORLD_W - WIDTH)
|
|
381
|
+
target_cy = (world_y - HEIGHT * 0.65).clamp(GROUND_BASE - HEIGHT * 1.15, GROUND_BASE - HEIGHT * 0.4)
|
|
382
|
+
smooth = 1 - Math.exp(-CAMERA_SMOOTHING * dt)
|
|
383
|
+
camera_x += (target_cx - camera_x) * smooth
|
|
384
|
+
camera_y += (target_cy - camera_y) * smooth
|
|
385
|
+
|
|
386
|
+
# Can pickups (cheap AABB-ish radius check around the chassis). Each grab
|
|
387
|
+
# tops up fuel, flashes the bar, and throws a little burst of sparks.
|
|
388
|
+
can_data.each_with_index do |(cx, cy), i|
|
|
389
|
+
next if can_collected[i]
|
|
390
|
+
if (cx - world_x).abs < 22 && (cy - world_y).abs < 28
|
|
391
|
+
can_collected[i] = true
|
|
392
|
+
score += 1
|
|
393
|
+
fuel = [fuel + CAN_FUEL, MAX_FUEL].min
|
|
394
|
+
fuel_flash = FUEL_FLASH
|
|
395
|
+
10.times do
|
|
396
|
+
a = rand * Math::PI * 2
|
|
397
|
+
spd = 70 + rand * 150
|
|
398
|
+
sparks << [cx, cy, Math.cos(a) * spd, Math.sin(a) * spd - 50, SPARK_LIFE]
|
|
399
|
+
end
|
|
400
|
+
end
|
|
401
|
+
end
|
|
402
|
+
|
|
403
|
+
# Advance and expire pickup sparks; a little gravity pulls them back down.
|
|
404
|
+
sparks.each do |s|
|
|
405
|
+
s[4] -= dt
|
|
406
|
+
s[0] += s[2] * dt
|
|
407
|
+
s[1] += s[3] * dt
|
|
408
|
+
s[3] += 320 * dt
|
|
409
|
+
end
|
|
410
|
+
sparks.reject! { |s| s[4] <= 0 }
|
|
411
|
+
|
|
412
|
+
# Advance turbo exhaust embers — heavy drag on both axes so they shoot
|
|
413
|
+
# straight out of the pipe and snuff quickly instead of trailing away.
|
|
414
|
+
embers.each do |e|
|
|
415
|
+
e[4] -= dt
|
|
416
|
+
e[0] += e[2] * dt
|
|
417
|
+
e[1] += e[3] * dt
|
|
418
|
+
e[2] *= Math.exp(-7.0 * dt)
|
|
419
|
+
e[3] *= Math.exp(-7.0 * dt)
|
|
420
|
+
end
|
|
421
|
+
embers.reject! { |e| e[4] <= 0 }
|
|
422
|
+
|
|
423
|
+
# Fade the fuel bar from a white flash back to its amber (#fbbf24).
|
|
424
|
+
if fuel_flash > 0
|
|
425
|
+
fuel_flash -= dt
|
|
426
|
+
t = (fuel_flash / FUEL_FLASH).clamp(0.0, 1.0)
|
|
427
|
+
fuel_bar.color.r = 0.984 + (1 - 0.984) * t
|
|
428
|
+
fuel_bar.color.g = 0.749 + (1 - 0.749) * t
|
|
429
|
+
fuel_bar.color.b = 0.141 + (1 - 0.141) * t
|
|
430
|
+
end
|
|
431
|
+
|
|
432
|
+
if fuel <= 0
|
|
433
|
+
fuel = 0
|
|
434
|
+
if !finished && on_ground && vx.abs < 6 && vy.abs < 6
|
|
435
|
+
finish_with.call('Out of fuel!')
|
|
436
|
+
end
|
|
437
|
+
end
|
|
438
|
+
|
|
439
|
+
fuel_text = "Fuel: #{format('%.1f', fuel)}s"
|
|
440
|
+
fuel_label.content = fuel_text unless fuel_label.content == fuel_text
|
|
441
|
+
score_text = "Cans: #{score} / #{can_data.length}"
|
|
442
|
+
score_label.content = score_text unless score_label.content == score_text
|
|
443
|
+
fuel_bar.width = (220 * fuel / MAX_FUEL).clamp(0, 220)
|
|
444
|
+
|
|
445
|
+
# Distance to the flag, right-aligned so the number can grow without shifting.
|
|
446
|
+
dist_m = [((FINISH_X - world_x) / PX_PER_M).round, 0].max
|
|
447
|
+
dist_text = "#{dist_m}m to go"
|
|
448
|
+
if dist_label.content != dist_text
|
|
449
|
+
dist_label.content = dist_text
|
|
450
|
+
dist_label.x = WIDTH - dist_label.width - 16
|
|
451
|
+
end
|
|
452
|
+
end
|
|
453
|
+
|
|
454
|
+
# === Render ===
|
|
455
|
+
|
|
456
|
+
render z: 10 do
|
|
457
|
+
# Farthest hazy mountains — very slow parallax, tinted toward the sky.
|
|
458
|
+
mtn_step = 80
|
|
459
|
+
sx = -mtn_step
|
|
460
|
+
while sx <= WIDTH + mtn_step
|
|
461
|
+
wx = sx + camera_x * 0.2
|
|
462
|
+
m1 = 48 * Math.sin(wx * 0.0016) + 24 * Math.sin(wx * 0.0037 + 2.1)
|
|
463
|
+
m2 = 48 * Math.sin((wx + mtn_step) * 0.0016) + 24 * Math.sin((wx + mtn_step) * 0.0037 + 2.1)
|
|
464
|
+
y1 = GROUND_BASE - 120 + m1 - camera_y * 0.25
|
|
465
|
+
y2 = GROUND_BASE - 120 + m2 - camera_y * 0.25
|
|
466
|
+
Quad.render(x1: sx, y1: y1, x2: sx + mtn_step, y2: y2,
|
|
467
|
+
x3: sx + mtn_step, y3: HEIGHT, x4: sx, y4: HEIGHT,
|
|
468
|
+
color: '#aec7d1')
|
|
469
|
+
sx += mtn_step
|
|
470
|
+
end
|
|
471
|
+
|
|
472
|
+
# Nearer parallax hills, hazed toward the sky for depth.
|
|
473
|
+
far_step = 60
|
|
474
|
+
sx = -far_step
|
|
475
|
+
while sx <= WIDTH + far_step
|
|
476
|
+
wx = sx + camera_x * 0.4
|
|
477
|
+
h1 = HILL_AMP1 * 1.4 * Math.sin(wx * HILL_FREQ1 * 0.55) + 40
|
|
478
|
+
y1 = GROUND_BASE - 80 + h1 - camera_y * 0.45
|
|
479
|
+
h2 = HILL_AMP1 * 1.4 * Math.sin((wx + far_step) * HILL_FREQ1 * 0.55) + 40
|
|
480
|
+
y2 = GROUND_BASE - 80 + h2 - camera_y * 0.45
|
|
481
|
+
Quad.render(x1: sx, y1: y1, x2: sx + far_step, y2: y2,
|
|
482
|
+
x3: sx + far_step, y3: HEIGHT, x4: sx, y4: HEIGHT,
|
|
483
|
+
color: '#8fb996')
|
|
484
|
+
sx += far_step
|
|
485
|
+
end
|
|
486
|
+
|
|
487
|
+
# Main terrain — a strip of trapezoids from the surface to the bottom of the
|
|
488
|
+
# window: a green grass band along the top, then soil shading from topsoil to
|
|
489
|
+
# a darker subsoil below. Sample one step beyond the viewport on each side so
|
|
490
|
+
# edges don't clip as the camera moves between frames.
|
|
491
|
+
start_x = ((camera_x / TERRAIN_STEP).floor - 1) * TERRAIN_STEP
|
|
492
|
+
end_x = start_x + WIDTH + TERRAIN_STEP * 2
|
|
493
|
+
x = start_x
|
|
494
|
+
while x <= end_x
|
|
495
|
+
y1 = terrain_y(x) - camera_y
|
|
496
|
+
y2 = terrain_y(x + TERRAIN_STEP) - camera_y
|
|
497
|
+
sx1 = x - camera_x
|
|
498
|
+
sx2 = x + TERRAIN_STEP - camera_x
|
|
499
|
+
Quad.render(x1: sx1, y1: y1, x2: sx2, y2: y2,
|
|
500
|
+
x3: sx2, y3: y2 + GRASS_THICK, x4: sx1, y4: y1 + GRASS_THICK,
|
|
501
|
+
color: '#4d9e3f')
|
|
502
|
+
Quad.render(x1: sx1, y1: y1 + GRASS_THICK, x2: sx2, y2: y2 + GRASS_THICK,
|
|
503
|
+
x3: sx2, y3: HEIGHT, x4: sx1, y4: HEIGHT,
|
|
504
|
+
color: ['#6b4a2f', '#6b4a2f', '#3f2d1d', '#3f2d1d'])
|
|
505
|
+
Line.render(x1: sx1, y1: y1, x2: sx2, y2: y2, stroke_width: 3, color: '#86d95c')
|
|
506
|
+
x += TERRAIN_STEP
|
|
507
|
+
end
|
|
508
|
+
|
|
509
|
+
# Checkered finish flag on a pole at the end of the world.
|
|
510
|
+
fsx = FINISH_X - camera_x
|
|
511
|
+
if fsx > -80 && fsx < WIDTH + 80
|
|
512
|
+
fy = terrain_y(FINISH_X) - camera_y
|
|
513
|
+
ftop = fy - 130
|
|
514
|
+
Rectangle.render(x: fsx - 2, y: ftop, width: 4, height: fy - ftop, color: '#475569')
|
|
515
|
+
cell = 11
|
|
516
|
+
4.times do |r|
|
|
517
|
+
6.times do |c|
|
|
518
|
+
shade = (r + c).even? ? '#f8fafc' : '#111827'
|
|
519
|
+
Rectangle.render(x: fsx + 2 + c * cell, y: ftop + r * cell,
|
|
520
|
+
width: cell, height: cell, color: shade)
|
|
521
|
+
end
|
|
522
|
+
end
|
|
523
|
+
end
|
|
524
|
+
|
|
525
|
+
# Cans.
|
|
526
|
+
can_data.each_with_index do |(cx, cy), i|
|
|
527
|
+
next if can_collected[i]
|
|
528
|
+
draw_can(cx - camera_x, cy - camera_y, terrain_slope(cx))
|
|
529
|
+
end
|
|
530
|
+
|
|
531
|
+
# Turbo exhaust embers glowing just behind the tailpipe.
|
|
532
|
+
embers.each do |ex, ey, _evx, _evy, elife|
|
|
533
|
+
a = (elife / EMBER_LIFE).clamp(0.0, 1.0)
|
|
534
|
+
Circle.render(x: ex - camera_x, y: ey - camera_y, radius: 1.0 + a * 2.0,
|
|
535
|
+
color: [1.0, 0.5 + a * 0.35, 0.15, a])
|
|
536
|
+
end
|
|
537
|
+
|
|
538
|
+
# Car. Build local-space points then rotate by `angle` and translate to
|
|
539
|
+
# the screen. Local origin is the chassis center; +y is "down" in body
|
|
540
|
+
# space, which lines up with screen y after rotation.
|
|
541
|
+
cos_a = Math.cos(angle)
|
|
542
|
+
sin_a = Math.sin(angle)
|
|
543
|
+
cx = world_x - camera_x
|
|
544
|
+
cy = world_y - camera_y
|
|
545
|
+
to_screen = ->(lx, ly) { [cx + lx * cos_a - ly * sin_a, cy + lx * sin_a + ly * cos_a] }
|
|
546
|
+
|
|
547
|
+
# Soft contact shadow on the ground below the car — a flattened ellipse
|
|
548
|
+
# rotated onto the local ground slope so it hugs the hill instead of lying
|
|
549
|
+
# flat. Shrinks and fades as the car gains air.
|
|
550
|
+
ground_sy = terrain_y(world_x) - camera_y
|
|
551
|
+
air = (terrain_y(world_x) - GROUND_OFFSET) - world_y
|
|
552
|
+
sh = (1 - air / 300.0).clamp(0.15, 1.0)
|
|
553
|
+
slope_deg = Math.atan(terrain_slope(world_x)) * 180.0 / Math::PI
|
|
554
|
+
Ellipse.render(x: cx, y: ground_sy, xradius: CHASSIS_W * 0.62 * sh, yradius: 5 * sh,
|
|
555
|
+
rotate: slope_deg, color: [0.0, 0.0, 0.0, 0.20 * sh])
|
|
556
|
+
|
|
557
|
+
hw = CHASSIS_W / 2.0
|
|
558
|
+
hh = CHASSIS_H / 2.0
|
|
559
|
+
|
|
560
|
+
# Turbo flame or a light exhaust puff out the tailpipe (behind the chassis).
|
|
561
|
+
if boosting && fuel.positive?
|
|
562
|
+
flick = 14 + rand * 8
|
|
563
|
+
b1 = to_screen.call(-hw - 3, -5)
|
|
564
|
+
b2 = to_screen.call(-hw - 3, 5)
|
|
565
|
+
tip = to_screen.call(-hw - 3 - flick, (rand - 0.5) * 3)
|
|
566
|
+
Triangle.render(x1: b1[0], y1: b1[1], x2: b2[0], y2: b2[1], x3: tip[0], y3: tip[1],
|
|
567
|
+
color: ['#f97316', '#f97316', '#fca311'])
|
|
568
|
+
b3 = to_screen.call(-hw - 3, -2.5)
|
|
569
|
+
b4 = to_screen.call(-hw - 3, 2.5)
|
|
570
|
+
tip2 = to_screen.call(-hw - 3 - flick * 0.6, (rand - 0.5) * 2)
|
|
571
|
+
Triangle.render(x1: b3[0], y1: b3[1], x2: b4[0], y2: b4[1], x3: tip2[0], y3: tip2[1],
|
|
572
|
+
color: ['#fde047', '#fde047', '#fff7cc'])
|
|
573
|
+
elsif accel && fuel.positive?
|
|
574
|
+
puff = to_screen.call(-hw - 6, 0)
|
|
575
|
+
r = 4 + rand * 3
|
|
576
|
+
Circle.render(x: puff[0] + rand(-2..2), y: puff[1] + rand(-2..2),
|
|
577
|
+
radius: r, color: [0.32, 0.34, 0.38, 0.5])
|
|
578
|
+
end
|
|
579
|
+
|
|
580
|
+
c1 = to_screen.call(-hw, -hh)
|
|
581
|
+
c2 = to_screen.call(hw, -hh)
|
|
582
|
+
c3 = to_screen.call(hw, hh)
|
|
583
|
+
c4 = to_screen.call(-hw, hh)
|
|
584
|
+
Quad.render(x1: c1[0], y1: c1[1], x2: c2[0], y2: c2[1],
|
|
585
|
+
x3: c3[0], y3: c3[1], x4: c4[0], y4: c4[1],
|
|
586
|
+
color: '#e63946')
|
|
587
|
+
|
|
588
|
+
cab1 = to_screen.call(-12, -hh)
|
|
589
|
+
cab2 = to_screen.call(18, -hh)
|
|
590
|
+
cab3 = to_screen.call(12, -hh - 14)
|
|
591
|
+
cab4 = to_screen.call(-6, -hh - 14)
|
|
592
|
+
Quad.render(x1: cab1[0], y1: cab1[1], x2: cab2[0], y2: cab2[1],
|
|
593
|
+
x3: cab3[0], y3: cab3[1], x4: cab4[0], y4: cab4[1],
|
|
594
|
+
color: '#bde0fe')
|
|
595
|
+
|
|
596
|
+
[-WHEEL_DX, WHEEL_DX].each do |wx|
|
|
597
|
+
pos = to_screen.call(wx, WHEEL_DY)
|
|
598
|
+
Circle.render(x: pos[0], y: pos[1], radius: WHEEL_RADIUS, color: '#0f172a')
|
|
599
|
+
Circle.render(x: pos[0], y: pos[1], radius: WHEEL_RADIUS - 4, color: '#475569')
|
|
600
|
+
sx2 = pos[0] + Math.cos(angle + wheel_spin) * (WHEEL_RADIUS - 2)
|
|
601
|
+
sy2 = pos[1] + Math.sin(angle + wheel_spin) * (WHEEL_RADIUS - 2)
|
|
602
|
+
Line.render(x1: pos[0], y1: pos[1], x2: sx2, y2: sy2, stroke_width: 2, color: '#cbd5e1')
|
|
603
|
+
end
|
|
604
|
+
|
|
605
|
+
# Fuel-can pickup sparks, brightest when freshly spawned.
|
|
606
|
+
sparks.each do |px, py, _pvx, _pvy, life|
|
|
607
|
+
a = (life / SPARK_LIFE).clamp(0.0, 1.0)
|
|
608
|
+
Circle.render(x: px - camera_x, y: py - camera_y, radius: 1.5 + a * 2.5,
|
|
609
|
+
color: [1.0, 0.93, 0.5, a])
|
|
610
|
+
end
|
|
611
|
+
end
|
|
612
|
+
|
|
613
|
+
show
|