Subscribed unsubscribe Subscribe Subscribe

物理エンジンを使う 4, static な円に円をぶつける

chipmunk

-- 物理エンジンを使う 4, static な円に円をぶつける
require "physics"

W, H = platform.window:width(), platform.window:height()
ZERO = physics.Vect(0, 0)

dt      = 0.01   
gravity = 100
mass    = 1
radius  = W/30
inertia = physics.misc.momentForCircle(mass, 0, radius, ZERO)

elasticity = 0.9
friction   = 0.9

angle1 = 0
velX1, velY1 = 55.9, 0
posX1, posY1 = 0, 0
posX2, posY2 = W/3, H * 0.9

newBody1 = physics.Body(mass, inertia)
   :setVel(physics.Vect(velX1, velY1))
   :setPos(physics.Vect(posX1, posY1))
   :setAngle(angle1)

newShape1 = physics.CircleShape(newBody1, radius, ZERO) 
   :setRestitution(elasticity)
   :setFriction(friction)

newShape2 = physics.CircleShape(nil, radius, physics.Vect(posX2, posY2)) -- 関連付ける Body を nil にすると static な Shape ができる。Body がないのだから力の作用を受けない。衝突判定はする。
   :setRestitution(elasticity)
   :setFriction(friction)

space = physics.Space()
   :setGravity(physics.Vect(0, gravity))
   :addBody(newBody1)
   :addShape(newShape1) 
   :addStaticShape(newShape2) -- static な Shape を Space へ投入する。 

function on.paint(gc)
   fillCircleCenter(posX1, posY1, radius, angle1, 0x7171C6, gc)
   fillCircleCenter(posX2, posY2, radius, 0, 0x388E8E, gc)
end
function on.timer()
   space:step(dt)
   pos1  = newBody1:pos()
   posX1, posY1 = pos1:x(), pos1:y()
   angle1 = newBody1:angle()
   platform.window:invalidate()
end
function on.enterKey()
   timer.start(dt)
end

-----------------------
-- general functions --
-----------------------
function fillCircleCenter(cx, cy, radius, angle, color, gc)
   gc:setColorRGB(color)
   gc:fillArc(cx - radius, cy - radius, radius + radius, radius + radius, 0, 360)
   gc:setColorRGB(0x000000)
   gc:drawLine(cx, cy, cx + radius * math.sin(-angle), cy + radius  * math.cos(-angle)) -- 廻っているのがわかるように線を引く。
end
Remove all ads