Jewel-mmo開発日記

RubyでMMORPGを作る過程を記録する日記。 Yokohama.rb 発起人。
2006-04-09

Ruby/SDL を簡易ライブラリ化

(RDスタイルに戻した。日をまたがないと切り替わらないのでしかたなく明日のエントリに書いている)

よく使う処理をシンプルなインターフェースに簡略化するならどんな形がよいか。

なんとなくの全体イメージ。

game_init
game_loop do
  # 処理
  # 描画
end

スクリーン生成

game_init
screen = Screen.new(SCREEN_W, SCREEN_H)
#screen = create_screen(SCREEN_W, SCREEN_H)

画像表示

この画像表示をラップするとしたらどういうインターフェースにするか。

image = SDL::Surface.load('ball.bmp')
image = image.displayFormat
image.setColorKey SDL::SRCCOLORKEY, image.getPixel(0,0)

SDL.blitSurface image, 0, 0, 0, 0, screen, x, y

クラス版

もっとも自然。

image = Igame.new(screen, 'ball.bmp')
image.x = x
image.y = y
game_loop do
  image.draw
end

シンプルなラッパー版

思ったよりいいかも。非オブジェクト指向。

image = create_image('ball.bmp')
game_loop do
  draw_image screen, image, x, y
end

命令タイプ

毎回 SDL::Surface.load から作り直す。非現実的。

game_loop do
  draw_image screen, 'ball.bmp', x, y
end

いやキャッシュすればいいからオブジェクト指向を避けるならありか。なんか良く見えてきた。

これを使ってクラスを書くのもあり。

class Ball
  def initialize(screen, x=0, y=0)
    @screen = screen
    @x = x
    @y = y
  end

  def run
    @x += 1
  end

  def draw
    draw_image @screen, 'ball.bmp', @x, @y
  end
end

うん、いいかも。実際は initialize を基底クラスに分離かな。

game_init
screen = Screen.new(SCREEN_W, SCREEN_H)
balls = Array.new(10) { Ball.new(screen, rand(SCREEN_W), rand(SCREEN_H)) }
game_loop do
  balls.each do |ball|
    ball.run
    ball.draw
  end
end

これ balls の生成が複雑だなもっと単純化できないものか。

balls = []
10.times { balls << Ball.new(screen, rand(SCREEN_W), rand(SCREEN_H)) }

うーん。

balls = []
10.times do
  balls << Ball.new(screen, rand(SCREEN_W), rand(SCREEN_H))
end

うーん。

balls = (0...10).map { Ball.new(screen, rand(SCREEN_W), rand(SCREEN_H)) }

最初の Array.new(10) が良く見えてきた。

あと each って難しいよね。オレ自身ブロックつきメソッドを理解したの最近だし。

balls.size.times do |i|
  ball[i].run
  ball[i].draw
end

結局ブロックつきメソッドなんだけど。for は一回も書いたことないなあ。これでいいのかな。

for ball in balls
  ball.run
  ball.draw
end

for は Rails でしか見たことない。 times は最近はなんか変な感じするけど、最初のころはすごくなじみやすかった覚えがある。each は最初ぜんぜんわからなかったけどすぐに慣れた(使う分には)。 for は C と違いすぎてぜんぜんなじまなかった。あ、 C とか他の言語を知らない人には for はいいのかも。