画面外判定を作ってみた

こんな感じかなあ・・・。

class Sprite
  def on_screen?(range = nil)
    if range == nil
      if self.target == nil
        screen = [0, 0, Window.width, Window.height]
      else
        screen = [0, 0, self.target.width, self.target.height]
      end
    else
      screen = range
    end

    xary = [0, self.image.width, 0, self.image.width]
    yary = [0, 0, self.image.height, self.image.height]

    if self.angle != 0 or self.scale_x != 1.0 or self.scale_y != 1.0
      cos = Math.cos(self.angle / 180.0 * Math::PI)
      sin = Math.sin(self.angle / 180.0 * Math::PI)
      4.times do |i|
        tempx = ((xary[i] - self.center_x) * cos - (yary[i] - self.center_x) * sin) * scale_x + self.center_x
        tempy = ((xary[i] - self.center_x) * sin + (yary[i] - self.center_x) * cos) * scale_y + self.center_x
        xary[i] = tempx
        yary[i] = tempy
      end
    end
    return !(screen[0] >= xary.max+self.x or screen[1] >= yary.max+self.y or screen[2] <= xary.min+self.x or screen[3] <= yary.min+self.y)
  end
end

範囲は自動取得するが指定可能で、回転した場合を考慮していて、真面目に判定しない。4点すべてが上下左右のどれかに出た場合のみという判定なので、大きな画像が斜めになってカドぎりぎり見えないところにいると消えないが、レアケースじゃないかと思う。
あと、範囲指定でnilにした方向は判定しない、とかできるとよいかもしれない。
いずれにせよ、こんなもんRubyで動かしてたら無駄に重いわけで、ユーザがキャラごとに自前で書いたほうが圧倒的に速い。Cで書かなければならないコードだろう。RubyVMは速いから回転してない場合ではCで書いても速くなるかどうか怪しいレベルだ。Spriteクラスのクラスメソッドとして配列をまとめて処理するものも無いと存在意義が無いかもしれない。