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
data/examples/snake.rb
ADDED
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
# Snake
|
|
2
|
+
# Classic snake — steer with arrow keys, eat to grow, don't cross yourself.
|
|
3
|
+
#
|
|
4
|
+
# Eat the red square to grow longer and earn a point. Every five points
|
|
5
|
+
# the snake speeds up. The world wraps at the edges, but the snake dies
|
|
6
|
+
# if it crosses itself. Press `r` at any time to start a new game.
|
|
7
|
+
|
|
8
|
+
require 'ruby2d'
|
|
9
|
+
|
|
10
|
+
# === Tunables ===
|
|
11
|
+
|
|
12
|
+
WIDTH = 640 # window width in pixels
|
|
13
|
+
HEIGHT = 480 # window height in pixels
|
|
14
|
+
GRID = 20 # cell size in pixels (smaller = bigger play area)
|
|
15
|
+
START_INTERVAL = 0.067 # seconds between moves at game start
|
|
16
|
+
MIN_INTERVAL = 0.025 # fastest cadence the snake will reach (seconds)
|
|
17
|
+
INTERVAL_STEP = 0.0083 # seconds shaved off the move interval per speedup
|
|
18
|
+
SPEEDUP_EVERY = 5 # speed up every N points
|
|
19
|
+
GROWTH = 2 # segments added to the snake per apple eaten
|
|
20
|
+
|
|
21
|
+
COLS = WIDTH / GRID
|
|
22
|
+
ROWS = HEIGHT / GRID
|
|
23
|
+
|
|
24
|
+
SNAKE_COLOR = '#06d6a0'
|
|
25
|
+
FOOD_COLOR = '#e94560'
|
|
26
|
+
|
|
27
|
+
# === Window ===
|
|
28
|
+
|
|
29
|
+
set title: 'Ruby 2D ▸ Examples ▸ Snake', width: WIDTH, height: HEIGHT, background: '#1b1b2f'
|
|
30
|
+
set close_on_esc: true
|
|
31
|
+
|
|
32
|
+
# === Helpers ===
|
|
33
|
+
|
|
34
|
+
def place_food(snake)
|
|
35
|
+
pos = [rand(COLS), rand(ROWS)]
|
|
36
|
+
pos = [rand(COLS), rand(ROWS)] while snake.include?(pos)
|
|
37
|
+
pos
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
# === Mutable state ===
|
|
41
|
+
|
|
42
|
+
snake = []
|
|
43
|
+
segments = []
|
|
44
|
+
dir = [1, 0]
|
|
45
|
+
next_dir = [1, 0]
|
|
46
|
+
food = [0, 0]
|
|
47
|
+
score = 0
|
|
48
|
+
interval = START_INTERVAL # current seconds between moves
|
|
49
|
+
move_timer = 0 # seconds until the next move
|
|
50
|
+
grow = 0
|
|
51
|
+
alive = true
|
|
52
|
+
|
|
53
|
+
# === HUD ===
|
|
54
|
+
|
|
55
|
+
label = Text.new('Score: 0', x: 10, y: 8, size: 18, color: '#f9fafb', z: 10)
|
|
56
|
+
food_sq = Square.new(size: GRID - 4, color: FOOD_COLOR)
|
|
57
|
+
|
|
58
|
+
reset = lambda do
|
|
59
|
+
segments.each(&:remove)
|
|
60
|
+
segments.clear
|
|
61
|
+
|
|
62
|
+
snake.replace([[COLS / 2, ROWS / 2]])
|
|
63
|
+
segments << Square.new(
|
|
64
|
+
x: snake[0][0] * GRID + 1, y: snake[0][1] * GRID + 1,
|
|
65
|
+
size: GRID - 2, color: SNAKE_COLOR
|
|
66
|
+
)
|
|
67
|
+
|
|
68
|
+
dir = [1, 0]
|
|
69
|
+
next_dir = [1, 0]
|
|
70
|
+
food = place_food(snake)
|
|
71
|
+
food_sq.x = food[0] * GRID + 2
|
|
72
|
+
food_sq.y = food[1] * GRID + 2
|
|
73
|
+
score = 0
|
|
74
|
+
interval = START_INTERVAL
|
|
75
|
+
move_timer = 0 # first move runs immediately on next frame
|
|
76
|
+
grow = 0
|
|
77
|
+
alive = true
|
|
78
|
+
label.content = 'Score: 0'
|
|
79
|
+
end
|
|
80
|
+
|
|
81
|
+
reset.call
|
|
82
|
+
|
|
83
|
+
# === Input ===
|
|
84
|
+
|
|
85
|
+
on :key_down do |event|
|
|
86
|
+
case event.key
|
|
87
|
+
when 'up' then next_dir = [0, -1] unless dir == [0, 1]
|
|
88
|
+
when 'down' then next_dir = [0, 1] unless dir == [0, -1]
|
|
89
|
+
when 'left' then next_dir = [-1, 0] unless dir == [1, 0]
|
|
90
|
+
when 'right' then next_dir = [1, 0] unless dir == [-1, 0]
|
|
91
|
+
when 'r' then reset.call
|
|
92
|
+
end
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
# === Per-frame update ===
|
|
96
|
+
|
|
97
|
+
update do |dt|
|
|
98
|
+
next unless alive
|
|
99
|
+
|
|
100
|
+
move_timer -= dt
|
|
101
|
+
next if move_timer > 0
|
|
102
|
+
|
|
103
|
+
dir = next_dir
|
|
104
|
+
head = [(snake[0][0] + dir[0]) % COLS, (snake[0][1] + dir[1]) % ROWS]
|
|
105
|
+
|
|
106
|
+
if snake.include?(head)
|
|
107
|
+
alive = false
|
|
108
|
+
label.content = "Game Over! Score: #{score} ▸ press r to restart"
|
|
109
|
+
next
|
|
110
|
+
end
|
|
111
|
+
|
|
112
|
+
snake.unshift(head)
|
|
113
|
+
segments.unshift(
|
|
114
|
+
Square.new(x: head[0] * GRID + 1, y: head[1] * GRID + 1,
|
|
115
|
+
size: GRID - 2, color: SNAKE_COLOR)
|
|
116
|
+
)
|
|
117
|
+
|
|
118
|
+
if head == food
|
|
119
|
+
score += 1
|
|
120
|
+
label.content = "Score: #{score}"
|
|
121
|
+
interval = [MIN_INTERVAL, interval - INTERVAL_STEP].max if score % SPEEDUP_EVERY == 0
|
|
122
|
+
grow += GROWTH
|
|
123
|
+
food = place_food(snake)
|
|
124
|
+
food_sq.x = food[0] * GRID + 2
|
|
125
|
+
food_sq.y = food[1] * GRID + 2
|
|
126
|
+
end
|
|
127
|
+
|
|
128
|
+
if grow > 0
|
|
129
|
+
grow -= 1
|
|
130
|
+
else
|
|
131
|
+
snake.pop
|
|
132
|
+
segments.last.remove
|
|
133
|
+
segments.pop
|
|
134
|
+
end
|
|
135
|
+
|
|
136
|
+
segments.each_with_index do |s, i|
|
|
137
|
+
g = i.to_f / [segments.size - 1, 1].max
|
|
138
|
+
s.color = [0.02 + 0.04 * g, 0.84 - 0.5 * g, 0.63 - 0.3 * g, 1]
|
|
139
|
+
end
|
|
140
|
+
|
|
141
|
+
move_timer = interval
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
show
|
|
@@ -0,0 +1,246 @@
|
|
|
1
|
+
# Sprite sheets
|
|
2
|
+
# A platformer scene built entirely from `SpriteSheet`-loaded Kenney.nl atlases.
|
|
3
|
+
#
|
|
4
|
+
# Every visible thing — background, ground, decorations, bee, the
|
|
5
|
+
# player — comes from a `SpriteSheet`, so the four PNGs decode and
|
|
6
|
+
# upload to the GPU once and every sprite reuses them.
|
|
7
|
+
#
|
|
8
|
+
# Left/right (or dpad) to run, space/up (or south button) to jump,
|
|
9
|
+
# 1/2/3 to switch character color, r to reset.
|
|
10
|
+
|
|
11
|
+
require 'ruby2d'
|
|
12
|
+
|
|
13
|
+
# Bundle the atlas directory (see "Atlases" below) into web builds' virtual
|
|
14
|
+
# filesystem. `ruby2d build` reads this directive, so no `--assets` flag is
|
|
15
|
+
# needed; on native the files are read straight from disk.
|
|
16
|
+
# ruby2d:assets assets/resources/spritesheets
|
|
17
|
+
|
|
18
|
+
# === Tunables ===
|
|
19
|
+
|
|
20
|
+
WIDTH = 800 # window width in pixels
|
|
21
|
+
HEIGHT = 600 # window height in pixels
|
|
22
|
+
TILE_SIZE = 64 # ground tile size on screen
|
|
23
|
+
GROUND_Y = HEIGHT - TILE_SIZE # top edge of the ground row
|
|
24
|
+
PLAYER_W = 88 # player render width (atlas frame is 256×256)
|
|
25
|
+
PLAYER_H = 96 # player render height
|
|
26
|
+
PLAYER_GROUND_Y = GROUND_Y - PLAYER_H + 4 # grounded top edge; +4 seats the feet
|
|
27
|
+
BEE_SIZE = 56 # bee render size
|
|
28
|
+
GRAVITY = 1980 # downward acceleration (px/sec²)
|
|
29
|
+
RUN_ACCEL = 2520 # horizontal acceleration (px/sec²)
|
|
30
|
+
FRICTION = 11.9 # horizontal decay rate when no input (per-sec)
|
|
31
|
+
JUMP_V = -780 # initial jump velocity (px/sec, negative is up)
|
|
32
|
+
MAX_SPEED = 380 # horizontal speed cap (px/sec)
|
|
33
|
+
WALK_FRAME_TIME = 110 # ms per walk-cycle frame
|
|
34
|
+
BEE_FRAME_TIME = 90 # ms per bee-fly frame
|
|
35
|
+
BEE_SPEED = 110 # bee horizontal speed (px/sec)
|
|
36
|
+
BEE_BOB_AMP = 28 # bee bob amplitude (px)
|
|
37
|
+
BEE_BOB_RATE = 2.5 # bee bob rate (rad/sec)
|
|
38
|
+
|
|
39
|
+
# === Window ===
|
|
40
|
+
|
|
41
|
+
set title: 'Ruby 2D ▸ Examples ▸ Sprite sheets',
|
|
42
|
+
width: WIDTH, height: HEIGHT, background: '#0c1a3a'
|
|
43
|
+
set close_on_esc: true
|
|
44
|
+
|
|
45
|
+
# === Atlases ===
|
|
46
|
+
#
|
|
47
|
+
# One PNG per sheet, from the bundled Kenney atlases. Every sprite below
|
|
48
|
+
# reaches into one of these via its named region, so this is the only
|
|
49
|
+
# place we touch the filesystem or the GPU for pixels. The path is
|
|
50
|
+
# relative, so run from the repo root; the `ruby2d:assets` directive at
|
|
51
|
+
# the top of the file bundles this directory into web builds.
|
|
52
|
+
|
|
53
|
+
sheets_dir = 'assets/resources/spritesheets'
|
|
54
|
+
tiles_sheet = SpriteSheet.new("#{sheets_dir}/spritesheet-tiles.xml")
|
|
55
|
+
characters_sheet = SpriteSheet.new("#{sheets_dir}/spritesheet-characters.xml")
|
|
56
|
+
backgrounds_sheet = SpriteSheet.new("#{sheets_dir}/spritesheet-backgrounds.xml")
|
|
57
|
+
enemies_sheet = SpriteSheet.new("#{sheets_dir}/spritesheet-enemies.xml")
|
|
58
|
+
|
|
59
|
+
# === Helpers ===
|
|
60
|
+
|
|
61
|
+
# Every character color in this atlas uses the same naming scheme
|
|
62
|
+
# (`character_<color>_idle`, `_walk_a`, `_walk_b`, `_jump`), so we can
|
|
63
|
+
# template the color into each frame name and pass the resulting
|
|
64
|
+
# arrays straight to `Sprite.new` as named animations.
|
|
65
|
+
build_player = lambda do |color|
|
|
66
|
+
Sprite.new(characters_sheet,
|
|
67
|
+
x: 100, y: PLAYER_GROUND_Y,
|
|
68
|
+
width: PLAYER_W, height: PLAYER_H, z: 5,
|
|
69
|
+
animations: {
|
|
70
|
+
idle: ["character_#{color}_idle"],
|
|
71
|
+
walk: ["character_#{color}_walk_a", "character_#{color}_walk_b"],
|
|
72
|
+
jump: ["character_#{color}_jump"]
|
|
73
|
+
},
|
|
74
|
+
time: WALK_FRAME_TIME)
|
|
75
|
+
end
|
|
76
|
+
|
|
77
|
+
# === Scene ===
|
|
78
|
+
|
|
79
|
+
# Backdrop fills the whole window. Setting width/height here scales
|
|
80
|
+
# whatever the atlas frame happens to be (these are 512×512) up to fit.
|
|
81
|
+
Sprite.new(backgrounds_sheet, frame: 'background_color_hills',
|
|
82
|
+
x: 0, y: 0, width: WIDTH, height: HEIGHT, z: 0)
|
|
83
|
+
|
|
84
|
+
# Ground row.
|
|
85
|
+
((WIDTH / TILE_SIZE) + 1).times do |col|
|
|
86
|
+
Sprite.new(tiles_sheet, frame: 'terrain_grass_block_top',
|
|
87
|
+
x: col * TILE_SIZE, y: GROUND_Y,
|
|
88
|
+
width: TILE_SIZE, height: TILE_SIZE, z: 2)
|
|
89
|
+
end
|
|
90
|
+
|
|
91
|
+
# Decorative tufts and props sitting on top of the ground row. Each is
|
|
92
|
+
# its own Sprite, all sharing the tiles texture under the hood.
|
|
93
|
+
[
|
|
94
|
+
[70, 'mushroom_red', 44],
|
|
95
|
+
[200, 'grass', 42],
|
|
96
|
+
[310, 'bush', 48],
|
|
97
|
+
[430, 'grass_purple', 42],
|
|
98
|
+
[560, 'mushroom_brown', 44],
|
|
99
|
+
[690, 'rock', 40]
|
|
100
|
+
].each do |x, name, size|
|
|
101
|
+
Sprite.new(tiles_sheet, frame: name,
|
|
102
|
+
x: x, y: GROUND_Y - size + 4,
|
|
103
|
+
width: size, height: size, z: 3)
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
# Bee — animated, drifts left across the sky and wraps.
|
|
107
|
+
bee = Sprite.new(enemies_sheet,
|
|
108
|
+
x: WIDTH - 200, y: 200,
|
|
109
|
+
width: BEE_SIZE, height: BEE_SIZE, z: 4,
|
|
110
|
+
animations: { fly: %w[bee_a bee_b] },
|
|
111
|
+
time: BEE_FRAME_TIME)
|
|
112
|
+
bee.play(animation: :fly, loop: true)
|
|
113
|
+
|
|
114
|
+
# === Mutable state ===
|
|
115
|
+
|
|
116
|
+
PLAYER_COLORS = %i[beige green pink].freeze
|
|
117
|
+
|
|
118
|
+
color_index = 0
|
|
119
|
+
player = build_player.(PLAYER_COLORS[color_index])
|
|
120
|
+
player.play(animation: :idle, loop: true)
|
|
121
|
+
|
|
122
|
+
px = player.x.to_f
|
|
123
|
+
py = player.y.to_f
|
|
124
|
+
vx = 0.0
|
|
125
|
+
vy = 0.0
|
|
126
|
+
on_ground = true
|
|
127
|
+
facing = :right
|
|
128
|
+
left = false
|
|
129
|
+
right = false
|
|
130
|
+
state = :idle # currently playing animation
|
|
131
|
+
bee_t = 0.0
|
|
132
|
+
bee_base_y = bee.y.to_f
|
|
133
|
+
|
|
134
|
+
# === Color switching ===
|
|
135
|
+
|
|
136
|
+
switch_color = lambda do |idx|
|
|
137
|
+
next if idx == color_index || idx >= PLAYER_COLORS.length
|
|
138
|
+
|
|
139
|
+
color_index = idx
|
|
140
|
+
old = player
|
|
141
|
+
player = build_player.(PLAYER_COLORS[color_index])
|
|
142
|
+
player.x = old.x
|
|
143
|
+
player.y = old.y
|
|
144
|
+
# `:jump` is non-looping so the new sprite holds on the jump pose
|
|
145
|
+
# mid-air; `:idle` and `:walk` keep cycling.
|
|
146
|
+
player.play(animation: state,
|
|
147
|
+
loop: state != :jump,
|
|
148
|
+
flip: facing == :left ? :horizontal : nil)
|
|
149
|
+
old.remove
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
# === Reset ===
|
|
153
|
+
|
|
154
|
+
reset = lambda do
|
|
155
|
+
px = 100.0
|
|
156
|
+
py = PLAYER_GROUND_Y.to_f
|
|
157
|
+
vx = 0.0
|
|
158
|
+
vy = 0.0
|
|
159
|
+
on_ground = true
|
|
160
|
+
facing = :right
|
|
161
|
+
state = :idle
|
|
162
|
+
player.play(animation: :idle, loop: true, flip: nil)
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
# === Input ===
|
|
166
|
+
|
|
167
|
+
on key_down: :left do left = true end
|
|
168
|
+
on key_down: :right do right = true end
|
|
169
|
+
on key_up: :left do left = false end
|
|
170
|
+
on key_up: :right do right = false end
|
|
171
|
+
|
|
172
|
+
on key_down: %i[space up], gamepad_button_down: :south do
|
|
173
|
+
if on_ground
|
|
174
|
+
vy = JUMP_V
|
|
175
|
+
on_ground = false
|
|
176
|
+
state = :jump
|
|
177
|
+
# Non-looping single-frame play: the sprite holds on the jump pose
|
|
178
|
+
# until we transition back to walk/idle on landing.
|
|
179
|
+
player.play(animation: :jump,
|
|
180
|
+
flip: facing == :left ? :horizontal : nil)
|
|
181
|
+
end
|
|
182
|
+
end
|
|
183
|
+
|
|
184
|
+
on(key_down: '1') { switch_color.call(0) }
|
|
185
|
+
on(key_down: '2') { switch_color.call(1) }
|
|
186
|
+
on(key_down: '3') { switch_color.call(2) }
|
|
187
|
+
on(key_down: :r) { reset.call }
|
|
188
|
+
|
|
189
|
+
# === Per-frame update ===
|
|
190
|
+
|
|
191
|
+
update do |dt|
|
|
192
|
+
go_left = left || gamepads.any? { |p| p.held?(:dpad_left) }
|
|
193
|
+
go_right = right || gamepads.any? { |p| p.held?(:dpad_right) }
|
|
194
|
+
|
|
195
|
+
vx -= RUN_ACCEL * dt if go_left && !go_right
|
|
196
|
+
vx += RUN_ACCEL * dt if go_right && !go_left
|
|
197
|
+
vx *= Math.exp(-FRICTION * dt) unless go_left ^ go_right
|
|
198
|
+
vx = vx.clamp(-MAX_SPEED, MAX_SPEED)
|
|
199
|
+
vy += GRAVITY * dt
|
|
200
|
+
|
|
201
|
+
px = (px + vx * dt).clamp(0, WIDTH - PLAYER_W)
|
|
202
|
+
py += vy * dt
|
|
203
|
+
|
|
204
|
+
# Ground collision
|
|
205
|
+
if py >= PLAYER_GROUND_Y
|
|
206
|
+
py = PLAYER_GROUND_Y.to_f
|
|
207
|
+
just_landed = !on_ground
|
|
208
|
+
on_ground = true
|
|
209
|
+
vy = 0
|
|
210
|
+
if just_landed
|
|
211
|
+
desired = vx.abs > 20 ? :walk : :idle
|
|
212
|
+
flip = facing == :left ? :horizontal : nil
|
|
213
|
+
player.play(animation: desired, loop: true, flip: flip)
|
|
214
|
+
state = desired
|
|
215
|
+
end
|
|
216
|
+
end
|
|
217
|
+
|
|
218
|
+
# Facing follows the velocity sign (with a small dead-zone so easing
|
|
219
|
+
# to a stop doesn't flip the sprite back).
|
|
220
|
+
new_facing = if vx > 20 then :right
|
|
221
|
+
elsif vx < -20 then :left
|
|
222
|
+
else facing
|
|
223
|
+
end
|
|
224
|
+
|
|
225
|
+
# Animation transitions on the ground only — mid-air sticks on :jump.
|
|
226
|
+
if on_ground
|
|
227
|
+
desired = vx.abs > 20 ? :walk : :idle
|
|
228
|
+
if desired != state || new_facing != facing
|
|
229
|
+
flip = new_facing == :left ? :horizontal : nil
|
|
230
|
+
player.play(animation: desired, loop: true, flip: flip)
|
|
231
|
+
state = desired
|
|
232
|
+
end
|
|
233
|
+
end
|
|
234
|
+
facing = new_facing
|
|
235
|
+
|
|
236
|
+
player.x = px
|
|
237
|
+
player.y = py
|
|
238
|
+
|
|
239
|
+
# Bee: drift left forever, bob in a sine wave, wrap around the right.
|
|
240
|
+
bee_t += dt
|
|
241
|
+
bee.x -= BEE_SPEED * dt
|
|
242
|
+
bee.x += WIDTH + BEE_SIZE if bee.x < -BEE_SIZE
|
|
243
|
+
bee.y = bee_base_y + Math.sin(bee_t * BEE_BOB_RATE) * BEE_BOB_AMP
|
|
244
|
+
end
|
|
245
|
+
|
|
246
|
+
show
|
data/examples/swarm.rb
ADDED
|
@@ -0,0 +1,206 @@
|
|
|
1
|
+
# Swarm
|
|
2
|
+
# Drifting dots linked to their nearest neighbors form a living mesh.
|
|
3
|
+
#
|
|
4
|
+
# 120 dots drift across a dark field, each linked to its two nearest
|
|
5
|
+
# neighbors by a thin line — a living network that re-stitches itself
|
|
6
|
+
# every frame. The cursor pushes dots aside within a small radius, so
|
|
7
|
+
# the mesh bends and tears around it as you move. Press `r` to scatter.
|
|
8
|
+
|
|
9
|
+
require 'ruby2d'
|
|
10
|
+
|
|
11
|
+
# === Tunables ===
|
|
12
|
+
|
|
13
|
+
WIDTH = 800 # window width in pixels
|
|
14
|
+
HEIGHT = 600 # window height in pixels
|
|
15
|
+
DOT_COUNT = 120 # number of dots in the swarm
|
|
16
|
+
NEIGHBORS = 2 # links per dot to its nearest neighbors
|
|
17
|
+
LINK_RADIUS = 160 # links beyond this distance are not drawn
|
|
18
|
+
DRIFT_SPEED = 25 # average dot drift speed (px/sec)
|
|
19
|
+
PUSH_RADIUS = 100 # cursor influence radius
|
|
20
|
+
PUSH_STRENGTH = 300 # max cursor push speed (px/sec)
|
|
21
|
+
FADE_IN_RATE = 3.0 # opacity units per second when a link forms
|
|
22
|
+
FADE_OUT_RATE = 2.0 # opacity units per second when a link drops
|
|
23
|
+
|
|
24
|
+
# === Window ===
|
|
25
|
+
|
|
26
|
+
set title: 'Ruby 2D ▸ Examples ▸ Swarm', width: WIDTH, height: HEIGHT, background: '#0a0a23'
|
|
27
|
+
set close_on_esc: true
|
|
28
|
+
|
|
29
|
+
# === Initialization ===
|
|
30
|
+
|
|
31
|
+
Dot = Struct.new(:x, :y, :vx, :vy, :shape)
|
|
32
|
+
Edge = Struct.new(:line, :opacity)
|
|
33
|
+
|
|
34
|
+
def random_velocity
|
|
35
|
+
angle = rand * 2 * Math::PI
|
|
36
|
+
speed = DRIFT_SPEED * (0.6 + rand * 0.8)
|
|
37
|
+
[Math.cos(angle) * speed, Math.sin(angle) * speed]
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def random_dot
|
|
41
|
+
vx, vy = random_velocity
|
|
42
|
+
x = rand * WIDTH
|
|
43
|
+
y = rand * HEIGHT
|
|
44
|
+
Dot.new(
|
|
45
|
+
x, y, vx, vy,
|
|
46
|
+
Circle.new(
|
|
47
|
+
x: x, y: y, radius: 3,
|
|
48
|
+
color: [rand * 0.5 + 0.5, rand * 0.5 + 0.5, rand * 0.5 + 0.5, 0.8]
|
|
49
|
+
)
|
|
50
|
+
)
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
dots = Array.new(DOT_COUNT) { random_dot }
|
|
54
|
+
|
|
55
|
+
# Pool sized to cover the steady-state edge count plus headroom for edges
|
|
56
|
+
# still fading out while their replacements fade in.
|
|
57
|
+
LINE_POOL_SIZE = DOT_COUNT * NEIGHBORS * 3
|
|
58
|
+
free_lines = Array.new(LINE_POOL_SIZE) do
|
|
59
|
+
Line.new(x1: 0, y1: 0, x2: 0, y2: 0,
|
|
60
|
+
stroke_width: 1, color: [0.6, 0.75, 1.0, 0],
|
|
61
|
+
visible: false)
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
# Active edges keyed by sorted-pair index. Tracking by pair (rather than by
|
|
65
|
+
# line slot) lets opacity ease toward its distance-based target across
|
|
66
|
+
# frames, so links fade in/out instead of snapping when the K-nearest
|
|
67
|
+
# neighbor set shifts.
|
|
68
|
+
edges = {}
|
|
69
|
+
|
|
70
|
+
# Reused per-frame buffers. `desired` is cleared rather than rebuilt, and
|
|
71
|
+
# the two `best_*` arrays hold one dot's nearest-NEIGHBORS selection.
|
|
72
|
+
desired = {}
|
|
73
|
+
best_d2 = Array.new(NEIGHBORS, 0.0)
|
|
74
|
+
best_j = Array.new(NEIGHBORS, -1)
|
|
75
|
+
|
|
76
|
+
mouse_x = WIDTH / 2.0
|
|
77
|
+
mouse_y = HEIGHT / 2.0
|
|
78
|
+
|
|
79
|
+
# === Input ===
|
|
80
|
+
|
|
81
|
+
on :mouse_move do |event|
|
|
82
|
+
mouse_x = event.x
|
|
83
|
+
mouse_y = event.y
|
|
84
|
+
end
|
|
85
|
+
|
|
86
|
+
on key_down: :r do
|
|
87
|
+
dots.each do |d|
|
|
88
|
+
d.x = rand * WIDTH
|
|
89
|
+
d.y = rand * HEIGHT
|
|
90
|
+
d.vx, d.vy = random_velocity
|
|
91
|
+
end
|
|
92
|
+
end
|
|
93
|
+
|
|
94
|
+
# === Update ===
|
|
95
|
+
|
|
96
|
+
update do |dt|
|
|
97
|
+
push_r2 = PUSH_RADIUS * PUSH_RADIUS
|
|
98
|
+
link_r2 = LINK_RADIUS * LINK_RADIUS
|
|
99
|
+
|
|
100
|
+
# Move dots: drift + cursor push, wrap at edges
|
|
101
|
+
dots.each do |d|
|
|
102
|
+
px = 0.0
|
|
103
|
+
py = 0.0
|
|
104
|
+
rx = d.x - mouse_x
|
|
105
|
+
ry = d.y - mouse_y
|
|
106
|
+
r2 = rx * rx + ry * ry
|
|
107
|
+
if r2 < push_r2 && r2 > 0.001
|
|
108
|
+
r = Math.sqrt(r2)
|
|
109
|
+
push = PUSH_STRENGTH * (1.0 - r / PUSH_RADIUS) * dt
|
|
110
|
+
px = (rx / r) * push
|
|
111
|
+
py = (ry / r) * push
|
|
112
|
+
end
|
|
113
|
+
d.x = (d.x + d.vx * dt + px) % WIDTH
|
|
114
|
+
d.y = (d.y + d.vy * dt + py) % HEIGHT
|
|
115
|
+
d.shape.x = d.x
|
|
116
|
+
d.shape.y = d.y
|
|
117
|
+
end
|
|
118
|
+
|
|
119
|
+
# Collect this frame's desired pairs and their target opacities. Pair
|
|
120
|
+
# distance is symmetric, so a pair selected from both endpoints writes
|
|
121
|
+
# the same target either way.
|
|
122
|
+
# Only the NEIGHBORS nearest survive, so each candidate is inserted
|
|
123
|
+
# straight into a sorted fixed-size buffer. Building a full candidate
|
|
124
|
+
# list and sorting it would allocate ~20 arrays per dot to discard all
|
|
125
|
+
# but two — the cutoff test below rejects most candidates outright.
|
|
126
|
+
desired.clear
|
|
127
|
+
cutoff = link_r2 + 1.0
|
|
128
|
+
DOT_COUNT.times do |i|
|
|
129
|
+
di = dots[i]
|
|
130
|
+
NEIGHBORS.times do |n|
|
|
131
|
+
best_d2[n] = cutoff
|
|
132
|
+
best_j[n] = -1
|
|
133
|
+
end
|
|
134
|
+
DOT_COUNT.times do |j|
|
|
135
|
+
next if i == j
|
|
136
|
+
dj = dots[j]
|
|
137
|
+
dx = di.x - dj.x
|
|
138
|
+
dy = di.y - dj.y
|
|
139
|
+
d2 = dx * dx + dy * dy
|
|
140
|
+
next if d2 > link_r2 || d2 >= best_d2[NEIGHBORS - 1]
|
|
141
|
+
|
|
142
|
+
n = NEIGHBORS - 1
|
|
143
|
+
while n > 0 && best_d2[n - 1] > d2
|
|
144
|
+
best_d2[n] = best_d2[n - 1]
|
|
145
|
+
best_j[n] = best_j[n - 1]
|
|
146
|
+
n -= 1
|
|
147
|
+
end
|
|
148
|
+
best_d2[n] = d2
|
|
149
|
+
best_j[n] = j
|
|
150
|
+
end
|
|
151
|
+
NEIGHBORS.times do |n|
|
|
152
|
+
j = best_j[n]
|
|
153
|
+
next if j.negative?
|
|
154
|
+
|
|
155
|
+
key = i < j ? i * DOT_COUNT + j : j * DOT_COUNT + i
|
|
156
|
+
desired[key] = (1.0 - Math.sqrt(best_d2[n]) / LINK_RADIUS) * 0.5
|
|
157
|
+
end
|
|
158
|
+
end
|
|
159
|
+
|
|
160
|
+
# Allocate lines for newly desired pairs (starting at opacity 0 so they
|
|
161
|
+
# fade in rather than appearing at full target opacity).
|
|
162
|
+
desired.each_key do |key|
|
|
163
|
+
next if edges.key?(key)
|
|
164
|
+
line = free_lines.pop
|
|
165
|
+
break unless line
|
|
166
|
+
edges[key] = Edge.new(line, 0.0)
|
|
167
|
+
end
|
|
168
|
+
|
|
169
|
+
# Ease each active edge's opacity toward its target, render it, and
|
|
170
|
+
# release lines whose edges have fully faded out.
|
|
171
|
+
edges.delete_if do |key, edge|
|
|
172
|
+
target = desired[key] || 0.0
|
|
173
|
+
edge.opacity = if edge.opacity < target
|
|
174
|
+
[edge.opacity + FADE_IN_RATE * dt, target].min
|
|
175
|
+
else
|
|
176
|
+
[edge.opacity - FADE_OUT_RATE * dt, target].max
|
|
177
|
+
end
|
|
178
|
+
if edge.opacity <= 0.001 && target.zero?
|
|
179
|
+
edge.line.visible = false
|
|
180
|
+
free_lines << edge.line
|
|
181
|
+
true
|
|
182
|
+
else
|
|
183
|
+
di = dots[key / DOT_COUNT]
|
|
184
|
+
dj = dots[key % DOT_COUNT]
|
|
185
|
+
line = edge.line
|
|
186
|
+
dx = di.x - dj.x
|
|
187
|
+
dy = di.y - dj.y
|
|
188
|
+
if dx * dx + dy * dy > link_r2
|
|
189
|
+
# Endpoints span more than LINK_RADIUS ▸ typically because a dot
|
|
190
|
+
# just wrapped at the screen edge or was scattered. Hide the line
|
|
191
|
+
# while the edge fades out so it doesn't shoot across the window.
|
|
192
|
+
line.visible = false
|
|
193
|
+
else
|
|
194
|
+
line.x1 = di.x
|
|
195
|
+
line.y1 = di.y
|
|
196
|
+
line.x2 = dj.x
|
|
197
|
+
line.y2 = dj.y
|
|
198
|
+
line.opacity = edge.opacity
|
|
199
|
+
line.visible = true
|
|
200
|
+
end
|
|
201
|
+
false
|
|
202
|
+
end
|
|
203
|
+
end
|
|
204
|
+
end
|
|
205
|
+
|
|
206
|
+
show
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
# Travelling salesman (simulated annealing)
|
|
2
|
+
# A 2-opt search wrapped in simulated annealing untangles a 60-city tour.
|
|
3
|
+
#
|
|
4
|
+
# Each step picks two edges, sees what happens if the tour segment
|
|
5
|
+
# between them is reversed, and accepts the swap when it shortens the
|
|
6
|
+
# tour — or, with probability `exp(-Δ / T)`, even when it lengthens it.
|
|
7
|
+
# The temperature `T` cools each step, so late on the search only takes
|
|
8
|
+
# the wins. The tangled mess relaxes into a clean closed loop. Press R
|
|
9
|
+
# for a fresh set of cities.
|
|
10
|
+
|
|
11
|
+
require 'ruby2d'
|
|
12
|
+
|
|
13
|
+
# === Tunables ===
|
|
14
|
+
|
|
15
|
+
WIDTH = 800 # window width in pixels
|
|
16
|
+
HEIGHT = 600 # window height in pixels
|
|
17
|
+
HUD_H = 36 # reserved strip at the top for the label
|
|
18
|
+
NUM_CITIES = 60 # cities to visit
|
|
19
|
+
ITERS_PER_FRAME = 800 # 2-opt proposals attempted each frame
|
|
20
|
+
INITIAL_T = 220.0 # starting temperature in distance units
|
|
21
|
+
COOLING = 0.99996 # T multiplier per attempt
|
|
22
|
+
|
|
23
|
+
# === Window ===
|
|
24
|
+
|
|
25
|
+
set title: 'Ruby 2D ▸ Examples ▸ Travelling salesman (simulated annealing)',
|
|
26
|
+
width: WIDTH, height: HEIGHT, background: '#0a0e1c'
|
|
27
|
+
set close_on_esc: true
|
|
28
|
+
|
|
29
|
+
# === State ===
|
|
30
|
+
|
|
31
|
+
cities = [] # [x, y] points
|
|
32
|
+
tour = [] # permutation of 0...NUM_CITIES
|
|
33
|
+
total_length = 0.0 # cached length of the current tour
|
|
34
|
+
temperature = 0.0
|
|
35
|
+
|
|
36
|
+
reset = lambda do
|
|
37
|
+
cities.clear
|
|
38
|
+
NUM_CITIES.times do
|
|
39
|
+
cities << [40 + rand(WIDTH - 80), HUD_H + 20 + rand(HEIGHT - HUD_H - 40)]
|
|
40
|
+
end
|
|
41
|
+
tour.replace((0...NUM_CITIES).to_a.shuffle)
|
|
42
|
+
total_length = 0.0
|
|
43
|
+
NUM_CITIES.times do |k|
|
|
44
|
+
pa = cities[tour[k]]
|
|
45
|
+
pb = cities[tour[(k + 1) % NUM_CITIES]]
|
|
46
|
+
total_length += Math.hypot(pa[0] - pb[0], pa[1] - pb[1])
|
|
47
|
+
end
|
|
48
|
+
temperature = INITIAL_T
|
|
49
|
+
end
|
|
50
|
+
|
|
51
|
+
reset.call
|
|
52
|
+
|
|
53
|
+
# === Persistent overlays ===
|
|
54
|
+
|
|
55
|
+
Text.new('Press R for new cities', x: 16, y: 12, size: 16, color: '#cbd5e1', z: 10)
|
|
56
|
+
|
|
57
|
+
# === Input ===
|
|
58
|
+
|
|
59
|
+
on key_down: :r do
|
|
60
|
+
reset.call
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
# === Per-frame update ===
|
|
64
|
+
|
|
65
|
+
# Each step picks i < j inside the tour interior, computes only the
|
|
66
|
+
# four edge lengths that change under the reverse, and either commits
|
|
67
|
+
# or rolls dice against the Boltzmann factor.
|
|
68
|
+
update do
|
|
69
|
+
k = 0
|
|
70
|
+
while k < ITERS_PER_FRAME
|
|
71
|
+
i = rand(NUM_CITIES - 2) + 1
|
|
72
|
+
j = i + 1 + rand(NUM_CITIES - i - 1)
|
|
73
|
+
|
|
74
|
+
a = cities[tour[i - 1]]
|
|
75
|
+
b = cities[tour[i]]
|
|
76
|
+
c = cities[tour[j]]
|
|
77
|
+
d = cities[tour[(j + 1) % NUM_CITIES]]
|
|
78
|
+
|
|
79
|
+
old_d = Math.hypot(a[0] - b[0], a[1] - b[1]) + Math.hypot(c[0] - d[0], c[1] - d[1])
|
|
80
|
+
new_d = Math.hypot(a[0] - c[0], a[1] - c[1]) + Math.hypot(b[0] - d[0], b[1] - d[1])
|
|
81
|
+
delta = new_d - old_d
|
|
82
|
+
|
|
83
|
+
if delta < 0 || rand < Math.exp(-delta / temperature)
|
|
84
|
+
tour[i..j] = tour[i..j].reverse
|
|
85
|
+
total_length += delta
|
|
86
|
+
end
|
|
87
|
+
|
|
88
|
+
temperature *= COOLING
|
|
89
|
+
k += 1
|
|
90
|
+
end
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
# === Render ===
|
|
94
|
+
|
|
95
|
+
render do
|
|
96
|
+
pts = Array.new(NUM_CITIES + 1) { |k| cities[tour[k % NUM_CITIES]] }
|
|
97
|
+
Polyline.render(points: pts, color: '#22d3ee', stroke_width: 1.5)
|
|
98
|
+
|
|
99
|
+
cities.each do |cx, cy|
|
|
100
|
+
Circle.render(x: cx, y: cy, radius: 4, color: '#fde047')
|
|
101
|
+
end
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
show
|