物理エンジンを使う 7, 何かを大量に実体化してみる

-- 物理エンジンを使う 7, 何かを大量に実体化してみる
-- 一部だけクラス化する
 
require "physics"
W = platform.window:width()
H = platform.window:height()
dt = 0.01
gravity = 200
ZERO = physics.Vect(0, 0)
elasticity = 0
friction = 0

----------------
-- pBall class --
----------------
pBall = class()
function pBall:init(mass, radius, cx, cy) -- 初期化(質量, 半径, 重心座標 )
   self.mass    = mass
   self.radius  = radius
   self.cx      = cx
   self.cy      = cy
   self.inertia = physics.misc.momentForCircle(self.mass, 0, self.radius, ZERO)
   self.body = physics.Body(self.mass, self.inertia)
      :setVel(physics.Vect(ZERO))
      :setPos(physics.Vect(self.cx, self.cy))
      :setAngle(0)
   self.shape = physics.CircleShape(self.body, self.radius, ZERO)
      :setRestitution(elasticity)
      :setFriction(friction)
end
function pBall:paint(gc) -- 描画函数
   local pos = self.body:pos()
   local cx = pos:x()
   local cy = pos:y()
   local radius = self.shape:radius()
   gc:setColorRGB(0x71C671)
   gc:fillArc(cx - radius, cy - radius, radius + radius, radius + radius, 0, 360)
   --gc:setColorRGB(0x000000)
   --gc:drawArc(cx - radius, cy - radius, radius + radius, radius + radius, 0, 360)

   --local angle = self.body:angle()
   --local x2 = self.radius * math.cos(angle) + cx
   --local y2 = self.radius * math.sin(angle) + cy
   --gc:setColorRGB(0x000000)
   --gc:drawLine(cx, cy, x2, y2)
end

----------------
-- pFloor class --
----------------
pFloor   = class()
function pFloor:init(x1, y1, x2, y2) -- 初期化(座標 a, 座標 b)
   self.x1 = x1
   self.y1 = y1
   self.x2 = x2
   self.y2 = y2
   self.shape = physics.SegmentShape(nil, physics.Vect(self.x1, self.y1), physics.Vect(self.x2, self.y2), 2.5)
      :setRestitution(elasticity)
      :setFriction(friction)
end
function pFloor:paint(gc) -- 描画函数
   local avec = self.shape:a()
   local x1 = avec:x()
   local y1 = avec:y() 
   local bvec = self.shape:b()
   local x2 = bvec:x()
   local y2 = bvec:y()
   gc:setColorRGB(0x388E8E)
   gc:setPen("thick")
   gc:drawLine(x1, y1, x2, y2)
end

-- pBall クラスを実体化する
ball = {}
for i = 1, 1500 do
   table.insert(ball, pBall(0.00001, 2, W*(math.random(12,18)/100), H*(math.random(-900,-1)/100)))
end

-- pFloor クラスを実体化する
floor = {pFloor(20,100,60,200),pFloor(60,200,270,200),pFloor(270,200,250,100),pFloor(250,100,100,10)}

-- スペースに実体化するオブジェクトを全部リストに入れる。
objectList = {ball, floor} 

--スペースを実体化し、そのスペースへボディーとシェイプとを投入する。
space = physics.Space() 
   :setGravity(physics.Vect(0, gravity))
   for _, vi in ipairs(objectList) do
   for _, vj in ipairs(vi) do
      if vj.body then space:addBody(vj.body) end
      if vj.shape then space:addShape(vj.shape) end
   end
   end

function on.paint(gc)
   for _, vi in ipairs(objectList) do
   for _, vj in ipairs(vi) do
      vj:paint(gc)
   end
   end
end
function on.timer()
   space:step(dt)
   platform.window:invalidate()
end
function on.enterKey()
   timer.start(dt)
end