物理エンジンを使う 5, 力の作用を受けない床壁を Segment で作る

-- 物理エンジンを使う 5, 力の作用を受けない床壁を Segment で作る
require "physics"

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

dt      = 0.01   
gravity = 100

circleRadius = 45
circleMass   = 1

elasticity = 0.8
friction   = 0.8

leftX,  leftY  = W * 0.2, H * 0.7 -- 床左端の座標
rightX, rightY = W * 0.8, H * 0.4 -- 床右端の座標

velX2, velY2 = 79, -175
posX2, posY2 = 0,   H * 0.7
angle2       = 0

-- SegmentShape の引数は(body, 端部座標 a, 端部座標 b, 半径)。
newShape1 = physics.SegmentShape(nil, physics.Vect(leftX, leftY), physics.Vect(rightX, rightY), 0) 
   :setRestitution(elasticity)
   :setFriction(friction)

newBody2 = physics.Body(circleMass, physics.misc.momentForCircle(circleMass, 0, circleRadius, ZERO))
   :setVel(physics.Vect(velX2, velY2))
   :setPos(physics.Vect(posX2, posY2))
   :setAngle(angle2)
newShape2 = physics.CircleShape(newBody2, circleRadius, ZERO) 
   :setRestitution(elasticity)
   :setFriction(friction)

space = physics.Space()
   :setGravity(physics.Vect(0, gravity))
   
   :addStaticShape(newShape1)
   
   :addBody(newBody2)
   :addShape(newShape2)

function on.paint(gc)
   gc:setColorRGB(0x8E8E38)
   gc:drawPolyLine({leftX, leftY, rightX, rightY})
   fillCircleCenter(posX2, posY2, circleRadius, angle2, 0x71C671, gc)
end
function on.timer()
   space:step(dt)

   pos2 = newBody2:pos()
   posX2, posY2 = pos2:x(), pos2:y()

   angle2 = newBody2: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.cos(angle), cy + radius  * math.sin(angle))
end