Code Sketch
sniper_0718
cleari()
// --- Canvas & Road Setup ---
val canvasWidth = 800
val canvasHeight = 600
val roadWidth = 340
val bg = Picture.rectangle(canvasWidth, canvasHeight)
bg.setFillColor(color(10, 25, 10))
bg.setPenColor(noColor)
bg.setPosition(-canvasWidth / 2, -canvasHeight / 2)
bg.draw()
val road = Picture.rectangle(roadWidth, canvasHeight)
road.setFillColor(color(35, 35, 38))
road.setPenColor(noColor)
road.setPosition(-roadWidth / 2, -canvasHeight / 2)
road.draw()
// --- Road Lines ---
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()
// --- Dashes ---
val dashCount = 8
val dashHeight = 40
val dashGap = 50
var dashOffset = 0.0
val yellowDashesL = Array.fill(dashCount) {
val d = Picture.rectangle(4, dashHeight)
d.setFillColor(color(255, 204, 0))
d.setPenColor(noColor)
d.draw()
d
}
def updateDashes(): Unit = {
dashOffset = (dashOffset - 12) % (dashHeight + dashGap)
for (i <- 0 until dashCount) {
val yPos = (canvasHeight / 2) - (i * (dashHeight + dashGap)) + dashOffset
yellowDashesL(i).setPosition(-2, yPos)
}
}
// --- ROUTE & WALLET DATA ---
case class RouteInfo(name: String, distance: Double, reward: Int)
val routesList = Array(
RouteInfo("Pune -> Satara", 1500.0, 1500),
RouteInfo("Solapur -> Kolhapur", 1500.0, 1500),
RouteInfo("Mumbai -> Karnatak", 3000.0, 3000)
)
var currentRouteIdx = 0
var playerWallet = 1000
var distanceMeters = routesList(currentRouteIdx).distance
// --- OPEN BALANCE DISPLAY (NO BOX) ---
val walletText = Picture.text(s"BALANCE: ?$playerWallet", 18)
walletText.setFillColor(color(0, 255, 120))
walletText.setPosition(-canvasWidth / 2 + 20, canvasHeight / 2 - 35)
walletText.draw()
// --- GPS TRACKER (WITH TOLL MARKER) ---
val mapBg = Picture.rectangle(170, 90)
mapBg.setFillColor(color(15, 20, 35))
mapBg.setPenColor(cyan)
mapBg.setPosition(canvasWidth / 2 - 190, canvasHeight / 2 - 110)
mapBg.draw()
val mapRoad = Picture.rectangle(140, 8)
mapRoad.setFillColor(color(60, 60, 70))
mapRoad.setPosition(canvasWidth / 2 - 175, canvasHeight / 2 - 70)
mapRoad.draw()
val mapTitle = Picture.text("GPS TRACKER", 11)
mapTitle.setFillColor(color(0, 230, 255))
mapTitle.setPosition(canvasWidth / 2 - 180, canvasHeight / 2 - 35)
mapTitle.draw()
// Toll Pin Marker on GPS Map
val mapTollPin = Picture.text("T", 12)
mapTollPin.setFillColor(red)
val mapPlayerPin = Picture.circle(5)
mapPlayerPin.setFillColor(yellow)
mapPlayerPin.setPosition(canvasWidth / 2 - 175, canvasHeight / 2 - 70)
mapPlayerPin.draw()
// --- DESTINATION LIST PANEL ('M' Key) ---
val listPanelBg = Picture.rectangle(340, 190)
listPanelBg.setFillColor(color(15, 15, 25))
listPanelBg.setPenColor(cyan)
listPanelBg.setPosition(-170, -95)
val listHeader = Picture.text("--- ROUTE DESTINATION LIST ---", 14)
listHeader.setFillColor(color(255, 200, 0))
listHeader.setPosition(-150, 65)
val routeItem1 = Picture.text("1. Pune to Satara (1500m) - Reward: ?1500", 12)
routeItem1.setFillColor(white); routeItem1.setPosition(-155, 30)
val routeItem2 = Picture.text("2. Solapur to Kolhapur (1500m) - Reward: ?1500", 12)
routeItem2.setFillColor(white); routeItem2.setPosition(-155, 0)
val routeItem3 = Picture.text("3. Mumbai to Karnatak (3000m) - Reward: ?3000", 12)
routeItem3.setFillColor(white); routeItem3.setPosition(-155, -30)
val listCloseHint = Picture.text("Press 'M' to Close Menu", 11)
listCloseHint.setFillColor(gray); listCloseHint.setPosition(-140, -65)
var showDestinationList = false
var mKeyWasPressed = false
// --- TOLL NAKA GRAPHICS ---
var isTollActive = false
var tollY = canvasHeight / 2.0 + 500.0
var tollGateOpen = false
var tKeyWasPressed = false
var tollPaidForCurrent = false
val tollPlazaRoof = Picture.rectangle(roadWidth + 80, 50)
tollPlazaRoof.setFillColor(color(220, 30, 30))
tollPlazaRoof.setPenColor(white)
val tollPlazaText = Picture.text("TOLL PLAZA - TAX ?500", 15)
tollPlazaText.setFillColor(white)
val tollPillarL = Picture.rectangle(20, 70)
tollPillarL.setFillColor(color(200, 200, 200))
val tollPillarR = Picture.rectangle(20, 70)
tollPillarR.setFillColor(color(200, 200, 200))
val tollGateBar = Picture.rectangle(roadWidth - 20, 14)
tollGateBar.setFillColor(color(255, 215, 0))
tollGateBar.setPenColor(black)
val tollSignalAlert = Picture.text("?? TOLL PLAZA AHEAD! SLOW DOWN", 15)
tollSignalAlert.setFillColor(color(255, 215, 0))
tollSignalAlert.setPosition(-170, 160)
val tollPayHint = Picture.text("PRESS 'T' TO PAY ?500 TOLL & OPEN BARRIER", 14)
tollPayHint.setFillColor(color(0, 255, 120))
tollPayHint.setPosition(-185, 180)
def drawTollNaka(): Unit = {
if (isTollActive) {
tollPlazaRoof.setPosition(-roadWidth / 2 - 40, tollY + 20); tollPlazaRoof.draw()
tollPlazaText.setPosition(-100, tollY + 35); tollPlazaText.draw()
tollPillarL.setPosition(-roadWidth / 2 - 15, tollY - 30); tollPillarL.draw()
tollPillarR.setPosition(roadWidth / 2 - 5, tollY - 30); tollPillarR.draw()
if (!tollGateOpen) {
tollGateBar.setPosition(-roadWidth / 2 + 10, tollY - 10); tollGateBar.draw()
} else {
tollGateBar.erase()
}
} else {
tollPlazaRoof.erase(); tollPlazaText.erase()
tollPillarL.erase(); tollPillarR.erase(); tollGateBar.erase()
}
}
// --- PARKING BAY ---
val parkingBay = Picture.rectangle(85, 140)
parkingBay.setFillColor(color(0, 220, 80))
parkingBay.setPenColor(yellow)
var parkingY = canvasHeight / 2.0 + 400.0
val parkingText = Picture.text("PARK HERE", 12)
parkingText.setFillColor(white)
// --- PLAYER TRUCK ---
val playerCab = Picture.rectangle(52, 40)
playerCab.setFillColor(color(245, 245, 250))
playerCab.setPenColor(black)
val playerGlass = Picture.rectangle(44, 16)
playerGlass.setFillColor(color(20, 40, 60))
playerGlass.setPenColor(noColor)
val playerBed = Picture.rectangle(50, 65)
playerBed.setFillColor(color(180, 40, 40))
playerBed.setPenColor(black)
playerBed.draw(); playerCab.draw(); playerGlass.draw()
var carX = -26.0
var carY = -220.0
val carSteerSpeed = 6.0
def updatePlayerPos(): Unit = {
playerBed.setPosition(carX + 1, carY)
playerCab.setPosition(carX + 1, carY + 63)
playerGlass.setPosition(carX + 5, carY + 80)
}
updatePlayerPos()
// --- HUD Displays ---
var gameOver = false
var routeCompleted = false
val hudText = Picture.text("", 15)
hudText.setFillColor(white)
hudText.setPosition(-canvasWidth / 2 + 230, canvasHeight / 2 - 35)
hudText.draw()
val helpText = Picture.text("Drive: SPACE | Steer: LEFT/RIGHT | Pay Toll: 'T' | Menu: 'M' | Park: 'P'", 12)
helpText.setFillColor(color(0, 230, 255))
helpText.setPosition(-canvasWidth / 2 + 20, -canvasHeight / 2 + 20)
helpText.draw()
val victoryText = Picture.text("", 20)
victoryText.setFillColor(color(0, 255, 100))
victoryText.setPosition(-250, 0)
val gameOverText = Picture.text("CRASHED INTO TOLL BARRIER! Press 'R' to Restart", 18)
gameOverText.setFillColor(color(255, 50, 50))
gameOverText.setPosition(-240, 0)
// --- Game Loop ---
animate {
if (!gameOver && !routeCompleted) {
val currentRoute = routesList(currentRouteIdx)
hudText.update(s"ROUTE: ${currentRoute.name} | DIST: ${distanceMeters.toInt} M")
walletText.update(s"BALANCE: ?$playerWallet")
if (isKeyPressed(Kc.VK_LEFT)) carX -= carSteerSpeed
if (isKeyPressed(Kc.VK_RIGHT)) carX += carSteerSpeed
val minX = -roadWidth / 2 + 12
val maxX = roadWidth / 2 - 64
if (carX < minX) carX = minX
if (carX > maxX) carX = maxX
// Menu Control ('M')
val mPressedNow = isKeyPressed(Kc.VK_M)
if (mPressedNow && !mKeyWasPressed) {
showDestinationList = !showDestinationList
if (showDestinationList) {
listPanelBg.draw(); listHeader.draw(); routeItem1.draw(); routeItem2.draw(); routeItem3.draw(); listCloseHint.draw()
} else {
listPanelBg.erase(); listHeader.erase(); routeItem1.erase(); routeItem2.erase(); routeItem3.erase(); listCloseHint.erase()
}
}
mKeyWasPressed = mPressedNow
// TOLL TRIGGER & MAP DISPLAY
val triggerTollDist = currentRoute.distance - 700.0
// Map Toll Marker Position
val tollRatio = (currentRoute.distance - triggerTollDist) / currentRoute.distance
val mapTollX = (canvasWidth / 2 - 175) + (tollRatio * 135.0)
mapTollPin.setPosition(mapTollX, canvasHeight / 2 - 65)
mapTollPin.draw()
if (distanceMeters <= triggerTollDist && distanceMeters >= triggerTollDist - 300 && !tollPaidForCurrent) {
tollSignalAlert.draw()
} else {
tollSignalAlert.erase()
}
if (distanceMeters <= triggerTollDist - 100 && !isTollActive && !tollPaidForCurrent) {
isTollActive = true
tollY = canvasHeight / 2.0 + 400.0
tollGateOpen = false
}
// TOLL PAYMENT ('T')
val tPressedNow = isKeyPressed(Kc.VK_T)
if (tPressedNow && !tKeyWasPressed && isTollActive) {
if (Math.abs(carY - (tollY - 30)) < 220 && !tollGateOpen) {
if (playerWallet >= 500) {
playerWallet -= 500
tollGateOpen = true
tollPaidForCurrent = true
tollPayHint.erase()
}
}
}
tKeyWasPressed = tPressedNow
if (isTollActive && !tollGateOpen && Math.abs(carY - (tollY - 30)) < 220) {
tollPayHint.draw()
} else {
tollPayHint.erase()
}
// DRIVING MECHANIC
if (isKeyPressed(Kc.VK_SPACE)) {
updateDashes()
if (distanceMeters > 0) {
distanceMeters -= 1.5
}
val progressRatio = (currentRoute.distance - distanceMeters) / currentRoute.distance
val mapPinX = (canvasWidth / 2 - 175) + (progressRatio * 135.0)
mapPlayerPin.setPosition(mapPinX, canvasHeight / 2 - 70)
// Toll Movement
if (isTollActive) {
tollY -= 5.0
drawTollNaka()
// Hit Toll Barrier Collision
if (!tollGateOpen && Math.abs((carY + 50) - (tollY - 10)) < 15) {
gameOver = true
gameOverText.draw()
}
if (tollY < -canvasHeight / 2 - 120) {
isTollActive = false
drawTollNaka()
}
}
// Parking Movement
if (distanceMeters <= 0) {
if (parkingY > 50) parkingY -= 5.0
parkingBay.setPosition(roadWidth / 2 + 5, parkingY)
parkingBay.draw()
parkingText.setPosition(roadWidth / 2 + 12, parkingY + 60)
parkingText.draw()
}
}
// DESTINATION PARKING CLAIM
val inParkingArea = carX > roadWidth / 2 - 75 && carY >= parkingY - 20 && carY <= parkingY + 100
if (distanceMeters <= 0 && inParkingArea && isKeyPressed(Kc.VK_P)) {
routeCompleted = true
playerWallet += currentRoute.reward
walletText.update(s"BALANCE: ?$playerWallet")
victoryText.update(s"DESTINATION REACHED! EARNED ?${currentRoute.reward}!")
victoryText.draw()
}
updatePlayerPos()
} else if (gameOver || routeCompleted) {
if (isKeyPressed(Kc.VK_R)) {
if (routeCompleted) {
currentRouteIdx = (currentRouteIdx + 1) % routesList.length
}
gameOver = false
routeCompleted = false
distanceMeters = routesList(currentRouteIdx).distance
isTollActive = false
tollGateOpen = false
tollPaidForCurrent = false
parkingY = canvasHeight / 2.0 + 400.0
parkingBay.erase()
parkingText.erase()
drawTollNaka()
gameOverText.erase()
victoryText.erase()
carX = -26.0
updatePlayerPos()
}
}
}