Code Sketch
Bixuu02
Category: Programming
// ============================================================
// KEYBOARD CONTROLLED CAR DRIVING MISSION GAME (FIXED)
// ============================================================
cleari()
originBottomLeft()
// ============================================================
// GAME VARIABLES & STATES
// ============================================================
var screen = 0 // 0: Letter, 1: Playing, 2: Game Over, 3: Victory
var playerX = 80.0
var playerY = 180.0
var playerSpeed = 6.0
// KEYBOARD STATE FLAGS
var isW = false
var isS = false
var isA = false
var isD = false
var gameTimer = 20
var frameCounter = 0
var finishX = 1200.0
var showFinishLine = false
var roadOffset = 0.0
// Obstacle Cars Class
class ObstacleCar(var x: Double, var y: Double, var speed: Double, val r: Int, val g: Int, val b: Int) {
def update() {
x -= speed
if (x < -100) {
x = cwidth + randomDouble(200)
y = 90 + randomDouble(170)
speed = 4.0 + randomDouble(4.0)
}
}
def draw(canvas: CanvasDraw) {
canvas.noStroke()
canvas.fill(40, 40, 40, 100)
canvas.ellipse(x + 35, y - 2, 80, 12)
canvas.fill(r, g, b)
canvas.rect(x, y + 5, 70, 25)
canvas.rect(x + 15, y + 25, 40, 18)
canvas.fill(200, 230, 255)
canvas.rect(x + 20, y + 27, 30, 14)
canvas.fill(20, 20, 20)
canvas.ellipse(x + 15, y + 4, 16, 16)
canvas.ellipse(x + 55, y + 4, 16, 16)
}
}
val obstacles = ArrayBuffer.empty[ObstacleCar]
def resetGame() {
playerX = 80.0
playerY = 180.0
gameTimer = 20
frameCounter = 0
showFinishLine = false
finishX = cwidth + 300.0
isW = false
isS = false
isA = false
isD = false
obstacles.clear()
val colors = Array((220, 30, 30), (255, 140, 0), (156, 39, 176), (0, 150, 136))
for (i <- 0 until 4) {
val (r, g, b) = colors(i % 4)
obstacles.append(new ObstacleCar(cwidth + i * 220 + randomDouble(100), 90 + (i * 45), 4.0 + randomDouble(3.0), r, g, b))
}
}
// ============================================================
// DRAW PLAYER CAR
// ============================================================
def drawPlayerCar(canvas: CanvasDraw, x: Double, y: Double) {
canvas.noStroke()
canvas.fill(30, 30, 30, 120)
canvas.ellipse(x + 40, y - 2, 90, 14)
// Blue Sports Car
canvas.fill(30, 144, 255)
canvas.rect(x, y + 5, 80, 28)
canvas.fill(0, 102, 204)
canvas.rect(x + 18, y + 28, 44, 20)
canvas.fill(220, 245, 255)
canvas.rect(x + 22, y + 30, 36, 15)
canvas.fill(255, 255, 150)
canvas.ellipse(x + 78, y + 12, 8, 10)
canvas.fill(20, 20, 20)
canvas.ellipse(x + 18, y + 4, 18, 18)
canvas.ellipse(x + 62, y + 4, 18, 18)
canvas.fill(220, 220, 220)
canvas.ellipse(x + 18, y + 4, 8, 8)
canvas.ellipse(x + 62, y + 4, 8, 8)
}
def drawCheckeredFinishLine(canvas: CanvasDraw, x: Double) {
val tileSize = 15
val rows = 14
val cols = 3
for (r <- 0 until rows) {
for (c <- 0 until cols) {
if ((r + c) % 2 == 0) canvas.fill(0, 0, 0)
else canvas.fill(255, 255, 255)
canvas.noStroke()
canvas.rect(x + (c * tileSize), 75 + (r * tileSize), tileSize, tileSize)
}
}
}
// ============================================================
// UPDATE MOVEMENT
// ============================================================
def updatePlayerMovement() {
if (screen == 1) {
if (isW && playerY < 240) playerY += playerSpeed
if (isS && playerY > 85) playerY -= playerSpeed
if (isA && playerX > 20) playerX -= playerSpeed
if (isD && playerX < cwidth - 100) playerX += playerSpeed
}
}
// ============================================================
// SCREENS
// ============================================================
def drawLetterScreen(canvas: CanvasDraw) {
canvas.background(20, 30, 50)
canvas.fill(255, 248, 220)
canvas.stroke(212, 175, 55)
canvas.strokeWeight(4)
canvas.rect(cwidth/2 - 240, cheight/2 - 170, 480, 350)
canvas.fill(200, 30, 30)
canvas.text("CAR DRIVING MISSION!", cwidth/2 - 120, cheight/2 + 130)
canvas.fill(40, 40, 40)
canvas.text("Dear Driver,", cwidth/2 - 210, cheight/2 + 90)
canvas.text("Control your car using Keyboard WASD or Arrow Keys:", cwidth/2 - 210, cheight/2 + 60)
canvas.text(" [W / UP] : Move Up", cwidth/2 - 190, cheight/2 + 35)
canvas.text(" [S / DOWN] : Move Down", cwidth/2 - 190, cheight/2 + 15)
canvas.text(" [A / LEFT] : Move Left", cwidth/2 - 190, cheight/2 - 5)
canvas.text(" [D / RIGHT] : Move Right", cwidth/2 - 190, cheight/2 - 25)
// Start Button
canvas.fill(220, 50, 50)
canvas.noStroke()
canvas.rect(cwidth/2 - 120, cheight/2 - 120, 240, 50)
canvas.fill(255, 255, 255)
canvas.text("START CAR MISSION", cwidth/2 - 92, cheight/2 - 90)
}
def drawGameplayScreen(canvas: CanvasDraw) {
canvas.background(135, 206, 235)
canvas.noStroke()
canvas.fill(34, 139, 34)
canvas.rect(0, 0, cwidth, cheight)
canvas.fill(60, 60, 65)
canvas.rect(0, 75, cwidth, 210)
canvas.fill(255, 255, 255)
canvas.rect(0, 75, cwidth, 6)
canvas.rect(0, 279, cwidth, 6)
roadOffset = (roadOffset - 6.0) % 40.0
canvas.fill(255, 215, 0)
var lineX = roadOffset
while (lineX < cwidth + 40) {
canvas.rect(lineX, 177, 25, 6)
lineX += 45
}
if (showFinishLine) {
drawCheckeredFinishLine(canvas, finishX)
finishX -= 4.0
}
drawPlayerCar(canvas, playerX, playerY)
repeatFor(obstacles) { obs =>
obs.update()
obs.draw(canvas)
if (math.abs(playerX - obs.x) < 60 && math.abs(playerY - obs.y) < 25) {
screen = 2
}
}
// Dashboard Timer
canvas.fill(0, 0, 0, 180)
canvas.rect(20, cheight - 60, 220, 45)
canvas.fill(255, 215, 0)
canvas.text(s"TIME LEFT: $gameTimer SECONDS", 35, cheight - 32)
if (showFinishLine && playerX >= finishX) {
screen = 3
}
}
def drawGameOverScreen(canvas: CanvasDraw) {
canvas.background(40, 10, 10)
canvas.fill(255, 50, 50)
canvas.text("MISSION FAILED - CAR CRASHED!", cwidth/2 - 160, cheight/2 + 40)
canvas.fill(255, 255, 255)
canvas.text("Be careful! Avoid oncoming traffic.", cwidth/2 - 130, cheight/2)
canvas.fill(0, 150, 200)
canvas.noStroke()
canvas.rect(cwidth/2 - 90, cheight/2 - 70, 180, 45)
canvas.fill(255, 255, 255)
canvas.text("RETRY MISSION", cwidth/2 - 62, cheight/2 - 42)
}
def drawVictoryScreen(canvas: CanvasDraw) {
canvas.background(20, 60, 30)
drawCheckeredFinishLine(canvas, cwidth/2 - 25)
canvas.fill(255, 215, 0)
canvas.text("YOU WIN! MISSION COMPLETED!", cwidth/2 - 150, cheight/2 + 60)
canvas.fill(255, 255, 255)
canvas.text("Congratulations! You safely navigated through traffic", cwidth/2 - 180, cheight/2 + 15)
canvas.text("and crossed the Checkered Finish Line in 20 seconds!", cwidth/2 - 185, cheight/2 - 15)
canvas.fill(0, 180, 80)
canvas.noStroke()
canvas.rect(cwidth/2 - 100, cheight/2 - 90, 200, 45)
canvas.fill(255, 255, 255)
canvas.text("PLAY AGAIN", cwidth/2 - 50, cheight/2 - 62)
}
// ============================================================
// CORRECTED KEY LISTENERS USING INT KEY CODES
// ============================================================
onKeyPress { key =>
if (key == Kc.VK_W || key == Kc.VK_UP || key == 87 || key == 38) isW = true
if (key == Kc.VK_S || key == Kc.VK_DOWN || key == 83 || key == 40) isS = true
if (key == Kc.VK_A || key == Kc.VK_LEFT || key == 65 || key == 37) isA = true
if (key == Kc.VK_D || key == Kc.VK_RIGHT || key == 68 || key == 39) isD = true
}
onKeyRelease { key =>
if (key == Kc.VK_W || key == Kc.VK_UP || key == 87 || key == 38) isW = false
if (key == Kc.VK_S || key == Kc.VK_DOWN || key == 83 || key == 40) isS = false
if (key == Kc.VK_A || key == Kc.VK_LEFT || key == 65 || key == 37) isA = false
if (key == Kc.VK_D || key == Kc.VK_RIGHT || key == 68 || key == 39) isD = false
}
// ============================================================
// MOUSE CLICK HANDLER FOR BUTTONS
// ============================================================
onMouseClick { (x, y) =>
if (screen == 0) {
if (x >= cwidth/2 - 120 && x <= cwidth/2 + 120 && y >= cheight/2 - 120 && y <= cheight/2 - 70) {
resetGame()
screen = 1
}
} else if (screen == 2) {
if (x >= cwidth/2 - 90 && x <= cwidth/2 + 90 && y >= cheight/2 - 70 && y <= cheight/2 - 25) {
resetGame()
screen = 1
}
} else if (screen == 3) {
if (x >= cwidth/2 - 100 && x <= cwidth/2 + 100 && y >= cheight/2 - 90 && y <= cheight/2 - 45) {
resetGame()
screen = 1
}
}
}
// ============================================================
// MAIN GAME LOOP
// ============================================================
animateWithCanvasDraw { canvas =>
if (screen == 0) {
drawLetterScreen(canvas)
} else if (screen == 1) {
updatePlayerMovement()
frameCounter += 1
if (frameCounter >= 60) {
frameCounter = 0
if (gameTimer > 0) {
gameTimer -= 1
} else {
showFinishLine = true
}
}
drawGameplayScreen(canvas)
} else if (screen == 2) {
drawGameOverScreen(canvas)
} else if (screen == 3) {
drawVictoryScreen(canvas)
}
}