とりあえず動いた花火。

星の数が多いので非常に重い。多いといっても460ほどなのだが。

軽くする努力を、と言っても、計算自体はすでにほぼ最小だからして、たとえばz値の計算は不要だから省いたとしてもせいぜい1割か2割ぐらいしか変わらないだろう。

数の多い点を描画するにはImageをたくさん描画するより、大きなImageに色を書き込んだほうが速くなる場合がある。
サンプルのdot.rbなどまさにその例だ。
そうすると画面をクリアするために膨大な処理時間を食われるため、画面サイズや点の大きななど、いろんなところを調整しなければいけない。
まあ、なんしか今の状態では複数飛ばすとか、芯を増やすとか、ぜんぜん無理なので、いろいろと試してみることにする。

require 'dxruby'

class Hoshi
  attr_accessor :x, :y, :dx, :dy, :dz
  def initialize(dx, dy, dz)
    @x = 320
    @y = 100
    @z = 0
    @dx = dx
    @dy = dy
    @dz = dz
  end

  def rotation (x, y, z)
    x += rand(3) - 1
    y += rand(3) - 1
    z += rand(3) - 1

    ax = x * TO_RADIAN
    ay = y * TO_RADIAN
    az = z * TO_RADIAN
    x = Math.cos(az) * @dx - Math.sin(az) * @dy
    y = Math.sin(az) * @dx + Math.cos(az) * @dy
    @dx = x;
    @dy = y;
    z = Math.cos(ax) * @dz - Math.sin(ax) * @dy
    y = Math.sin(ax) * @dz + Math.cos(ax) * @dy
    @dz = z;
    @dy = y;
    x = Math.cos(ay) * @dx - Math.sin(ay) * @dz
    z = Math.sin(ay) * @dx + Math.cos(ay) * @dz
    @dx = x;
    @dz = z;
    @dx = @dx / 160.0
    @dy = @dy / 160.0
    @dz = @dz / 160.0
  end

  def update
    @x += @dx
    @y += @dy
    @z += @dz
    @dx *= 0.99
    @dy *= 0.99
    @dz *= 0.99
    @dy += 0.01
  end
end

TO_RADIAN = Math::PI / 180

hoshi_r = 26
tama_r = 160
hoshi_da = 360.0 / ((tama_r * 2 * Math::PI) / hoshi_r)

z = 90.0

hoshi = []

hoshi.push(Hoshi.new(0.0, 160.0, 0.0))

loop do
  z = z - hoshi_da
  break if z < 0

  # 次の高さを求める
  y = Math.sin(z * TO_RADIAN) * tama_r

  # 半径を求める
  x = Math.cos(z * TO_RADIAN) * tama_r

  # 円周を求める
  syu = x * 2 * Math::PI

  kazu = (syu / hoshi_r).to_i

  da = 360.0 / kazu
  for i in 0...kazu
    hoshi.push(Hoshi.new(Math.cos((i * da) * TO_RADIAN) * x, y+rand(3)-1, Math.sin((i * da) * TO_RADIAN) * x))
  end
end

hoshi += hoshi.map {|h|
  Hoshi.new(h.dx, -h.dy, h.dz)
}

# 回転させる
x = rand(360)
y = rand(360)
z = rand(360)
hoshi.each do |h|
  h.rotation(x, y, z)
end

image = Image.new(640, 480)
hoshi_image = Image.new(2,2,[255,255,255])
alpha = 255

font = Font.new(32)

Window.loop do
  alpha -= 1
  hoshi = [] if alpha < 0
  hoshi.each do |h|
    h.update
    Window.drawAlpha(h.x, h.y, hoshi_image, alpha)
  end

  break if Input.keyPush?(K_ESCAPE)
  Window.drawFont(0,0,Window.getLoad.to_i.to_s, font)
end