弾幕生成機能


必要な機能に絞って、BulletGeneratorとSpriteに分離させた。
とりあえずライブラリ側のコードをのっけると長すぎだから、ここではそれを利用するコードだけとしておく。だからそのままでは動かない。
調子に乗って弾を多くしすぎたのでちょっと重くなった。

require 'dxruby'
require 'bulletgenerator'
require 'sprite'

class Shot < Sprite
  @@image = Image.load("image/enemyshot1.png")
  @@command = [
    [:wait=, -1],
  ]

  def initialize(x, y, angle, speed)
    super(x-@@image.width/2, y-@@image.height/2, angle, speed, @@image, @@command)
  end
end

class BG_16way < BulletGenerator
  action1 = [
    [:fire_relative, Shot, 0, 5],
    [:rotation, 22.5],
  ]
  @@command = [
    [:call_command, action1, 16],
    [:wait=, 3],
    [:rotation, 12],
  ]
  def initialize(parent, x, y)
    super(Objects, parent, x, y, 0, @@command)
  end
end

class Enemy2 < Sprite
  @@image = Image.load("image/enemy2.png", 0, 0, 128, 64)
  @@command = [
    [:right, 100, 2],
    [:left, 100, 2]
  ]

  def initialize(x, y)
    Objects.push(BG_16way.new(self, 16, 48))
    Objects.push(BG_16way.new(self, 112, 48))
    super(x, y, 0, 0, @@image, @@command)
    @angle = 90
  end
end

Objects = []
Objects.push(Enemy2.new(200,100))

font = Font.new(32)

Window.loop do
  Objects.each do |obj| obj.update end
  Objects.delete_if do |obj| obj.delete end
  Objects.each do |obj| obj.draw end
  Window.drawFont(0, 0, Window.getLoad.to_i.to_s + " %", font, :z => 100.0)
  Window.drawFont(0, 32, Objects.size.to_s + " objects", font, :z => 100.0)
end

BulletGeneratorは弾を生成したときの格納先配列と親になるオブジェクト、座標、初期角度、コマンドを渡して生成する。親の角度とは別に自分で角度を持てるから、独自に回転しながら弾をばらまくことができる。
弾の角度が決めうちなら:file_absoluteとして絶対角度で打ち出すこともできる。
Spriteのほうには今後、アニメーションの機能などを搭載する必要がある。
アニメーションもコマンド列として扱うような、ぶっちゃけMyGameのアニメーション機能みたいなのがいいなーと思っている。あれは柔軟で便利だ。
移動コマンドとは非同期で動作し、移動コマンドからもRubyのコードからも切り替えができるのが望ましい。