Code Sketch
sniper_0718
// Clear screen and setup canvas
cleari()
setBackground(black)
// --- Helper: Draw Curved Square App Icon ---
def drawCurvedSquare(x: Double, y: Double, size: Double, fillColor: Color, label: String): Unit = {
val box = Picture.rectangle(size, size)
.withFillColor(fillColor)
.withPenColor(fillColor)
val txt = Picture.text(label)
.withPenColor(black)
val btn = picStackCentered(box, txt)
btn.setPosition(x + size/2, y + size/2)
btn.draw()
}
// ==========================================
// GAME 1: LAND ROVER DEFENDER CAR GAME
// ==========================================
def runCarGame(): Unit = {
cleari()
val canvasWidth = 800
val canvasHeight = 600
val roadWidth = 360
val bg = Picture.rectangle(canvasWidth, canvasHeight)
bg.setFillColor(Color(70, 160, 70, 255))
bg.setPenColor(noColor)
bg.setPosition(-canvasWidth / 2, -canvasHeight / 2)
bg.draw()
val road = Picture.rectangle(roadWidth, canvasHeight)
road.setFillColor(Color(35, 35, 38, 255))
road.setPenColor(noColor)
road.setPosition(-roadWidth / 2, -canvasHeight / 2)
road.draw()
val lineLeft = Picture.rectangle(6, canvasHeight)
lineLeft.setFillColor(white)
lineLeft.setPenColor(noColor)
lineLeft.setPosition(-roadWidth / 2 + 5, -canvasHeight / 2)
lineLeft.draw()
val lineRight = Picture.rectangle(6, canvasHeight)
lineRight.setFillColor(white)
lineRight.setPenColor(noColor)
lineRight.setPosition(roadWidth / 2 - 11, -canvasHeight / 2)
lineRight.draw()
val centerDivider1 = Picture.rectangle(3, canvasHeight)
centerDivider1.setFillColor(Color(255, 204, 0, 255))
centerDivider1.setPenColor(noColor)
centerDivider1.setPosition(-4, -canvasHeight / 2)
centerDivider1.draw()
val centerDivider2 = Picture.rectangle(3, canvasHeight)
centerDivider2.setFillColor(Color(255, 204, 0, 255))
centerDivider2.setPenColor(noColor)
centerDivider2.setPosition(1, -canvasHeight / 2)
centerDivider2.draw()
val dashCount = 8
val dashHeight = 40
val dashGap = 50
var dashOffset = 0.0
val whiteDashesL = Array.fill(dashCount) {
val d = Picture.rectangle(3, dashHeight)
d.setFillColor(Color(200, 200, 200, 150))
d.setPenColor(noColor)
d.draw()
d
}
val whiteDashesR = Array.fill(dashCount) {
val d = Picture.rectangle(3, dashHeight)
d.setFillColor(Color(200, 200, 200, 150))
d.setPenColor(noColor)
d.draw()
d
}
def updateDashes(moveSpeed: Double): Unit = {
dashOffset = (dashOffset - moveSpeed) % (dashHeight + dashGap)
for (i <- 0 until dashCount) {
val yPos = (canvasHeight / 2) - (i * (dashHeight + dashGap)) + dashOffset
whiteDashesL(i).setPosition(-roadWidth / 4, yPos)
whiteDashesR(i).setPosition(roadWidth / 4, yPos)
}
}
val destFixedY = 120.0
val destWidth = 110
val destHeight = 90
val building = Picture.rectangle(destWidth, destHeight)
building.setFillColor(Color(70, 40, 90, 255))
building.setPenColor(white)
val roof = Picture.rectangle(destWidth + 10, 15)
roof.setFillColor(Color(200, 50, 50, 255))
roof.setPenColor(noColor)
val destSign = Picture.text("HOTEL DELUXE", 11)
destSign.setFillColor(yellow)
val parkingSpotX = (roadWidth / 2 + 15).toDouble
val parkingSpotWidth = 70
val parkingSpotHeight = 100
val parkingSpot = Picture.rectangle(parkingSpotWidth, parkingSpotHeight)
parkingSpot.setFillColor(Color(50, 50, 55, 255))
parkingSpot.setPenColor(white)
val parkingSign = Picture.text("P", 30)
parkingSign.setFillColor(Color(0, 230, 255, 255))
def updateDestinationPosition(): Unit = {
building.setPosition(parkingSpotX, destFixedY + 110)
roof.setPosition(parkingSpotX - 5, destFixedY + 110 + destHeight)
destSign.setPosition(parkingSpotX + 5, destFixedY + 110 + destHeight - 20)
parkingSpot.setPosition(parkingSpotX, destFixedY)
parkingSign.setPosition(parkingSpotX + 22, destFixedY + 32)
}
def hideDestination(): Unit = {
building.setPosition(-1000, -1000)
roof.setPosition(-1000, -1000)
destSign.setPosition(-1000, -1000)
parkingSpot.setPosition(-1000, -1000)
parkingSign.setPosition(-1000, -1000)
}
def showDestination(): Unit = {
updateDestinationPosition()
}
hideDestination()
val playerBody = Picture.rectangle(54, 100)
playerBody.setFillColor(Color(245, 245, 250, 255))
playerBody.setPenColor(gray)
val playerRoof = Picture.rectangle(48, 42)
playerRoof.setFillColor(Color(215, 215, 220, 255))
playerRoof.setPenColor(gray)
val playerRack = Picture.rectangle(44, 30)
playerRack.setFillColor(Color(30, 30, 30, 255))
playerRack.setPenColor(noColor)
val playerGlassF = Picture.rectangle(42, 16)
playerGlassF.setFillColor(Color(20, 30, 45, 255))
playerGlassF.setPenColor(noColor)
val playerGlassR = Picture.rectangle(42, 18)
playerGlassR.setFillColor(Color(20, 30, 45, 255))
playerGlassR.setPenColor(noColor)
val playerSpareWheel = Picture.rectangle(16, 20)
playerSpareWheel.setFillColor(Color(40, 40, 40, 255))
playerSpareWheel.setPenColor(black)
val playerTailL = Picture.rectangle(6, 6)
playerTailL.setFillColor(Color(220, 20, 20, 255))
playerTailL.setPenColor(noColor)
val playerTailR = Picture.rectangle(6, 6)
playerTailR.setFillColor(Color(220, 20, 20, 255))
playerTailR.setPenColor(noColor)
val playerHeadL = Picture.rectangle(10, 8)
playerHeadL.setFillColor(yellow)
playerHeadL.setPenColor(noColor)
val playerHeadR = Picture.rectangle(10, 8)
playerHeadR.setFillColor(yellow)
playerHeadR.setPenColor(noColor)
val beamL = Picture.fromPath { p =>
p.moveTo(0, 0)
p.lineTo(-45, 170)
p.lineTo(20, 170)
p.lineTo(9, 0)
}
beamL.setFillColor(Color(245, 245, 255, 140))
beamL.setPenColor(noColor)
val beamR = Picture.fromPath { p =>
p.moveTo(0, 0)
p.lineTo(-20, 170)
p.lineTo(45, 170)
p.lineTo(9, 0)
}
beamR.setFillColor(Color(245, 245, 255, 140))
beamR.setPenColor(noColor)
playerBody.draw()
playerRoof.draw()
playerRack.draw()
playerGlassF.draw()
playerGlassR.draw()
playerSpareWheel.draw()
playerTailL.draw()
playerTailR.draw()
playerHeadL.draw()
playerHeadR.draw()
val enemyBody = Picture.rectangle(52, 95)
enemyBody.setFillColor(Color(200, 30, 30, 255))
enemyBody.setPenColor(gray)
val enemyRoof = Picture.rectangle(44, 34)
enemyRoof.setFillColor(Color(120, 20, 20, 255))
enemyRoof.setPenColor(noColor)
val enemyGlass = Picture.rectangle(44, 18)
enemyGlass.setFillColor(Color(50, 50, 70, 255))
enemyGlass.setPenColor(noColor)
val enemyHeadL = Picture.rectangle(8, 6)
enemyHeadL.setFillColor(yellow)
enemyHeadL.setPenColor(noColor)
val enemyHeadR = Picture.rectangle(8, 6)
enemyHeadR.setFillColor(yellow)
enemyHeadR.setPenColor(noColor)
enemyBody.draw()
enemyRoof.draw()
enemyGlass.draw()
enemyHeadL.draw()
enemyHeadR.draw()
val leftTrafficBody = Picture.rectangle(52, 95)
leftTrafficBody.setFillColor(Color(30, 140, 200, 255))
leftTrafficBody.setPenColor(gray)
val leftTrafficRoof = Picture.rectangle(44, 34)
leftTrafficRoof.setFillColor(Color(15, 80, 130, 255))
leftTrafficRoof.setPenColor(noColor)
val leftTrafficGlass = Picture.rectangle(44, 18)
leftTrafficGlass.setFillColor(Color(40, 60, 80, 255))
leftTrafficGlass.setPenColor(noColor)
val leftTrafficTailL = Picture.rectangle(8, 6)
leftTrafficTailL.setFillColor(Color(220, 20, 20, 255))
leftTrafficTailL.setPenColor(noColor)
val leftTrafficTailR = Picture.rectangle(8, 6)
leftTrafficTailR.setFillColor(Color(220, 20, 20, 255))
leftTrafficTailR.setPenColor(noColor)
leftTrafficBody.draw()
leftTrafficRoof.draw()
leftTrafficGlass.draw()
leftTrafficTailL.draw()
leftTrafficTailR.draw()
var carX = -100.0
var carY = -220.0
val carSteerSpeed = 6.0
var currentPlayerSpeed = 0.0
var enemyX = 40.0
var enemyY = 420.0
var enemySpeed = 6.0
var leftTrafficX = -100.0
var leftTrafficY = 650.0
var leftTrafficSpeed = 3.0
var isLightActive = false
var currentLevel = 1
var levelDistance = 0.0
val targetDistancePerLevel = 600.0
var gameOver = false
var gameWon = false
var score = 0
var levelTransitionTimer = 0.0
var destinationShown = false
def updatePlayerPos(): Unit = {
playerBody.setPosition(carX, carY)
playerRoof.setPosition(carX + 3, carY + 29)
playerRack.setPosition(carX + 5, carY + 35)
playerGlassF.setPosition(carX + 6, carY + 68)
playerGlassR.setPosition(carX + 6, carY + 44)
playerSpareWheel.setPosition(carX + 19, carY + 4)
playerTailL.setPosition(carX + 4, carY + 2)
playerTailR.setPosition(carX + 44, carY + 2)
playerHeadL.setPosition(carX + 4, carY + 92)
playerHeadR.setPosition(carX + 40, carY + 92)
if (isLightActive) {
beamL.setPosition(carX + 4, carY + 98)
beamR.setPosition(carX + 40, carY + 98)
}
}
def updateEnemyPos(): Unit = {
enemyBody.setPosition(enemyX, enemyY)
enemyRoof.setPosition(enemyX + 4, enemyY + 28)
enemyGlass.setPosition(enemyX + 4, enemyY + 20)
enemyHeadL.setPosition(enemyX + 2, enemyY + 2)
enemyHeadR.setPosition(enemyX + 42, enemyY + 2)
}
def updateLeftTrafficPos(): Unit = {
leftTrafficBody.setPosition(leftTrafficX, leftTrafficY)
leftTrafficRoof.setPosition(leftTrafficX + 4, leftTrafficY + 28)
leftTrafficGlass.setPosition(leftTrafficX + 4, leftTrafficY + 58)
leftTrafficTailL.setPosition(leftTrafficX + 2, leftTrafficY + 2)
leftTrafficTailR.setPosition(leftTrafficX + 42, leftTrafficY + 2)
}
def resetEnemy(): Unit = {
enemyX = random(20, (roadWidth / 2 - 65).toInt)
enemyY = canvasHeight / 2 + 180
enemySpeed = currentLevel match {
case 1 => 6.0
case 2 => 10.0
case 3 => 15.0
}
updateEnemyPos()
}
def resetLeftTraffic(): Unit = {
leftTrafficX = random((-roadWidth / 2 + 15).toInt, -65)
leftTrafficY = canvasHeight / 2 + 380
leftTrafficSpeed = currentLevel match {
case 1 => 2.0
case 2 => 5.0
case 3 => 8.0
}
updateLeftTrafficPos()
}
def setupLevelTheme(): Unit = {
currentLevel match {
case 1 =>
bg.setFillColor(Color(70, 160, 70, 255))
building.setFillColor(Color(70, 40, 90, 255))
roof.setFillColor(Color(200, 50, 50, 255))
destSign.update("HOTEL DELUXE")
case 2 =>
bg.setFillColor(Color(190, 140, 70, 255))
building.setFillColor(Color(130, 70, 40, 255))
roof.setFillColor(Color(240, 180, 40, 255))
destSign.update("SUNSET VILLA")
case 3 =>
bg.setFillColor(Color(20, 25, 45, 255))
building.setFillColor(Color(30, 90, 110, 255))
roof.setFillColor(Color(220, 40, 120, 255))
destSign.update("BEACH CLUB")
}
hideDestination()
destinationShown = false
}
resetEnemy()
resetLeftTraffic()
updatePlayerPos()
setupLevelTheme()
val hudText = Picture.text("", 15)
hudText.setFillColor(Color(20, 20, 20, 255))
hudText.setPosition(-canvasWidth / 2 + 15, canvasHeight / 2 - 35)
hudText.draw()
val statusText = Picture.text("", 24)
statusText.setPosition(-240, 0)
animate {
if (!gameOver && !gameWon) {
if (levelDistance < targetDistancePerLevel) {
if (isKeyPressed(Kc.VK_SPACE)) {
currentPlayerSpeed = 7.0 + (currentLevel * 2.0)
} else if (isKeyPressed(Kc.VK_DOWN)) {
currentPlayerSpeed = -4.0
} else if (isKeyPressed(Kc.VK_B)) {
currentPlayerSpeed = 0.0
} else {
if (currentPlayerSpeed > 0) currentPlayerSpeed = Math.max(0.0, currentPlayerSpeed - 0.5)
if (currentPlayerSpeed < 0) currentPlayerSpeed = Math.min(0.0, currentPlayerSpeed + 0.5)
}
} else {
currentPlayerSpeed = 0.0
}
if (isKeyPressed(Kc.VK_LEFT)) carX -= carSteerSpeed
if (isKeyPressed(Kc.VK_RIGHT)) carX += carSteerSpeed
val minX = -canvasWidth / 2 + 20
val maxX = canvasWidth / 2 - 70
if (carX < minX) carX = minX
if (carX > maxX) carX = maxX
updateDashes(currentPlayerSpeed)
if (currentPlayerSpeed != 0.0 && levelDistance < targetDistancePerLevel) {
levelDistance += currentPlayerSpeed * 0.2
if (levelDistance < 0) levelDistance = 0.0
}
val speedKmh = (currentPlayerSpeed * 12).toInt
val levelLabel = currentLevel match {
case 1 => "1 (HOTEL)"
case 2 => "2 (VILLA)"
case 3 => "3 (CLUB)"
}
hudText.update("LEVEL: " + levelLabel + " | SCORE: " + score + " | SPEED: " + speedKmh + " KM/H")
if (levelDistance >= targetDistancePerLevel) {
if (!destinationShown) {
showDestination()
destinationShown = true
}
if (carY < destFixedY) carY += 4.0
if (carX < parkingSpotX - 10) carX += 1.0
else if (carX > parkingSpotX + 10) carX -= 1.0
val isInsideSpotX = carX >= (parkingSpotX - 35) && (carX + 54) <= (parkingSpotX + parkingSpotWidth + 35)
val isInsideSpotY = carY >= (destFixedY - 40) && (carY + 100) <= (destFixedY + parkingSpotHeight + 40)
if (isInsideSpotX && isInsideSpotY) {
levelTransitionTimer += 1.0
if (levelTransitionTimer > 180.0) {
levelTransitionTimer = 0.0
if (currentLevel < 3) {
currentLevel += 1
levelDistance = 0.0
carY = -220.0
setupLevelTheme()
resetEnemy()
resetLeftTraffic()
} else {
gameWon = true
statusText.setFillColor(Color(50, 255, 50, 255))
statusText.update("WON! Press 'R'")
statusText.draw()
}
} else {
statusText.setFillColor(Color(0, 230, 255, 255))
statusText.update("PARKED! Next level in...")
statusText.draw()
}
}
}
if (isKeyPressed(Kc.VK_A)) {
if (!isLightActive) {
isLightActive = true
playerHeadL.setFillColor(Color(245, 245, 255, 255))
playerHeadR.setFillColor(Color(245, 245, 255, 255))
beamL.draw()
beamR.draw()
}
} else {
if (isLightActive) {
isLightActive = false
playerHeadL.setFillColor(yellow)
playerHeadR.setFillColor(yellow)
beamL.erase()
beamR.erase()
}
}
updatePlayerPos()
if (levelDistance < targetDistancePerLevel) {
enemyY -= (enemySpeed + currentPlayerSpeed * 0.5)
if (enemyY < -canvasHeight / 2 - 120) {
if (currentPlayerSpeed > 0) score += 10
resetEnemy()
}
}
updateEnemyPos()
if (levelDistance < targetDistancePerLevel) {
leftTrafficY -= (currentPlayerSpeed - leftTrafficSpeed)
if (leftTrafficY < -canvasHeight / 2 - 120) {
if (currentPlayerSpeed > 0) score += 15
resetLeftTraffic()
}
}
updateLeftTrafficPos()
val crashEnemy = Math.abs((carX + 27) - (enemyX + 26)) < 44 && Math.abs((carY + 50) - (enemyY + 47)) < 82
val crashLeftTraffic = Math.abs((carX + 27) - (leftTrafficX + 26)) < 44 && Math.abs((carY + 50) - (leftTrafficY + 47)) < 82
if ((crashEnemy || crashLeftTraffic) && levelDistance < targetDistancePerLevel) {
gameOver = true
statusText.setFillColor(Color(255, 50, 50, 255))
statusText.update("CRASHED! Press 'R'")
statusText.draw()
}
} else {
if (isKeyPressed(Kc.VK_R)) {
gameOver = false
gameWon = false
currentLevel = 1
levelDistance = 0.0
score = 0
currentPlayerSpeed = 0.0
setupLevelTheme()
statusText.erase()
carX = -100.0
carY = -220.0
resetEnemy()
resetLeftTraffic()
updatePlayerPos()
}
}
}
}
// ==========================================
// MAIN MENU / LAUNCHER ("BABU APP")
// ==========================================
def runBabuApp(): Unit = {
cleari()
setBackground(darkGray)
val phoneFrame = Picture.rectangle(340, 540)
.withPenColor(white)
.withFillColor(black)
phoneFrame.setPosition(-170, -270)
phoneFrame.draw()
val title = Picture.text("Babu App Menu")
.withPenColor(cyan)
title.setPosition(-60, 200)
title.draw()
val subTitle = Picture.text("Click an App Icon below", 12)
.withPenColor(white)
subTitle.setPosition(-65, 170)
subTitle.draw()
drawCurvedSquare(-80, 50, 90, pink, "Car Game")
drawCurvedSquare(20, 50, 90, green, "Truck Game")
onMouseClick { (x, y) =>
if (x >= -80 && x <= 10 && y >= 50 && y <= 140) {
runCarGame()
}
}
}
// ==========================================
// LOCK SCREEN LOGIN (USING readln POPUP)
// ==========================================
def runLockScreen(): Unit = {
val lockFrame = Picture.rectangle(340, 540)
.withPenColor(white)
.withFillColor(darkGray)
lockFrame.setPosition(-170, -270)
lockFrame.draw()
val lockTitle = Picture.text("Babu App - Locked")
.withPenColor(yellow)
lockTitle.setPosition(-70, 120)
lockTitle.draw()
val boxPrompt = Picture.text("Click the box below to login:")
.withPenColor(white)
boxPrompt.setPosition(-110, 90)
boxPrompt.draw()
val inputBoxBg = Picture.rectangle(240, 50)
.withPenColor(cyan)
.withFillColor(black)
inputBoxBg.setPosition(-120, 20)
inputBoxBg.draw()
val boxText = Picture.text("Enter Password")
.withPenColor(cyan)
boxText.setPosition(-65, 35)
boxText.draw()
val errDisplay = Picture.text("")
.withPenColor(red)
errDisplay.setPosition(-100, -50)
errDisplay.draw()
onMouseClick { (x, y) =>
if (x >= -120 && x <= 120 && y >= 20 && y <= 70) {
// Using readln for Kojo popup dialog input
val enteredPassword = readln("Enter Password to open Babu App:").trim
if (enteredPassword == "aishu") {
println("Access Granted! Opening Babu App...")
runBabuApp()
} else {
println("Wrong Password! Access Denied.")
errDisplay.update("Wrong Password! Try Again.")
}
}
}
}
// Start the lock screen when the program runs
runLockScreen()