WebSDL - Ruby/SDL × WebSocket/Canvas

投稿者 nanki 2010-06-23 02:42:00 GMT

Ruby勉強会@関西44の懇親会にて @cyross, @KazkiMatz さんらとSDLをWebSocketと組み合わせて…という話をしていておもしろそうだったので実装してみた。

websdl
青は@nanki, 赤は@ujm

github - WebSDL

  1. Ruby/SDLの画面描画を全て文字列としてシリアライズし、WebSocketで送信、Canvasに描画する。
  2. ブラウザ上で発生したイベントをWebSocketで送信、SDLのイベントモデルの中に還元してやる。

というのが基本的な仕組み。

# samples/sample1.rb
require 'rubygems'
gem 'rubysdl'
require 'sdl'
require 'websdl'

class TestFrame < Frame
  attr_reader :mx, :my, :color

  def initialize
    @color = 0xff000000 | (1..3).inject(0){|r,i|r << 8 | rand(0xff)}
    @mx = -100
    @my = -100
  end

  def open_screen
    SDL::Screen.open(640, 480, 32, SDL::HWSURFACE || SDL::DOUBLEBUF)
  end

  def mainloop(screen)
    screen.fill_rect(0, 0, screen.w, screen.h, 0)

    while event = SDL::Event.poll
      @mx, @my = event.x, event.y if SDL::Event::MouseMotion === event
    end

    frames.each do |f|
      screen.fill_rect(f.mx - 15, f.my - 15, 30, 30, f.color)
    end
    
    screen.flip
  end
end


SDL = WebSDL if ARGV.first == 'web'

SDL.init(SDL::INIT_VIDEO)
SDL.run(TestFrame, :host => '0.0.0.0', :port => 3000)

上記のようなコードで、

$ rsdl -Ilib samples/sample1.rb

ではSDLのウィンドウが起動し、

$ ruby -Ilib samples/sample1.rb web

でWebSDL版が起動するようになっている。 WebSDL版はsamples/test.html をWebSocket, Canvasに対応したブラウザで開く。

ただCanvasを使うだけでは芸が無いので、マルチユーザに対応、ユーザ間の情報共有にも対応してみた。

言うまでもなくProof of Conceptの段階であり、SDLの機能もdraw_rect, MouseMotion くらいしか実装していない。

また、0.1秒毎に更新しているのがかっこわるいが、適切なイベントに基づいた処理をすれば、パズルゲームやアドベンチャーゲームなど頻繁に画面更新のないものなら実用的なものができる可能性がある。 ウェブへぇボタンとかね。

問題点

一方、SDLのAPIは同期的なものもあり、SDL::Surface#get_pixel (画面上のピクセルの色を返す) などは現在の方法では実現が困難である。

参考:

This entry was posted on 2010-06-23 02:42:00 GMT and カテゴリ , , , , . You can follow any response to this entry through the Atom feed. or a trackback from your own site.

タグ , , , ,


トラックバック

トラックバックリンク:
http://blog.netswitch.jp/trackbacks?article_id=8665

コメント

  1. mattn 2010-06-23 15:31:14 GMT:

    chromeで見ると真っ白けになってます。 意図的だったらすみません。

  2. nanki 2010-06-25 00:47:44 GMT:

    あれ。Safariでしかチェックしてないのでありえます。