-- 2D physics with no 3D at all: crates drawn as sprites fall and pile up in overlay coordinates. -- Runs on any machine, GPU or not (try it with SDL_GPU_DRIVER=nothing). local font = fontLoad("Singe/FreeSansBold.ttf", 24) local box = spriteLoad("testScripts/crate.png") local frames = 0 local width, height = overlayGetWidth(), overlayGetHeight() fontSelect(font) physicsSet2D(true) physicsSetGravity(0, 900, 0) -- Pixels per second squared; overlay Y runs down. -- The floor and walls, static, sized in pixels. local floor = nodeNew() nodeSetPosition(floor, width / 2, height - 10, 0) bodyNew(floor, BODY_STATIC, SHAPE_BOX, width, 20, 50) local leftWall = nodeNew() nodeSetPosition(leftWall, -10, height / 2, 0) bodyNew(leftWall, BODY_STATIC, SHAPE_BOX, 20, height, 50) local rightWall = nodeNew() nodeSetPosition(rightWall, width + 10, height / 2, 0) bodyNew(rightWall, BODY_STATIC, SHAPE_BOX, 20, height, 50) -- A slope the crates tumble off. local slope = nodeNew() nodeSetPosition(slope, width * 0.3, height * 0.55, 0) nodeSetRotation(slope, 0, 0, 20) bodyNew(slope, BODY_STATIC, SHAPE_BOX, width * 0.45, 12, 50) local size = spriteGetWidth(box) local crates = {} local function drop(i) local crate = nodeNew() nodeSetPosition(crate, width * 0.15 + (i % 5) * size * 0.6, -size * (1 + i * 0.5), 0) nodeSetRotation(crate, 0, 0, i * 13) bodyNew(crate, BODY_DYNAMIC, SHAPE_BOX, size, size, 50) bodySetMass(crate, 1) bodySetFriction(crate, 0.6) bodySetBounce(crate, 0.2) crates[#crates + 1] = crate end for i = 1, 14 do drop(i) end local resting = 0 function onCollision(a, b, x, y, z, speed) end function onOverlayUpdate() frames = frames + 1 overlayClear() resting = 0 for _, crate in ipairs(crates) do local x, y = nodeGetPosition(crate) local _, _, angle = nodeGetRotation(crate) spriteRotate(box, angle) spriteDraw(box, x, y, true) if bodyIsResting(crate) then resting = resting + 1 end end fontPrint(10, 8, string.format("2D physics, frame %d, %d of %d resting", frames, resting, #crates)) if frames == 40 or frames == 100 or frames == 220 then singeScreenshot() end if frames == 240 then singeQuit() end return OVERLAY_UPDATED end