singe/testScripts/scene9.singe
2026-09-05 19:52:04 -05:00

94 lines
2.9 KiB
Text

-- Physics stage 2: a stack of crates and a ball dropped onto the floor in front of the cabinet,
-- then a kinematic paddle sweeps through the stack.
local font = fontLoad("Singe/FreeSansBold.ttf", 28)
local frames = 0
fontSelect(font)
discPlay()
sceneEnable(true)
sceneSetBackground(18, 18, 30, 255)
sceneSetAmbient(70, 70, 85)
local floorLook = materialNew()
materialSetColor(floorLook, 120, 110, 100)
materialSetRoughness(floorLook, 0.9)
local crateLook = materialNew()
materialSetColor(crateLook, 200, 140, 60)
materialSetRoughness(crateLook, 0.7)
local ballLook = materialNew()
materialSetColor(ballLook, 60, 140, 230)
materialSetRoughness(ballLook, 0.3)
local paddleLook = materialNew()
materialSetColor(paddleLook, 230, 60, 40)
local screen = materialNew()
materialSetVideo(screen)
materialSetUnlit(screen, true)
local black = materialNew()
materialSetColor(black, 25, 25, 28)
local floor = nodeNew()
nodeSetMesh(floor, meshBox(14, 0.2, 14), floorLook)
nodeSetPosition(floor, 0, -1.9, 0)
bodyNew(floor, BODY_STATIC, SHAPE_BOX, 14, 0.2, 14)
-- A slab of a cabinet at the back with the disc on it, as a static body.
local cabinet = nodeNew()
nodeSetMesh(cabinet, meshBox(2.2, 3.0, 0.8), black)
nodeSetPosition(cabinet, 0, -0.3, -2.5)
bodyNew(cabinet, BODY_STATIC, SHAPE_BOX, 2.2, 3.0, 0.8)
local tv = nodeNew(cabinet)
nodeSetMesh(tv, meshPlane(1.8, 1.35), screen)
nodeSetPosition(tv, 0, 0.5, 0.41)
nodeSetRotation(tv, 90, 0, 0)
local crates = {}
for i = 1, 6 do
local crate = nodeNew()
nodeSetMesh(crate, meshBox(0.6, 0.6, 0.6), crateLook)
nodeSetPosition(crate, -0.6 + (i % 2) * 0.05, -1.5 + (i - 1) * 0.62, 0.2)
nodeSetRotation(crate, 0, (i - 1) * 7, 0)
bodyNew(crate, BODY_DYNAMIC, SHAPE_BOX, 0.6, 0.6, 0.6)
bodySetFriction(crate, 0.6)
crates[i] = crate
end
local ball = nodeNew()
nodeSetMesh(ball, meshSphere(0.35, 32), ballLook)
nodeSetPosition(ball, 1.2, 3.0, 0.6)
bodyNew(ball, BODY_DYNAMIC, SHAPE_SPHERE, 0.35)
bodySetBounce(ball, 0.6)
bodySetMass(ball, 2)
local paddle = nodeNew()
nodeSetMesh(paddle, meshBox(0.3, 1.2, 1.6), paddleLook)
nodeSetPosition(paddle, -4.5, -1.2, 0.2)
bodyNew(paddle, BODY_KINEMATIC, SHAPE_BOX, 0.3, 1.2, 1.6)
local sun = lightNew(LIGHT_DIRECTIONAL)
nodeSetPosition(sun, -3, 6, 4)
nodeLookAt(sun, 0, 0, 0)
lightSetIntensity(sun, 1.2)
lightSetShadow(sun, true)
local camera = nodeNew()
nodeSetPosition(camera, 3.5, 1.8, 6.5)
nodeLookAt(camera, 0, -0.4, 0)
cameraSet(camera)
cameraSetPerspective(50, 0.1, 100)
function onOverlayUpdate()
frames = frames + 1
overlayClear()
local bx, by, bz = nodeGetWorldPosition(ball)
fontPrint(20, 20, string.format("Physics %d ball y=%.1f %s", frames, by, bodyIsResting(ball) and "resting" or "moving"))
if frames >= 70 and frames < 160 then
-- The paddle sweeps through the stack from the left.
nodeMove(paddle, 0.07, 0, 0)
end
if frames == 40 or frames == 120 or frames == 200 then
singeScreenshot()
end
if frames == 210 then
singeQuit()
end
end