singe/testScripts/scene19.singe

121 lines
4.2 KiB
Text

-- Character controller: the Fox as a player walking a course of stairs, ramps, a wall, a crate to
-- shove and a moving platform, driven by a scripted route so it runs headless; the camera follows.
local font = fontLoad("Singe/FreeSansBold.ttf", 28)
local frames = 0
fontSelect(font)
discPlay()
sceneEnable(true)
sceneSetBackground(0, 0, 0, 0)
sceneSetAmbient(70, 70, 80)
local stone = materialNew()
materialSetColor(stone, 120, 120, 130)
materialSetRoughness(stone, 0.9)
local wood = materialNew()
materialSetColor(wood, 150, 100, 50)
local steel = materialNew()
materialSetColor(steel, 90, 110, 150)
materialSetMetallic(steel, 0.6)
local function block(x, y, z, w, h, d, material)
local node = nodeNew()
nodeSetMesh(node, meshBox(w, h, d), material)
nodeSetPosition(node, x, y, z)
bodyNew(node, BODY_STATIC, SHAPE_BOX, w, h, d)
return node
end
-- The course runs along +X. Floor, three stairs, a gentle ramp, a steep ramp, a wall to slide along.
block(8, -0.1, 0, 30, 0.2, 8, stone)
block(2.0, 0.075, 0, 0.6, 0.15, 4, wood)
block(2.6, 0.15, 0, 0.6, 0.30, 4, wood)
block(3.2, 0.225, 0, 0.6, 0.45, 4, wood)
local ramp = nodeNew()
nodeSetMesh(ramp, meshBox(3, 0.2, 4), stone)
nodeSetPosition(ramp, 6.2, 0.7, 0)
nodeSetRotation(ramp, 0, 0, 25)
bodyNew(ramp, BODY_STATIC, SHAPE_BOX, 3, 0.2, 4)
block(9.0, 0.7, 0, 2.6, 2.6, 4, stone) -- The top landing behind the ramp
local steep = nodeNew()
nodeSetMesh(steep, meshBox(2, 0.2, 4), stone)
nodeSetPosition(steep, 11.0, 2.85, 0)
nodeSetRotation(steep, 0, 0, 60)
bodyNew(steep, BODY_STATIC, SHAPE_BOX, 2, 0.2, 4)
block(9.0, 2.4, -2.5, 4, 1.2, 0.2, steel) -- A wall along the landing's far edge
-- A crate to shove and a platform that slides back and forth.
local crate = nodeNew()
nodeSetMesh(crate, meshBox(0.6, 0.6, 0.6), wood)
nodeSetPosition(crate, 4.6, 0.3, 0.15)
bodyNew(crate, BODY_DYNAMIC, SHAPE_BOX, 0.6, 0.6, 0.6)
bodySetMass(crate, 5)
local platform = nodeNew()
nodeSetMesh(platform, meshBox(1.5, 0.2, 1.5), steel)
nodeSetPosition(platform, 8.5, 2.1, 1.5)
bodyNew(platform, BODY_KINEMATIC, SHAPE_BOX, 1.5, 0.2, 1.5)
-- The player: a capsule with the Fox model hanging off the node, facing +X.
local player = nodeNew()
nodeSetPosition(player, 0, 0.05, 0)
playerNew(player, 0.3, 1.0)
playerSetStep(player, 0.35)
local foxModel = modelLoad("testScripts/Models/Fox.glb")
local fox = modelInstance(foxModel)
nodeSetParent(fox, player)
nodeSetScale(fox, 0.01)
nodeSetRotation(fox, 0, 90, 0)
animationPlay(fox, "Walk", true)
local sun = lightNew(LIGHT_DIRECTIONAL)
nodeSetPosition(sun, -3, 8, 5)
nodeLookAt(sun, 6, 0, 0)
lightSetIntensity(sun, 1.5)
lightSetShadow(sun, true)
local camera = nodeNew()
cameraSet(camera)
local jumped = false
local landings = 0
function onCollision(a, b, x, y, z, speed)
if a == player or b == player then
landings = landings + 1
end
end
function onOverlayUpdate()
local px, py, pz = nodeGetPosition(player)
local t = frames / 60
frames = frames + 1
-- Route: walk east up the stairs and the ramp, veer to the wall, then onto the platform.
local vz = 0
if px > 7.5 and px < 10 then
vz = (t < 6) and -1.2 or 1.2
end
playerMove(player, 3.0, vz)
if px > 5.5 and not jumped and playerIsOnGround(player) then
jumped = playerJump(player, 4.5)
end
nodeSetRotation(player, 0, math.deg(math.atan(vz, 3.0)) * -1, 0)
-- The platform slides in Z.
nodeSetPosition(platform, 8.5, 2.1, 1.5 + math.sin(t * 1.5) * 1.5)
-- Camera behind and above the player.
nodeSetPosition(camera, px - 4.5, py + 2.6, pz + 4.5)
nodeLookAt(camera, px + 1, py + 0.6, pz)
overlayClear()
fontPrint(20, 20, string.format("Player, frame %d x %.1f y %.2f ground %s landings %d", frames, px, py, tostring(playerIsOnGround(player)), landings))
if frames % 30 == 0 then
local fx, fy, fz = nodeGetWorldPosition(fox)
local vx, vy, vz = playerGetVelocity(player)
local cx, cy, cz = nodeGetPosition(crate)
debugPrint(string.format("frame %d player %.2f %.2f %.2f v %.2f %.2f %.2f ground %s jumped %s crate %.2f %.2f landings %d", frames, px, py, pz, vx, vy, vz, tostring(playerIsOnGround(player)), tostring(jumped), cx, cz, landings))
end
if frames == 40 or frames == 80 or frames == 120 or frames == 160 then
singeScreenshot()
end
if frames == 180 then
singeQuit()
end
end