150 lines
3.5 KiB
Text
150 lines
3.5 KiB
Text
-- Learn to Program with Singe -- Lesson 7: A Game
|
|
|
|
dofile("Singe/Framework.singe")
|
|
|
|
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 = overlayGetWidth() // overlayGetFontWidth()
|
|
|
|
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"
|
|
|
|
|
|
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)
|
|
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"
|
|
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
|
|
if lives == 0 then
|
|
state = "over"
|
|
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()
|
|
if state == "playing" then
|
|
updatePlaying()
|
|
end
|
|
|
|
overlayClear()
|
|
drawGame()
|
|
if state == "waiting" then
|
|
drawWaitingText()
|
|
elseif state == "over" then
|
|
drawOverText()
|
|
end
|
|
|
|
return OVERLAY_UPDATED
|
|
end
|