Code Sketch
navya
Category: Art
// ========================================
// SPACE SHOOTER
// Kojo Coding Competition
// ========================================
cleari()
originBottomLeft()
// GAME VARIABLES
var shipX = 400.0
var shipY = 90.0
var score = 0
var lives = 3
var gameOver = false
var tick = 0
val meteorX = Array(
100.0, 250.0, 400.0, 550.0, 700.0
)
val meteorY = Array(
500.0, 650.0, 800.0, 950.0, 1100.0
)
val starX = Array(
180.0, 350.0, 520.0, 680.0
)
val starY = Array(
400.0, 600.0, 800.0, 1000.0
)
val starTaken =
Array.fill(starX.length)(false)
// KEYBOARD CONTROLS
onKeyPress { key =>
if (!gameOver) {
if (key == Kc.VK_LEFT) {
shipX -= 25
}
if (key == Kc.VK_RIGHT) {
shipX += 25
}
shipX = math.max(
30,
math.min(cwidth - 30, shipX)
)
}
}
// DRAW BACKGROUND
def drawBackground(canvas: CanvasDraw) {
canvas.fill(5, 5, 30)
canvas.noStroke()
canvas.rect(0, 0, cwidth, cheight)
canvas.fill(180, 200, 255)
for (i <- 0 until 50) {
val x = (i * 137) % cwidth.toInt
val y = (i * 197) % cheight.toInt
canvas.ellipse(
x.toDouble,
y.toDouble,
3,
3
)
}
}
// DRAW SPACESHIP
def drawShip(canvas: CanvasDraw) {
canvas.fill(0, 220, 255)
canvas.stroke(255, 255, 255)
canvas.strokeWeight(2)
canvas.rect(
shipX - 20,
shipY - 15,
40,
30
)
canvas.fill(255, 80, 20)
canvas.noStroke()
canvas.ellipse(
shipX,
shipY - 20,
14,
18
)
canvas.fill(255, 255, 0)
canvas.ellipse(
shipX,
shipY + 5,
12,
12
)
}
// DRAW METEORS
def drawMeteors(canvas: CanvasDraw) {
canvas.fill(255, 80, 40)
canvas.stroke(255, 180, 80)
canvas.strokeWeight(2)
for (i <- meteorX.indices) {
canvas.ellipse(
meteorX(i),
meteorY(i),
30,
30
)
}
}
// DRAW STARS
def drawStars(canvas: CanvasDraw) {
for (i <- starX.indices) {
if (!starTaken(i)) {
canvas.fill(255, 240, 0)
canvas.noStroke()
canvas.ellipse(
starX(i),
starY(i),
18,
18
)
}
}
}
// UPDATE GAME
def updateGame() {
if (!gameOver) {
tick += 1
// Move meteors
for (i <- meteorY.indices) {
meteorY(i) -= 5
if (meteorY(i) < 0) {
meteorY(i) = cheight + 50
meteorX(i) =
randomDouble(30, cwidth - 30)
}
// Meteor collision
if (
math.abs(meteorX(i) - shipX) < 30 &&
math.abs(meteorY(i) - shipY) < 30
) {
lives -= 1
meteorY(i) = cheight + 100
if (lives <= 0) {
gameOver = true
}
}
}
// Move stars
for (i <- starY.indices) {
starY(i) -= 3
if (starY(i) < 0) {
starY(i) = cheight + 100
starTaken(i) = false
}
// Collect stars
if (
!starTaken(i) &&
math.abs(starX(i) - shipX) < 25 &&
math.abs(starY(i) - shipY) < 25
) {
starTaken(i) = true
score += 10
}
}
// Bonus points for survival
if (tick % 100 == 0) {
score += 5
}
}
}
// DRAW SCOREBOARD
def drawScore(canvas: CanvasDraw) {
canvas.fill(255, 255, 255)
canvas.noStroke()
canvas.text(
s"SCORE: $score",
25,
cheight - 35
)
canvas.text(
s"LIVES: $lives",
25,
cheight - 60
)
canvas.text(
"SPACE SHOOTER",
cwidth / 2 - 65,
cheight - 35
)
}
// GAME OVER SCREEN
def drawGameOver(canvas: CanvasDraw) {
canvas.fill(10, 10, 35)
canvas.noStroke()
canvas.rect(0, 0, cwidth, cheight)
canvas.fill(255, 60, 60)
canvas.text(
"GAME OVER!",
cwidth / 2 - 55,
cheight / 2 + 40
)
canvas.fill(255, 255, 255)
canvas.text(
s"FINAL SCORE: $score",
cwidth / 2 - 65,
cheight / 2
)
canvas.text(
"Refresh to play again",
cwidth / 2 - 75,
cheight / 2 - 40
)
}
// GAME LOOP
animateWithCanvasDraw { canvas =>
updateGame()
if (!gameOver) {
drawBackground(canvas)
drawStars(canvas)
drawMeteors(canvas)
drawShip(canvas)
drawScore(canvas)
} else {
drawGameOver(canvas)
}
}