-- Lesson 10: Sound. 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 shootClip = soundLoad(DIR .. "art/shoot.wav") local boomClip = soundLoad(DIR .. "art/boom.wav") local clickClip = soundLoad("Singe/click.wav") local theme = musicLoad("Singe/menuIntro.flac") 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 local dying = false local deathChannel = -1 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 endGame() dying = false deathChannel = -1 over = true musicStop(theme, 1500) 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 soundPlay(clickClip) 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 } soundPlay(shootClip, 0, 35) 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 and not dying 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) soundUnload(shootClip) soundUnload(boomClip) soundUnload(clickClip) musicUnload(theme) end function onSoundCompleted(channel) if channel == deathChannel then endGame() end 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 dying = false deathChannel = -1 shots = {} for i = 1, ROCK_COUNT do rocks[i] = {} newRock(rocks[i]) end musicSetVolume(50) musicPlay(theme, -1) 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 local channel = soundPlay(boomClip) newRock(rock) lives = lives - 1 if lives <= 0 then dying = true deathChannel = channel if channel < 0 then endGame() end 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 soundPlay(boomClip, 0, 45) 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()