Upgrade to Pro — share decks privately, control downloads, hide ads and more …

ゼロからの、レトロゲームエンジンの作り方

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.
Avatar for tokujiros tokujiros
January 18, 2025

 ゼロからの、レトロゲームエンジンの作り方

東京Ruby会議12 で発表した資料です。

Avatar for tokujiros

tokujiros

January 18, 2025
Tweet

More Decks by tokujiros

Other Decks in Programming

Transcript

  1. ࣗݾ঺հ • ޷͖ͳݴޠ͸ Ruby ͱ C++ • ςΩετΤσΟλʔΛࣗ࡞ͨͯ͘͠ GUI πʔϧΩοτ͔

    Β࡞ͬͯͨΒ͍ͭͷؒʹ͔ήʔϜΤϯδϯΛ࡞ͬͯ·ͨ͠ • ࢓ࣄͰ͸લ͸ Android ͱ iOS ΞϓϦɺࠓ͸ Java Ͱ Spring Boot ॻ͍ͯ·͢  @tokujiros x.com/tokujiros github.com/xord
  2. ϨτϩήʔϜΤϯδϯͱ͸ ௿ղ૾౓άϥϑΟοΫͱϐίϐία΢ϯυ ϨτϩήʔϜಛԽͷπʔϧͱͯ͠ɺεϓϥΠτΤσΟλʔɺϚοϓΤ σΟλʔɺα΢ϯυΤσΟλʔɺϛϡʔδοΫΤσΟλʔͳͲΛ౥ࡌ ౷߹։ൃ؀ڥ ϓϩάϥϛϯάɺάϥϑΟοΫɺα΢ϯυͳͲΛҰͭͷ؀ڥͰ࡞੒Մೳ ϓϩάϥϛϯάͷ؆ུԽ Lua ΍ Python

    ͳͲͷεΫϦϓτݴޠͰήʔϜΛ࣮૷Մೳ ήʔϜ੍࡞ͷෑډ͕௿͍ ৭਺΍ղ૾౓ɺಉ࣌ൃԻ਺ͳͲ͕ҙਤతʹ੍ݶ͞Ε͍ͯΔͷͰήʔϜ σβΠϯͦͷ΋ͷʹूதͰ͖ɺήʔϜΛ࡞Γ࢝Ί΍͘͢׬੒ͤ͞΍͢ ͍ 
  3. ϨτϩήʔϜΤϯδϯ Reight ͷ঺հ Ruby Ͱ࣮૷ͨ͠ϨτϩήʔϜΤϯδϯ Ruby ͷ R ͱ PICO-8

    ͷ 8 Ͱ R8 ͔͠͠ R8 ͩͱݕࡧੑ͕ѱ͍ͷͰ Reight ʹ Ruby ΞιγΤʔγϣϯ։ൃॿ੒ۚʹ࠾୒͍͍ͨͩͯ։ൃத → https://www.ruby.or.jp/ja/news/20241030 
  4. ϨτϩήʔϜΤϯδϯ Reight ͷ঺հ ήʔϜͷίʔυΛ Ruby Ͱॻ͚Δ άϥϑΟοΫεͷ API ͸ Processing

    Λ࠾༻ ֤छΤσΟλʔΛ౥ࡌͨ͠౷߹։ൃ؀ڥ εϓϥΠτΤσΟλʔ ϚοϓΤσΟλʔ α΢ϯυΤσΟλʔʢ༧ఆʣ ϛϡʔδοΫΤσΟλʔʢ༧ఆʣ ςΩετΤσΟλʔ͸ࠓͷͱ͜Ζ֎෦ςΩετΤσΟλʔར༻Λ૝ఆ কདྷతʹ͸ςΩετΤσΟλʔ΋౥ࡌ͍ͨ͠ 
  5. Reight ͷ࢖͍ํ MacɺWindows Ͱ͸ “gem install reight” ͰΠϯετʔϧՄೳʢ˞ʣ $ gem

    install reight Fetching reflexion-0.3.2.gem Fetching xot-0.3.2.gem Fetching rays-0.3.2.gem Fetching rucy-0.3.2.gem Fetching beeps-0.3.2.gem Fetching rubysketch-0.7.2.gem Fetching processing-1.1.2.gem Building native extensions. This could take a while... Successfully installed xot-0.3.2 Building native extensions. This could take a while... Successfully installed rucy-0.3.2 Building native extensions. This could take a while... Successfully installed rays-0.3.2 Building native extensions. This could take a while... Successfully installed beeps-0.3.2 Building native extensions. This could take a while... Successfully installed reflexion-0.3.2 Successfully installed processing-1.1.2 Successfully installed rubysketch-0.7.2 Successfully installed reight-0.1 Parsing documentation for xot-0.3.2 Installing ri documentation for xot-0.3.2 Parsing documentation for rucy-0.3.2 Installing ri documentation for rucy-0.3.2 Parsing documentation for rays-0.3.2 Installing ri documentation for rays-0.3.2 Parsing documentation for beeps-0.3.2 Installing ri documentation for beeps-0.3.2 Parsing documentation for reflexion-0.3.2 Installing ri documentation for reflexion-0.3.2 Parsing documentation for processing-1.1.2 Installing ri documentation for processing-1.1.2 Parsing documentation for rubysketch-0.7.2 Installing ri documentation for rubysketch-0.7.2 Parsing documentation for reight-0.1 Done installing documentation for xot, rucy, rays, beeps, reflexion, processing, rubysketch, reight after 0 seconds 8 gems installed • Mac • Xcode ͷΠϯετʔϧ͕ඞཁ • Windows • ݱ࣌఺Ͱ͸ RubyInstaller+DevKit ͷΈαϙʔτ • ͞Βʹ pacman Ͱ glewɺopenal ͷΠϯετʔϧ͕ඞཁ ˞ 
  6. Reight ͷ࢖͍ํ “r8" ίϚϯυʹσΟϨΫτϦΛࢦఆͯ͠ىಈ ֎෦ΤσΟλʔͰ game.rb Λฤू  $ mkdir

    mygame $ cd mygame $ r8 . & $ emacs game.rb ... $ ls chips.json chips.png game.rb maps.json project.json
  7. ϨτϩήʔϜΤϯδϯͷٕज़ελοΫ 1.OpenGL ந৅ԽϨΠϠʔ → https://github.com/xord/rays 2.GUI πʔϧΩοτ → https://github.com/xord/re fl

    ex 3.Processing ޓ׵ API ϨΠϠʔ → https://github.com/xord/processing 4.ʢඇϨτϩʣ2DήʔϜϥΠϒϥϦʔ → https://github.com/xord/rubysketch 5.ΦʔσΟΦॲཧϥΠϒϥϦʔ → https://github.com/xord/beeps  https://discord.gg/C847WppZeT
  8. ϨτϩήʔϜΤϯδϯͷٕज़ελοΫ 1.OpenGL ந৅ԽϨΠϠʔ → https://github.com/xord/rays 2.GUI πʔϧΩοτ → https://github.com/xord/re fl

    ex 3.Processing ޓ׵ API ϨΠϠʔ → https://github.com/xord/processing 4.ʢඇϨτϩʣ2DήʔϜϥΠϒϥϦʔ → https://github.com/xord/rubysketch 5.ΦʔσΟΦॲཧϥΠϒϥϦʔ → https://github.com/xord/beeps  https://discord.gg/C847WppZeT
  9. 1. OpenGL ந৅ԽϨΠϠʔ OpenGL Λந৅Խͯ͠ Ruby Β͍͠ API ʹͯ͠ఏڙ ࠓޙ༨༟͕Ͱ͖ͨΒ

    VulkanɺMetal ͳͲʹ΋ରԠ͍ͨ͠ PainterɺImageɺFontɺPolygonɺPolylineɺShader ΫϥεͳͲ Ruby ͔Β Painter Ϋϥεܦ༝Ͱ OpenGL ͷඳը API Λݺͼग़͠ line()ɺrect()ɺellipse()ɺcurve()ɺimage()ɺtext()ɺ fi ll()ɺstroke()ɺ matrix() ͳͲ  https://discord.gg/C847WppZeT
  10. 1. OpenGL ந৅ԽϨΠϠʔ # ը૾ΦϒδΣΫτΛੜ੒ img = Rays::Image.new(256, 256) #

    ը૾ΦϒδΣΫτΛ Painter ΦϒδΣΫτͰඳը͢Δ img.paint do |painter| # എܠΛനͰΫϦΞ painter.background(1, 1, 1) # ੺ͰۣܗΛඳը painter.fill(1, 0, 0) painter.rect(10, 10, 100, 100) # ྘ͰؙΛඳը painter.fill(0, 1, 0) painter.ellipse(100, 100, 100, 100) end # ը૾ΛϑΝΠϧʹอଘ img.save(‘sample.png’)  TBNQMFQOH https://discord.gg/C847WppZeT
  11. ϨτϩήʔϜΤϯδϯͷٕज़ελοΫ 1.OpenGL ந৅ԽϨΠϠʔ → https://github.com/xord/rays 2.GUI πʔϧΩοτ → https://github.com/xord/re fl

    ex 3.Processing ޓ׵ API ϨΠϠʔ → https://github.com/xord/processing 4.ʢඇϨτϩʣ2DήʔϜϥΠϒϥϦʔ → https://github.com/xord/rubysketch 5.ΦʔσΟΦॲཧϥΠϒϥϦʔ → https://github.com/xord/beeps  https://discord.gg/C847WppZeT
  12. 2. GUI πʔϧΩοτ WindowɺView ΫϥεͳͲ View#on_draw Ͱ OpenGL ந৅ԽϨΠϠʔΛར༻ ֤

    OS ωΠςΟϒͷ API Ͱ࣮૷ ࠓͷͱ͜Ζ macOS(AppKit)ɺiOS(UIKit)ɺWindows(Win32) ʹରԠ ࠓޙ༨༟͕͋Ε͹ LinuxɺAndroid ʹ΋ରԠ͍ͨ͠ ෺ཧԋࢉϥΠϒϥϦʔͷ Box2D ΋૊ΈࠐΈ ॏྗΛઃఆͨ͠Γɺݸʑͷ View ΦϒδΣΫτʹ൓ൃ܎਺Λ෇͚ͨΓ  https://discord.gg/C847WppZeT
  13. 2. GUI πʔϧΩοτ w = Reflex::Window.new # ΢Οϯυ΢ΦϒδΣΫτΛੜ੒ w.width =

    256 # ΢Οϯυ΢ͷ෯Λઃఆ w.height = 256 # ΢Οϯυ΢ͷߴ͞Λઃఆ w.title = 'Hello, world!’ # ΢Οϯυ΢ͷλΠτϧΛઃఆ v = Reflex::View.new # ϏϡʔΦϒδΣΫτΛੜ੒ def v.on_draw(e) # ಺෦ͷඳըॲཧΛఆٛ # ΠϕϯτͰఏڙ͞ΕΔ Painter ΦϒδΣΫτͰඳը e.painter.background(1, 1, 1) e.painter.fill(1, 0, 0) e.painter.rect(10, 10, 100, 100) e.painter.fill(0, 1, 0) e.painter.ellipse(100, 100, 100, 100) end w.add(v) # ϏϡʔΦϒδΣΫτΛ΢Οϯυ΢ʹ௥Ճ w.show # ΢Οϯυ΢Λදࣔ  8JOEPXT NBD04
  14. ϨτϩήʔϜΤϯδϯͷٕज़ελοΫ 1.OpenGL ந৅ԽϨΠϠʔ → https://github.com/xord/rays 2.GUI πʔϧΩοτ → https://github.com/xord/re fl

    ex 3.Processing ޓ׵ API ϨΠϠʔ → https://github.com/xord/processing 4.ʢඇϨτϩʣ2DήʔϜϥΠϒϥϦʔ → https://github.com/xord/rubysketch 5.ΦʔσΟΦॲཧϥΠϒϥϦʔ → https://github.com/xord/beeps  https://discord.gg/C847WppZeT
  15. 3. Processing ޓ׵ API ϨΠϠʔ Creative Coding ϑϨʔϜϫʔΫͱͯ͠༗໊ͳ Processing ͱಉ͡ػೳΛఏڙ

    OpenGL ந৅ԽϨΠϠʔͷϥούʔϥΠϒϥϦʔ 2023೥౓ͷ Ruby ΞιγΤʔγϣϯ։ൃॿ੒ۚʹ࠾୒͞Ε։ൃ rubygems.org/gems/processing Ͱެ։த ϨτϩήʔϜΤϯδϯͱͯ͠ Processing API ͰήʔϜΛ࣮૷͢Δ͜ͱ͕Ͱ͖Δ Processing ͷྑ͍ͱ͜Ζ͸΢Σϒ্ͷ৘ใ͕྆ଟ͍ͱ͜Ζ  https://discord.gg/C847WppZeT
  16. 3. Processing ޓ׵ API ϨΠϠʔ setup do # ىಈ࣌ʹҰ౓͚ͩݺ͹ΕΔ size(256,

    256) # ΢Οϯυ΢ͷαΠζΛࢦఆ setTitle('Hello, world!’) # ΢Οϯυ΢ͷλΠτϧΛઃఆ ellipseMode(CORNER) # ପԁͷ࠲ඪ͸ࠨ্Λࢦఆ͢ΔϞʔυʹ end draw do # ຖඵ60ճݺ͹ΕΔ # എܠΛനͰΫϦΞ background(255) # ੺͍ۣܗΛඳը fill(255, 0, 0) rect(10, 10, 100, 100) # ྘ͷؙΛඳը fill(0, 255, 0) ellipse(100, 100, 100, 100) end  https://discord.gg/C847WppZeT
  17. ϨτϩήʔϜΤϯδϯͷٕज़ελοΫ 1.OpenGL ந৅ԽϨΠϠʔ → https://github.com/xord/rays 2.GUI πʔϧΩοτ → https://github.com/xord/re fl

    ex 3.Processing ޓ׵ API ϨΠϠʔ → https://github.com/xord/processing 4.ʢඇϨτϩʣ2DήʔϜϥΠϒϥϦʔ → https://github.com/xord/rubysketch 5.ΦʔσΟΦॲཧϥΠϒϥϦʔ → https://github.com/xord/beeps  https://discord.gg/C847WppZeT
  18. 4. ʢඇϨτϩʣ2DήʔϜϥΠϒϥϦʔ sprites = [] # ஍໘ΦϒδΣΫτΛੜ੒ ground = createSprite

    0, height - 10, width, 10 setup do gravity(0, 1000) # ॏྗΛઃఆ end draw do background 100 sprite(*sprites, ground) # ΫϦοΫͰੜ੒ͨ͠εϓϥΠτͱ஍໘Λඳը end # Ϛ΢ε͕ΫϦοΫ͞ΕͨΒݺ͹ΕΔ mousePressed do x, y = mouseX, mouseY # Ϛ΢εͷ࠲ඪΛऔಘ sp = createSprite(x, y, 50, 50) # εϓϥΠτΛੜ੒ sp.dynamic = true # ෺ཧԋࢉͷର৅ʹ͢Δ sprites << sp end  https://discord.gg/C847WppZeT
  19. ϨτϩήʔϜΤϯδϯͷٕज़ελοΫ 1.OpenGL ந৅ԽϨΠϠʔ → https://github.com/xord/rays 2.GUI πʔϧΩοτ → https://github.com/xord/re fl

    ex 3.Processing ޓ׵ API ϨΠϠʔ → https://github.com/xord/processing 4.ʢඇϨτϩʣ2DήʔϜϥΠϒϥϦʔ → https://github.com/xord/rubysketch 5.ΦʔσΟΦॲཧϥΠϒϥϦʔ → https://github.com/xord/beeps  https://discord.gg/C847WppZeT
  20. 5. ΦʔσΟΦॲཧϥΠϒϥϦʔ OpenAL Ͱα΢ϯυΛ࠶ੜ Synthesis Tool Kit Λ૊ΈࠐΈ OscillatorɺEnvelope ͳͲͷԻ੠৴߸ॲཧ

    Λ࣮૷ ͦͷଞ͍͔ͭ͘֎෦ϥΠϒϥϦΛར༻ͯ͠λΠϜετϨονɺϐονม ׵ɺαϯϓϦϯάϨʔτม׵ͳͲ΋ Sequencer ΫϥεΛར༻ͯ͠ɺα΢ϯυͱϛϡʔδοΫΤσΟλʔΛ࣮ ૷༧ఆ  https://discord.gg/C847WppZeT
  21. 5. ΦʔσΟΦॲཧϥΠϒϥϦʔ # γʔέϯαʔΦϒδΣΫτΛੜ੒ seq = Sequencer.new # ΦγϨʔλʔͰɺࢦఆͷप೾਺ͷαΠϯ೾Λੜ੒ seq.add

    Oscillator.new(freq: 261.626), 0.0, 0.1 # 0.0ඵޙʹ0.1ඵؒɺυͷԻΛ໐Β͢ seq.add Oscillator.new(freq: 293.665), 0.1, 0.1 # 0.1ඵޙʹ0.1ඵؒɺϨ seq.add Oscillator.new(freq: 329.628), 0.2, 0.1 # 0.2ඵޙʹ0.1ඵؒɺϛ seq.add Oscillator.new(freq: 349.228), 0.3, 0.1 # 0.3ඵޙʹ0.1ඵؒɺϑΝ seq.add Oscillator.new(freq: 391.995), 0.4, 0.1 # 0.4ඵޙʹ0.1ඵؒɺι seq.add Oscillator.new(freq: 440.000), 0.5, 0.1 # 0.5ඵޙʹ0.1ඵؒɺϥ seq.add Oscillator.new(freq: 493.883), 0.6, 0.1 # 0.6ඵޙʹ0.1ඵؒɺγ seq.add Oscillator.new(freq: 523.251), 0.7, 0.1 # 0.7ඵޙʹ0.1ඵؒɺυ # γʔέϯαʔΦϒδΣΫτ͕ੜ੒͢Δ೾ܗσʔλͰα΢ϯυΦϒδΣΫτΛੜ੒ snd = Sound.new(seq, 1) # α΢ϯυΛ࠶ੜ snd.play  https://discord.gg/C847WppZeT 0TDJMMBUPSΛͦͷ··໐Β͍ͯ͠ΔͷͰϊΠζʢΫϦοΫԻʣ ͕͋Γ·͢ͷͰɺ&OWFMPQFΛೖΕΔ͜ͱͰվળ͠·͢
  22. 5. ΦʔσΟΦॲཧϥΠϒϥϦʔ class MMLCompiler def compile(str) scanner = StringScanner.new str.gsub(/;.*\n/,

    '') seq = B::Sequencer.new bpm = 120 time = 0 tone = 0 octave = 4 length = 4 velocity = 127 scanner.skip /\s*/ until scanner.empty? case when scanner.scan(/T\s*(\d+)/i) bpm = scanner[1].to_i when scanner.scan(/O\s*(\d+)/i) octave = scanner[1].to_i when scanner.scan(/L\s*(\d+)/i) length = scanner[1].to_i when scanner.scan(/V\s*(\d+)/i) velocity = scanner[1].to_i when scanner.scan(/R\s*(\d+)?/i) time += seconds scanner[1]&.to_i || length, bpm when scanner.scan(/@\s*(\d+)/) tone = scanner[1].to_i when scanner.scan(/([<>])/) case scanner[1] when '<' then octave -= 1 when '>' then octave += 1 end when scanner.scan(/([CDEFGAB])\s*([#+-]+)?\s*(\d+)?\s*(\.+)?/i)&.chomp char, offset, len, dots = [1, 2, 3, 4].map {scanner[_1]} freq = frequency(char, offset, octave) or next sec = seconds len&.to_i || length, bpm sec *= 1 + dots.size.times.map {0.5 / (_1 + 1)}.sum if dots osc = B::Oscillator.new TONES[tone], freq: freq env = B::Envelope.new {note_on; note_off (sec - 0.01).clamp(0.01..)} gain = B::Gain.new gain: velocity.clamp(0, 127) / 127.0 * 0.5 seq.add osc >> env >> gain, time, sec time += sec else raise "Unknown input: #{scanner.rest[..10]}" end scanner.skip /\s*/ end seq end private TONES = [:sine, :triangle, :square, :sawtooth] DISTANCES = -> { notes = 'c_d_ef_g_a_b'.each_char.with_index.reject {|c,| c == '_'}.to_a octaves = (0..11).to_a octaves.product(notes) .map.with_object({}) {|(octave, (note, index)), hash| hash[[note, octave]] = octave * 12 + index - 57 } }.call def frequency(note, offset, octave) raise "Bad note: '#{note}'" unless note =~ /[cdefgab]/i distance = DISTANCES[[note.downcase, octave]] distance += (offset || '').each_char.reduce(0) {|value, char| case char when '+', '#' then value + 1 when '-' then value - 1 else value end } 440 * (2 ** (distance.to_f / 12)) end def seconds(length, bpm) 60.0 / bpm / length end end  ؆қ..-ίϯύΠϥʔ # Ϛ΢ε͕ΫϦοΫ͞ΕͨΒݺ͹ΕΔ mousePressed do # ΫϦοΫ͕Θ͔ΔΑ͏ʹؙΛඳը circle mouseX, mouseY, 50 # 2ͭͷ MML ΛίϯύΠϧͯ͠ Sequencer ΦϒδΣΫτΛ2ͭੜ੒ seq1 = MMLCompiler.new.compile '@1 ffffre-rgrf1' seq2 = MMLCompiler.new.compile '@1 c<bb-argrb-ra1' # 2ͭͷ Sequencer ΦϒδΣΫτΛಉ࣌ʹ໐Β͢ B::Sound.new(seq1, 3).play B::Sound.new(seq2, 3).play end https://discord.gg/C847WppZeT IUUQTHJTUHJUIVCDPNYPSEEDEBGFG
  23. ήʔϜશମ͸ Processing ϕʔεͰ࣮૷ ॏྗͷॲཧ΍িಥ൑ఆ͸ɺඇϨτϩͷ2DήʔϜϥΠ ϒϥϦʔͷεϓϥΠτͱ෺ཧԋࢉͰ؆୯ʹ࣮૷Մೳ ήʔϜ಺ͷα΢ϯυ΋ࣄલʹΦʔσΟΦσʔλԽ͠ ࠶ੜʢ༧ఆʣ GUI πʔϧΩοτͰ΢Οϯυ΢දࣔ ΢Οϯυ΢಺෦͸

    OpenGL ந৅ԽϨΠϠʔͰඳը ϨτϩήʔϜΤϯδϯͷ࡞Γํ  ground = createSprite 0, height - 10, width, 10 sprites = [] setup do gravity(0, 1000) end draw do background 100 sprite(*sprites, ground) end mousePressed do sp = createSprite(mouseX, mouseY, 50, 50) sp.dynamic = true sprites << sp end https://discord.gg/C847WppZeT
  24. macOS / iOS ΞϓϦԽ Reight ϨτϩήʔϜΤϯδϯࣗମΛΞϓϦԽ macOS ΍ iOS ͷ

    AppStore Ͱ഑෍͍ͨ͠ CRuby ΠϯλʔϓϦλʔ΋૊ΈࠐΉʢ˞ʣͷͰɺΞϓϦΛΠϯετʔϧ ͢Δ͚ͩͰϨτϩήʔϜ։ൃ؀ڥ͕੔͏ Ruby ͷॲཧܥΛ༻ҙͯ͠ gem install reight ͢ΔΑΓ΋खܰ  ˞ʣ$3VCZΠϯλʔϓϦλʔ૊ΈࠐΈͷ$PDPB1PE ˠIUUQTHJUIVCDPNYPSEDSVCZ https://discord.gg/C847WppZeT
  25. ϨτϩήʔϜΤϯδϯͰ࡞ͬͨήʔϜΛެ։ ήʔϜΛΞϓϦԽ֤ͯ͠ετΞʹެ։Ͱ͖ΔΑ͏ʹ͍ͨ͠ macOS ΞϓϦԽ iOS ΞϓϦԽ RubySolitaire ͱ͍͏ɺಉٕ͡ज़ελοΫͰ࡞ͬͨήʔϜΛ AppStore Ͱެ։த

    ༗ྉΞϓϦ΍޿ࠂɺ՝ۚʹ΋ରԠ͢ΔͷͰϚωλΠζ΋Մೳ Steam ͰͷϦϦʔε΋ ήʔϜΛ΢ΣϒͰެ։ WebAssembly (WASM) ʹରԠ͠ɺϒϥ΢βʔ্Ͱಈ͔͢ ϦϯΫΛڞ༗͢Δ͚ͩͰखܰʹଞਓʹ༡ΜͰ΋Β͑Δ  https://discord.gg/C847WppZeT
  26. ࢀߟϦϯΫ 2023 ೥౓ Ruby ΞιγΤʔγϣϯ։ൃॿ੒ۚ ࠷ऴใࠂʢ2024ʣ https://gist.github.com/xord/c464669d41f37f4858a193c658e9a705 Processing ϕʔεͷ2DήʔϜΤϯδϯ for

    CRuby ͷ঺հʢ2023ʣ https://zenn.dev/tokujiros/articles/7f0b44a6b7e2a6 ࣗલ Processing ࣮૷ͷޓ׵ੑݕূʹ p5.rb Λ࢖ͬͯΈͨ࿩ʢ2023ʣ https://zenn.dev/tokujiros/articles/973815bce7afdc 3ϲ݄ؒͷϑϧλΠϜݸਓ։ൃΛऴ͑ͯɻʢͦͯࣾ͠ձ෮ؼ΁ɾɾɾ ʢ2023ʣ https://note.com/tokujiros/n/ndb4bc589ef8f RubySketch ήʔϜΤϯδϯԽܭը ʙ ෺ཧԋࢉ෇͖εϓϥΠτΫϥεͷ ௥ՃͳͲʢ2022ʣ https://zenn.dev/tokujiros/articles/647d1f6df2b342 Ruby Ͱ Processing ͢Δ gemʢͱΞϓϦʣͷ঺հʢ2020ʣ https://zenn.dev/tokujiros/articles/96f63899760cb0 iPhone ͷʮΧϝϥೖྗʯͰ͓΋͠ΖϏσΦΧϝϥΛ࡞Ζ͏ʢ2020ʣ https://zenn.dev/tokujiros/articles/09988fc99b636c CRuby ͰήʔϜΛ࡞ͬͯ iPhone Ͱಈ͔ͦ͏ʢ2015ʣ https://qiita.com/tokujiros/items/0c4bd2dd995f0e6740b5 Ruby ༻ࣗ࡞ GUI πʔϧΩοτʹ Box2D Λ૊ΈࠐΜͩΒϒϩοΫ่͠ ήʔϜ͕؆୯ʹ࡞Εͨ࿩ʢ2014ʣ https://qiita.com/tokujiros/items/a9e8d16c2a4c1ccf2238 CRuby ΠϯλϓϦλͷ CocoaPod Λ࡞ͬͨͷͰ঺հ͠·͢ʢ2014ʣ https://qiita.com/tokujiros/items/30e9d0cf6236cd8e303d  https://discord.gg/C847WppZeT
  27. Textbringer ͷ૊ΈࠐΈ Ruby Ͱ࣮૷͞Εͨ Textbringer ͱ͍͏ςΩετΤσΟλʔ͕͋Δ Textbringer ͸ը໘දࣔͱΩʔೖྗʹ Curses ϥΠϒϥϦʔΛར༻͍ͯ͠Δ

    Textbringer ͷ Curses ར༻෦෼Λࠩ͠ସ͑Ε͹ GUI ΞϓϦԽͰ͖ΔͷͰ͸ʁ ͱ͍͏ࢥ͍͖ͭ Textbringer ͕ར༻͍ͯ͠Δ࠷௿ݶͷ Curses Λ GUI πʔϧΩοτͰ࠶ݱ͠ ͨΒಈ͍ͨ → https://x.com/tokujiros/status/1841538130148786677 ϨτϩήʔϜΤϯδϯͷςΩετΤσΟλʔͱͯ͠ Textbringer Λ૊ΈࠐΊΔ ͷͰ͸ʁ ೔ຊޠೖྗपΓ͕େมͦ͏Ͱ͸͋Δ͕ɾɾɾ  https://discord.gg/C847WppZeT