69 lines
2.4 KiB
Text
69 lines
2.4 KiB
Text
-- Character controller in 2D: a platformer drawn on the overlay with sprites and boxes, no GPU
|
|
-- needed. The player runs right, hops a gap, climbs a step, is stopped by a wall and jumps onto a
|
|
-- ledge, on a scripted route; gravity points down the screen (+Y) like every 2D game here.
|
|
local font = fontLoad("Singe/FreeSansBold.ttf", 24)
|
|
local crate = spriteLoad("testScripts/crate.png")
|
|
local frames = 0
|
|
|
|
overlaySetResolution(720, 480)
|
|
local width, height = overlayGetWidth(), overlayGetHeight()
|
|
|
|
fontSelect(font)
|
|
physicsSet2D(true)
|
|
physicsSetGravity(0, 900, 0)
|
|
|
|
local blocks = {}
|
|
local function block(x, y, w, h)
|
|
local node = nodeNew()
|
|
nodeSetPosition(node, x, y, 0)
|
|
bodyNew(node, BODY_STATIC, SHAPE_BOX, w, h, 50)
|
|
blocks[#blocks + 1] = { x = x, y = y, w = w, h = h }
|
|
return node
|
|
end
|
|
|
|
-- Ground with a gap, a low step, a wall, and a ledge to jump onto.
|
|
local ground = height - 20
|
|
block(width * 0.2, ground, width * 0.4, 20)
|
|
block(width * 0.72, ground, width * 0.56, 20)
|
|
block(width * 0.55, ground - 22, 60, 24)
|
|
block(width * 0.85, ground - 60, 20, 100)
|
|
block(width * 0.92, ground - 140, 140, 20)
|
|
|
|
local size = spriteGetWidth(crate)
|
|
local player = nodeNew()
|
|
nodeSetPosition(player, 40, ground - 10, 0)
|
|
playerNew(player, size * 0.45, size * 1.4)
|
|
playerSetStep(player, 26)
|
|
|
|
local hops = 0
|
|
|
|
function onOverlayUpdate()
|
|
local px, py = nodeGetPosition(player)
|
|
frames = frames + 1
|
|
playerMove(player, (px < width * 0.9) and 220 or 0)
|
|
-- Hop the gap, and later the wall, when the ground runs out ahead or the wall is near.
|
|
if playerIsOnGround(player) and ((px > width * 0.36 and px < width * 0.42) or (px > width * 0.70 and px < width * 0.75)) then
|
|
if playerJump(player, 560) then
|
|
hops = hops + 1
|
|
end
|
|
end
|
|
overlayClear()
|
|
colorForeground(90, 90, 110)
|
|
for _, b in ipairs(blocks) do
|
|
overlayBox(b.x - b.w / 2, b.y - b.h / 2, b.x + b.w / 2, b.y + b.h / 2)
|
|
end
|
|
spriteDraw(crate, px - size / 2, py - size * 1.4, px + size / 2, py)
|
|
colorForeground(255, 255, 255)
|
|
fontPrint(20, 20, string.format("Platformer, frame %d x %.0f y %.0f ground %s hops %d", frames, px, py, tostring(playerIsOnGround(player)), hops))
|
|
if frames % 10 == 0 then
|
|
local vx, vy = playerGetVelocity(player)
|
|
debugPrint(string.format("frame %d player %.0f %.0f v %.0f %.0f ground %s hops %d", frames, px, py, vx, vy, tostring(playerIsOnGround(player)), hops))
|
|
end
|
|
if frames == 40 or frames == 90 or frames == 140 then
|
|
singeScreenshot()
|
|
end
|
|
if frames == 180 then
|
|
singeQuit()
|
|
end
|
|
return OVERLAY_UPDATED
|
|
end
|