Star RubyでDXRubyExtensionを使う
DXRubyExtensionは用途は色々になる予定だが、とりあえず衝突判定ロジックが詰め込まれている。
これはRuby汎用の拡張ライブラリだから、名前にはDXRubyと付いているしサンプルもDXRuby用だがDXRubyには依存しない。
はずだ。
論より証拠ということで、Star Rubyと一緒に使ってみた。
円が無いのはStar Rubyに円を描画する機能がなくて作るのが面倒だったからだ。
ソースはこんな感じで、ハッキリ言ってしまって、Star RubyとDXRuby間の移植はメソッド呼び出し部分を書き換えるだけだ。
これを統一したらほぼ同じソースになるんじゃね?ってぐらい。
とはいえお互い独特な機能があるから、そこまで単純な話ではないのだが。
でも使用感はやっぱ似てるな。
# DXRubyExtension0.0.5サンプル(StarRuby版) require "starruby" require "dxrubyex" include StarRuby # 衝突判定配列 # ここに判定オブジェクトをたくさん入れる $collisions = [] # 動くもの共通クラス class CollisionObject def initialize @x = rand(639-@image1.width) @y = rand(439-@image1.height) @hit = false @dx = (rand(4)*2-3)/2.0 @dy = (rand(4)*2-3)/2.0 end # キャラ移動と判定配列設定 def update @x += @dx @y += @dy @dx = -@dx if @x <= 0 or @x >= 639-@image1.width @dy = -@dy if @y <= 0 or @y >= 479-@image1.height # setメソッドで判定オブジェクトの位置を移動する @collision.set(@x, @y) # 配列にpush $collisions.push(@collision) @hit = false end def draw(game) if @hit then game.screen.render_texture(@image2, @x, @y) else game.screen.render_texture(@image1, @x, @y) end end # あたっていたらhitが呼ばれる def hit(d) @hit = true end end # しかく class Box < CollisionObject def initialize # 衝突判定オブジェクト作成。 # 第一引数のオブジェクトのhitメソッドが呼ばれる。 # 第二以降の引数は判定範囲の指定。原点はキャラの座標。 # setメソッドで移動させるから、判定範囲は変更する必要がない。 @collision = CollisionBox.new(self, 0, 0, 29, 29) @image1 = Texture.new(30, 30).fill(Color.new(200,0,0)) @image2 = Texture.new(30, 30).fill(Color.new(200,200,200)) super end end # さんかく class Triangle < CollisionObject def initialize # 三角は3点の座標を指定する。 @collision = CollisionTriangle.new(self, 20,0,0,39,39,39) @image1 = Texture.new(40, 40) @image2 = Texture.new(40, 40) for i in 0..39 @image1.render_line(20-i/2, i, 20+i/2, i, Color.new(0,200,0)) @image2.render_line(20-i/2, i, 20+i/2, i, Color.new(200,200,200)) end super end end font = Font.new("MS UI Gothic", 24) # 移動&描画するモノの配列。30個ずつ作る。 object = Array.new(30) {Box.new} + Array.new(30) {Triangle.new} # メインループ Game.run(640, 480, :fps=>60) do |game| # 移動&判定オブジェクトの配列へのpush object.each do |o| o.update end # マウスカーソルの座標をセットした点判定オブジェクト。 # 第一引数にnilを指定すると衝突通知が行われない。 mousecollision = CollisionPoint.new(nil) x, y = Input.mouse_location mousecollision.set(x, y) # マウスカーソルとオブジェクトの衝突判定。 # 単体の場合は配列である必要はない。 Collision.check(mousecollision, $collisions) # オブジェクト同士の衝突判定。 Collision.check($collisions, $collisions) # 判定配列をクリアする。 $collisions.clear # 描画 game.screen.clear object.each do |o| o.draw(game) end break if Input.keys(:keyboard).include?(:escape) game.screen.render_text(game.real_fps.to_s + " fps", 0, 0, font, Color.new(255,255,255)) end
あ、このサンプルコードはいつものようにパブリックドメインということで。