188 lines
4.2 KiB
Text
188 lines
4.2 KiB
Text
-- Lesson 11: Hitting Things. The finished script, exactly as the lesson ends.
|
|
dofile("Singe/Framework.singe")
|
|
|
|
local SHIP_WIDTH = 32
|
|
local SHIP_HEIGHT = 24
|
|
local SHIP_PAD_X = 6
|
|
local SHIP_PAD_Y = 5
|
|
local SHIP_SPEED = 3
|
|
local ROCK_WIDTH = 24
|
|
local ROCK_HEIGHT = 24
|
|
local ROCK_PAD = 4
|
|
local ROCK_SPEED = 1
|
|
local ROCK_CHANCE = 40
|
|
local SHOT_WIDTH = 4
|
|
local SHOT_HEIGHT = 10
|
|
local SHOT_SPEED = 6
|
|
local SHOW_BOXES = false
|
|
|
|
local shipSprite = spriteLoad(DIR .. "art/ship.png")
|
|
local rockSprite = spriteLoad(DIR .. "art/rock.png")
|
|
local shotSprite = spriteLoad(DIR .. "art/shot.png")
|
|
local shootSound = soundLoad(DIR .. "art/shoot.wav")
|
|
local boomSound = soundLoad(DIR .. "art/boom.wav")
|
|
|
|
local shipX = (overlayGetWidth() - SHIP_WIDTH) / 2
|
|
local shipY = overlayGetHeight() - SHIP_HEIGHT - 8
|
|
local movingLeft = false
|
|
local movingRight = false
|
|
local rocks = {}
|
|
local shots = {}
|
|
|
|
|
|
local function addRock()
|
|
local rock = {}
|
|
rock.x = math.random(0, overlayGetWidth() - ROCK_WIDTH)
|
|
rock.y = -ROCK_HEIGHT
|
|
rocks[#rocks + 1] = rock
|
|
end
|
|
|
|
|
|
local function fireShot()
|
|
local shot = {}
|
|
shot.x = shipX + SHIP_WIDTH / 2 - SHOT_WIDTH / 2
|
|
shot.y = shipY - SHOT_HEIGHT
|
|
shots[#shots + 1] = shot
|
|
soundPlay(shootSound)
|
|
end
|
|
|
|
|
|
local function rockBox(rock)
|
|
return rock.x + ROCK_PAD, rock.y + ROCK_PAD, ROCK_WIDTH - ROCK_PAD * 2, ROCK_HEIGHT - ROCK_PAD * 2
|
|
end
|
|
|
|
|
|
local function shipBox()
|
|
return shipX + SHIP_PAD_X, shipY + SHIP_PAD_Y, SHIP_WIDTH - SHIP_PAD_X * 2, SHIP_HEIGHT - SHIP_PAD_Y * 2
|
|
end
|
|
|
|
|
|
local function shipHitsRock(rock)
|
|
local sx, sy, sw, sh = shipBox()
|
|
local rx, ry, rw, rh = rockBox(rock)
|
|
return collideRects(sx, sy, sw, sh, rx, ry, rw, rh)
|
|
end
|
|
|
|
|
|
local function shotHitsRock(shot, rock)
|
|
local rx, ry, rw, rh = rockBox(rock)
|
|
return collidePointRect(shot.x + SHOT_WIDTH / 2, shot.y, rx, ry, rw, rh)
|
|
end
|
|
|
|
|
|
local function moveShip()
|
|
if movingLeft then
|
|
shipX = shipX - SHIP_SPEED
|
|
end
|
|
if movingRight then
|
|
shipX = shipX + SHIP_SPEED
|
|
end
|
|
if shipX < 0 then
|
|
shipX = 0
|
|
end
|
|
if shipX > overlayGetWidth() - SHIP_WIDTH then
|
|
shipX = overlayGetWidth() - SHIP_WIDTH
|
|
end
|
|
end
|
|
|
|
|
|
local function moveRocks()
|
|
if math.random(ROCK_CHANCE) == 1 then
|
|
addRock()
|
|
end
|
|
for i = #rocks, 1, -1 do
|
|
local rock = rocks[i]
|
|
rock.y = rock.y + ROCK_SPEED
|
|
if rock.y > overlayGetHeight() then
|
|
table.remove(rocks, i)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local function moveShots()
|
|
for i = #shots, 1, -1 do
|
|
local shot = shots[i]
|
|
shot.y = shot.y - SHOT_SPEED
|
|
if shot.y + SHOT_HEIGHT < 0 then
|
|
table.remove(shots, i)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local function checkHits()
|
|
for s = #shots, 1, -1 do
|
|
for r = #rocks, 1, -1 do
|
|
if shotHitsRock(shots[s], rocks[r]) then
|
|
table.remove(rocks, r)
|
|
table.remove(shots, s)
|
|
soundPlay(boomSound)
|
|
break
|
|
end
|
|
end
|
|
end
|
|
for r = #rocks, 1, -1 do
|
|
if shipHitsRock(rocks[r]) then
|
|
table.remove(rocks, r)
|
|
soundPlay(boomSound)
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
local function drawBox(x, y, width, height)
|
|
overlayBox(x, y, x + width - 1, y + height - 1)
|
|
end
|
|
|
|
|
|
local function drawBoxes()
|
|
colorForeground(0, 255, 0, 255)
|
|
drawBox(shipBox())
|
|
for _, rock in ipairs(rocks) do
|
|
drawBox(rockBox(rock))
|
|
end
|
|
end
|
|
|
|
|
|
function onInputPressed(what)
|
|
if what == SWITCH_LEFT then
|
|
movingLeft = true
|
|
elseif what == SWITCH_RIGHT then
|
|
movingRight = true
|
|
elseif what == SWITCH_BUTTON1 then
|
|
fireShot()
|
|
end
|
|
end
|
|
|
|
|
|
function onInputReleased(what)
|
|
if what == SWITCH_LEFT then
|
|
movingLeft = false
|
|
elseif what == SWITCH_RIGHT then
|
|
movingRight = false
|
|
end
|
|
end
|
|
|
|
|
|
function onOverlayUpdate()
|
|
overlayClear()
|
|
|
|
moveShip()
|
|
moveRocks()
|
|
moveShots()
|
|
checkHits()
|
|
|
|
spriteDraw(shipSprite, shipX, shipY)
|
|
for _, rock in ipairs(rocks) do
|
|
spriteDraw(rockSprite, rock.x, rock.y)
|
|
end
|
|
for _, shot in ipairs(shots) do
|
|
spriteDraw(shotSprite, shot.x, shot.y)
|
|
end
|
|
if SHOW_BOXES then
|
|
drawBoxes()
|
|
end
|
|
|
|
return OVERLAY_UPDATED
|
|
end
|