179 lines
4.3 KiB
Text
179 lines
4.3 KiB
Text
-- Learn to Program with Singe -- Lesson 8: When It Goes Wrong
|
|
|
|
dofile("Singe/Framework.singe")
|
|
|
|
local DEBUG = true
|
|
local REPORT_FRAMES = 120
|
|
|
|
local PLAYER_WIDTH = 40
|
|
local PLAYER_HEIGHT = 8
|
|
local PLAYER_SPEED = 4
|
|
local PLAYER_MARGIN = 4
|
|
local BLOCK_SIZE = 12
|
|
local BLOCK_SPEED = 1.5
|
|
local BLOCK_FASTER = 0.05
|
|
local SPAWN_FRAMES = 40
|
|
local START_LIVES = 3
|
|
local TEXT_COLUMNS = 60
|
|
|
|
local screenWidth = overlayGetWidth()
|
|
local screenHeight = overlayGetHeight()
|
|
local playerY = screenHeight - PLAYER_HEIGHT - PLAYER_MARGIN
|
|
|
|
local playerX = (screenWidth - PLAYER_WIDTH) / 2
|
|
local goingLeft = false
|
|
local goingRight = false
|
|
local blocks = {}
|
|
local blockSpeed = BLOCK_SPEED
|
|
local spawnTimer = 0
|
|
local score = 0
|
|
local lives = START_LIVES
|
|
local state = "waiting"
|
|
local reportTimer = 0
|
|
|
|
|
|
function debugLog(text)
|
|
if DEBUG then
|
|
debugPrint(text)
|
|
end
|
|
end
|
|
|
|
|
|
function debugReport()
|
|
debugLog(state .. ": score " .. score .. ", lives " .. lives .. ", blocks " .. #blocks)
|
|
debugLog(" speed " .. blockSpeed .. ", left " .. tostring(goingLeft) .. ", right " .. tostring(goingRight))
|
|
end
|
|
|
|
|
|
function drawGame()
|
|
colorForeground(80, 255, 160)
|
|
overlayBox(playerX, playerY, playerX + PLAYER_WIDTH - 1, playerY + PLAYER_HEIGHT - 1)
|
|
colorForeground(255, 90, 90)
|
|
for i, block in ipairs(blocks) do
|
|
overlayBox(block.x, block.y, block.x + BLOCK_SIZE - 1, block.y + BLOCK_SIZE - 1)
|
|
end
|
|
overlayPrint(1, 1, "SCORE " .. score .. " LIVES " .. lives)
|
|
if DEBUG then
|
|
overlayPrint(1, 3, "BLOCKS " .. #blocks .. " PLAYER " .. playerX)
|
|
end
|
|
end
|
|
|
|
|
|
function drawOverText()
|
|
printCentered(7, "GAME OVER")
|
|
printCentered(9, "PRESS SPACE TO PLAY AGAIN")
|
|
end
|
|
|
|
|
|
function drawWaitingText()
|
|
printCentered(6, "DODGE THE BLOCKS")
|
|
printCentered(8, "ARROW KEYS TO MOVE")
|
|
printCentered(10, "PRESS SPACE TO START")
|
|
end
|
|
|
|
|
|
function printCentered(row, text)
|
|
overlayPrint(math.floor((TEXT_COLUMNS - #text) / 2), row, text)
|
|
end
|
|
|
|
|
|
function spawnBlock()
|
|
local block = {}
|
|
block.x = math.random(0, screenWidth - BLOCK_SIZE)
|
|
block.y = -BLOCK_SIZE
|
|
table.insert(blocks, block)
|
|
end
|
|
|
|
|
|
function startGame()
|
|
playerX = (screenWidth - PLAYER_WIDTH) / 2
|
|
blocks = {}
|
|
blockSpeed = BLOCK_SPEED
|
|
spawnTimer = 0
|
|
score = 0
|
|
lives = START_LIVES
|
|
state = "playing"
|
|
debugLog("startGame: lives " .. lives .. ", speed " .. blockSpeed)
|
|
end
|
|
|
|
|
|
function updatePlaying()
|
|
if goingLeft then
|
|
playerX = playerX - PLAYER_SPEED
|
|
end
|
|
if goingRight then
|
|
playerX = playerX + PLAYER_SPEED
|
|
end
|
|
if playerX < 0 then
|
|
playerX = 0
|
|
elseif playerX > screenWidth - PLAYER_WIDTH then
|
|
playerX = screenWidth - PLAYER_WIDTH
|
|
end
|
|
|
|
spawnTimer = spawnTimer - 1
|
|
if spawnTimer <= 0 then
|
|
spawnBlock()
|
|
spawnTimer = SPAWN_FRAMES
|
|
end
|
|
|
|
for i = #blocks, 1, -1 do
|
|
local block = blocks[i]
|
|
block.y = block.y + blockSpeed
|
|
if collideRects(block.x, block.y, BLOCK_SIZE, BLOCK_SIZE, playerX, playerY, PLAYER_WIDTH, PLAYER_HEIGHT) then
|
|
table.remove(blocks, i)
|
|
lives = lives - 1
|
|
debugLog("hit at y " .. math.floor(block.y) .. ", lives now " .. lives)
|
|
if lives == 0 then
|
|
state = "over"
|
|
debugLog("game over with score " .. score)
|
|
end
|
|
elseif block.y > screenHeight then
|
|
table.remove(blocks, i)
|
|
score = score + 1
|
|
blockSpeed = blockSpeed + BLOCK_FASTER
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function onInputPressed(what)
|
|
if what == SWITCH_LEFT then
|
|
goingLeft = true
|
|
elseif what == SWITCH_RIGHT then
|
|
goingRight = true
|
|
elseif what == SWITCH_BUTTON1 and state ~= "playing" then
|
|
startGame()
|
|
end
|
|
end
|
|
|
|
|
|
function onInputReleased(what)
|
|
if what == SWITCH_LEFT then
|
|
goingLeft = false
|
|
elseif what == SWITCH_RIGHT then
|
|
goingRight = false
|
|
end
|
|
end
|
|
|
|
|
|
function onOverlayUpdate()
|
|
reportTimer = reportTimer - 1
|
|
if reportTimer <= 0 then
|
|
debugReport()
|
|
reportTimer = REPORT_FRAMES
|
|
end
|
|
|
|
if state == "playing" then
|
|
updatePlaying()
|
|
end
|
|
|
|
overlayClear()
|
|
drawGame()
|
|
if state == "waiting" then
|
|
drawWaitingText()
|
|
elseif state == "over" then
|
|
drawOverText()
|
|
end
|
|
|
|
return OVERLAY_UPDATED
|
|
end
|