singe/docs/learn/09-pictures.singe
2026-09-22 21:57:42 -05:00

227 lines
5 KiB
Text

-- Lesson 9: Pictures. The finished script, exactly as the lesson ends.
dofile("Singe/Framework.singe")
local SHIP_SPEED = 3
local SHOT_SPEED = 6
local ROCK_COUNT = 6
local STAR_COUNT = 40
local START_LIVES = 3
local HIT_SCORE = 10
local shipSprite = spriteLoad(DIR .. "art/ship.png")
local rockSprite = spriteLoad(DIR .. "art/rock.png")
local shotSprite = spriteLoad(DIR .. "art/shot.png")
local starSprite = spriteLoad(DIR .. "art/star.png")
local screenWidth = overlayGetWidth()
local screenHeight = overlayGetHeight()
local shipWidth = spriteGetWidth(shipSprite)
local shipHeight = spriteGetHeight(shipSprite)
local rockWidth = spriteGetWidth(rockSprite)
local rockHeight = spriteGetHeight(rockSprite)
local shotWidth = spriteGetWidth(shotSprite)
local shotHeight = spriteGetHeight(shotSprite)
local shipX = (screenWidth - shipWidth) / 2
local shipY = screenHeight - shipHeight - 4
local goLeft = false
local goRight = false
local rocks = {}
local shots = {}
local stars = {}
local score = 0
local lives = START_LIVES
local over = false
function drawHud()
overlayPrint(1, 1, "SCORE " .. score)
overlayPrint(50, 1, "LIVES " .. lives)
if over then
overlayPrint(25, 8, "GAME OVER")
overlayPrint(17, 10, "PRESS 1 TO PLAY AGAIN")
end
end
function drawRocks()
for _, rock in ipairs(rocks) do
spriteDraw(rockSprite, rock.x, rock.y)
end
end
function drawShots()
for _, shot in ipairs(shots) do
spriteDraw(shotSprite, shot.x, shot.y)
end
end
function drawStars()
for _, star in ipairs(stars) do
spriteDraw(starSprite, star.x, star.y)
end
end
function newRock(rock)
rock.x = math.random(0, screenWidth - rockWidth)
rock.y = -rockHeight - math.random(0, 160)
rock.speed = math.random(8, 20) / 10
end
function onInputPressed(what)
if over then
if what == SWITCH_START1 then
startGame()
end
return
end
if what == SWITCH_LEFT then
goLeft = true
elseif what == SWITCH_RIGHT then
goRight = true
elseif what == SWITCH_BUTTON1 then
shots[#shots + 1] = { x = shipX + shipWidth / 2 - shotWidth / 2, y = shipY }
end
end
function onInputReleased(what)
if what == SWITCH_LEFT then
goLeft = false
elseif what == SWITCH_RIGHT then
goRight = false
end
end
function onOverlayUpdate()
overlayClear()
updateStars()
if not over then
updateShip()
updateShots()
updateRocks()
end
drawStars()
drawRocks()
drawShots()
spriteDraw(shipSprite, shipX, shipY)
drawHud()
return OVERLAY_UPDATED
end
function onShutdown()
spriteUnload(shipSprite)
spriteUnload(rockSprite)
spriteUnload(shotSprite)
spriteUnload(starSprite)
end
function overlapping(ax, ay, aw, ah, bx, by, bw, bh)
if ax + aw <= bx then
return false
end
if bx + bw <= ax then
return false
end
if ay + ah <= by then
return false
end
if by + bh <= ay then
return false
end
return true
end
function startGame()
shipX = (screenWidth - shipWidth) / 2
score = 0
lives = START_LIVES
over = false
shots = {}
for i = 1, ROCK_COUNT do
rocks[i] = {}
newRock(rocks[i])
end
end
function updateRocks()
for _, rock in ipairs(rocks) do
rock.y = rock.y + rock.speed
if rock.y > screenHeight then
newRock(rock)
end
if overlapping(shipX, shipY, shipWidth, shipHeight, rock.x, rock.y, rockWidth, rockHeight) then
newRock(rock)
lives = lives - 1
if lives <= 0 then
over = true
end
end
end
end
function updateShip()
if goLeft then
shipX = shipX - SHIP_SPEED
end
if goRight then
shipX = shipX + SHIP_SPEED
end
if shipX < 0 then
shipX = 0
end
if shipX > screenWidth - shipWidth then
shipX = screenWidth - shipWidth
end
end
function updateShots()
for i = #shots, 1, -1 do
local shot = shots[i]
local gone = false
shot.y = shot.y - SHOT_SPEED
if shot.y + shotHeight < 0 then
gone = true
end
for _, rock in ipairs(rocks) do
if not gone and overlapping(shot.x, shot.y, shotWidth, shotHeight, rock.x, rock.y, rockWidth, rockHeight) then
newRock(rock)
score = score + HIT_SCORE
gone = true
end
end
if gone then
table.remove(shots, i)
end
end
end
function updateStars()
for _, star in ipairs(stars) do
star.y = star.y + star.speed
if star.y > screenHeight then
star.y = 0
star.x = math.random(0, screenWidth - 1)
end
end
end
for i = 1, STAR_COUNT do
stars[i] = { x = math.random(0, screenWidth - 1), y = math.random(0, screenHeight - 1), speed = math.random(1, 3) / 4 }
end
startGame()