Code Sketch


sniper_0718
By: Mhalsakant School
Category: Art
cleari()
disablePanAndZoom()
drawStage(ColorMaker.darkGray)

val cb = canvasBounds //> val cb: edu.umd.cs.piccolo.util.PBounds = PBounds[x=-387.5,y=-263.5,width=775.0,height=527.0]

// One-way Road background
val road = Picture.rectangle(320, cb.height).thatsFilledWith(ColorMaker.darkGray).thatsStrokeColored(ColorMaker.gray) //> val road: net.kogics.kojo.core.Picture = PostDrawTransform (Id: 430971932 -> PostDrawTransform (Id: 1663416654 -> Picture with Id: 735671940))
road.setPosition(cb.x + cb.width / 2 - 160, cb.y)
road.draw()

// Road side borders
val leftBorder = Picture.rectangle(6, cb.height).thatsFilledWith(ColorMaker.white) //> val leftBorder: net.kogics.kojo.core.Picture = PostDrawTransform (Id: 793254896 -> Picture with Id: 1462046727)
leftBorder.setPosition(cb.x + cb.width / 2 - 160, cb.y)
leftBorder.draw()

val rightBorder = Picture.rectangle(6, cb.height).thatsFilledWith(ColorMaker.white) //> val rightBorder: net.kogics.kojo.core.Picture = PostDrawTransform (Id: 346857048 -> Picture with Id: 315068997)
rightBorder.setPosition(cb.x + cb.width / 2 + 154, cb.y)
rightBorder.draw()

// Dashed lane divider lines for one-way traffic
val laneLine1 = Picture.rectangle(4, cb.height).thatsFilledWith(ColorMaker.yellow) //> val laneLine1: net.kogics.kojo.core.Picture = PostDrawTransform (Id: 1896569211 -> Picture with Id: 1947751058)
laneLine1.setPosition(cb.x + cb.width / 2 - 53, cb.y)
laneLine1.draw()

val laneLine2 = Picture.rectangle(4, cb.height).thatsFilledWith(ColorMaker.yellow) //> val laneLine2: net.kogics.kojo.core.Picture = PostDrawTransform (Id: 1792395863 -> Picture with Id: 1818642963)
laneLine2.setPosition(cb.x + cb.width / 2 + 53, cb.y)
laneLine2.draw()

// Realistic Top-Down Bus Graphic
def createBus(): Picture = {
  val body = Picture.rectangle(55, 110).thatsFilledWith(ColorMaker.yellow).thatsStrokeColored(ColorMaker.black).thatsTranslated(0, 0)
  val windshield = Picture.rectangle(45, 22).thatsFilledWith(ColorMaker.cyan).thatsStrokeColored(ColorMaker.black).thatsTranslated(5, 78)
  val roofHatch = Picture.rectangle(35, 45).thatsFilledWith(ColorMaker.gray).thatsStrokeColored(ColorMaker.black).thatsTranslated(10, 32)
  val wheelL = Picture.rectangle(8, 25).thatsFilledWith(ColorMaker.black).thatsTranslated(-4, 75)
  val wheelR = Picture.rectangle(8, 25).thatsFilledWith(ColorMaker.black).thatsTranslated(51, 75)
  val wheelL2 = Picture.rectangle(8, 25).thatsFilledWith(ColorMaker.black).thatsTranslated(-4, 15)
  val wheelR2 = Picture.rectangle(8, 25).thatsFilledWith(ColorMaker.black).thatsTranslated(51, 15)
  picStack(body, windshield, roofHatch, wheelL, wheelR, wheelL2, wheelR2)
} //> def createBus(): builtins.Picture

// Realistic Top-Down Traffic Car Graphic
def createTraffic(): Picture = {
  val body = Picture.rectangle(48, 90).thatsFilledWith(ColorMaker.red).thatsStrokeColored(ColorMaker.black).thatsTranslated(0, 0)
  val windshield = Picture.rectangle(38, 18).thatsFilledWith(ColorMaker.cyan).thatsStrokeColored(ColorMaker.black).thatsTranslated(5, 60)
  val rearWindow = Picture.rectangle(38, 12).thatsFilledWith(ColorMaker.cyan).thatsStrokeColored(ColorMaker.black).thatsTranslated(5, 12)
  val wheelL = Picture.rectangle(8, 20).thatsFilledWith(ColorMaker.black).thatsTranslated(-4, 55)
  val wheelR = Picture.rectangle(8, 20).thatsFilledWith(ColorMaker.black).thatsTranslated(44, 55)
  val wheelL2 = Picture.rectangle(8, 20).thatsFilledWith(ColorMaker.black).thatsTranslated(-4, 15)
  val wheelR2 = Picture.rectangle(8, 20).thatsFilledWith(ColorMaker.black).thatsTranslated(44, 15)
  picStack(body, windshield, rearWindow, wheelL, wheelR, wheelL2, wheelR2)
} //> def createTraffic(): builtins.Picture

val bus = createBus() //> val bus: builtins.Picture = Picture Stack (Id: 1594693001)
// 3 distinct lanes on the road
val lanes = List(cb.x + cb.width / 2 - 120, cb.x + cb.width / 2 - 27, cb.x + cb.width / 2 + 65) //> val lanes: List[Double] = List(-120.0, -27.0, 65.0)
var busLaneIndex = 1 //> var busLaneIndex: Int = 1
bus.setPosition(lanes(busLaneIndex), cb.y + 40)
bus.draw()

// Traffic setup
var trafficLaneIndex = scala.util.Random.nextInt(3) //> var trafficLaneIndex: Int = 2
var trafficY = cb.y + cb.height + 100 //> var trafficY: Double = 363.5
var trafficX = lanes(trafficLaneIndex) //> var trafficX: Double = 65.0

val traffic = createTraffic() //> val traffic: builtins.Picture = Picture Stack (Id: 1272522120)
traffic.setPosition(trafficX, trafficY)
traffic.draw()

// Game state variables
var score = 0 //> var score: Int = 0
var speed = 4.5 //> var speed: Double = 4.5
var gameOver = false //> var gameOver: Boolean = false

// Smooth lane-switching via Left and Right arrow keys
onKeyPress { k =>
  if (!gameOver) {
    k match {
      case Kc.VK_LEFT =>
        if (busLaneIndex > 0) {
          busLaneIndex -= 1
          bus.setPosition(lanes(busLaneIndex), bus.position.y)
        }
      case Kc.VK_RIGHT =>
        if (busLaneIndex < lanes.length - 1) {
          busLaneIndex += 1
          bus.setPosition(lanes(busLaneIndex), bus.position.y)
        }
      case _ =>
    }
  }
}

// Main top-down animation loop
animate {
  if (!gameOver) {
    // Move traffic downwards
    trafficY -= speed
    traffic.setPosition(lanes(trafficLaneIndex), trafficY)

    // Reset traffic when it goes off screen
    if (trafficY < cb.y - 120) {
      trafficLaneIndex = scala.util.Random.nextInt(3)
      trafficY = cb.y + cb.height + 100
      score += 1
      speed += 0.3 // Gradual difficulty increase
    }

    // Collision detection
    if (bus.collidesWith(traffic)) {
      gameOver = true
      val crashText = Picture.text("You car crashed!", 28)
      crashText.setPenColor(ColorMaker.red)
      crashText.setPosition(cb.x + cb.width / 2 - 110, cb.y + cb.height / 2)
      crashText.draw()
    }
  }
} //> val res54: java.util.concurrent.Future[edu.umd.cs.piccolo.activities.PActivity] = net.kogics.kojo.util.FutureResult@43dd875e