Code Sketch


sniper_0718
By: Mhalsakant School
Category: Art
// ==========================================
// SECURE BHOOL BHULAIYAA (ERROR-FREE DIALOG)
// ==========================================

cleari()
disablePanAndZoom()
setBackground(ColorMaker.black)

val cb = canvasBounds //> val cb: edu.umd.cs.piccolo.util.PBounds = PBounds[x=-387.5,y=-263.5,width=775.0,height=527.0]
val offsetX = cb.x + 80 //> val offsetX: Double = -307.5
val offsetY = cb.y + cb.height - 40 //> val offsetY: Double = 223.5

// Java Swing Dialog Box (No Error)
val enteredPassword = javax.swing.JOptionPane.showInputDialog(null, "Enter Password to Play Bhool Bhulaiyaa:") //> val enteredPassword: String = BHIXNYA

if (enteredPassword == null || enteredPassword.trim.toUpperCase != "BHIXNYA") {
  val errorText = Picture.text("? Wrong Password! Game Locked.", 18)
  errorText.setFillColor(ColorMaker.red)
  errorText.setPosition(cb.x + 100, cb.y + cb.height / 2)
  errorText.draw()
} else {

  val mazeLevel1 = Seq(
    Seq(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
    Seq(1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1),
    Seq(1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 1),
    Seq(1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1),
    Seq(1, 0, 1, 1, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1),
    Seq(1, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1),
    Seq(1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1),
    Seq(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1),
    Seq(1, 0, 1, 0, 1, 1, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 0, 1, 1),
    Seq(1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1),
    Seq(1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1),
    Seq(1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 1),
    Seq(1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1),
    Seq(1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1),
    Seq(1, 0, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 0, 1),
    Seq(1, 0, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1),
    Seq(1, 0, 1, 0, 1, 0, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1),
    Seq(1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1),
    Seq(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
  )

  val mazeLevel2 = Seq(
    Seq(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
    Seq(1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1),
    Seq(1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 0, 1),
    Seq(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1),
    Seq(1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1),
    Seq(1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1),
    Seq(1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1),
    Seq(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1),
    Seq(1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1),
    Seq(1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1),
    Seq(1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1),
    Seq(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1),
    Seq(1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1),
    Seq(1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1),
    Seq(1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1),
    Seq(1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1),
    Seq(1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1),
    Seq(1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1),
    Seq(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
  )

  val mazeLevel3 = Seq(
    Seq(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1),
    Seq(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 1),
    Seq(1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 1),
    Seq(1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1),
    Seq(1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1),
    Seq(1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1),
    Seq(1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1),
    Seq(1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 1),
    Seq(1, 1, 1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1),
    Seq(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 1),
    Seq(1, 0, 1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 0, 1),
    Seq(1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1),
    Seq(1, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1),
    Seq(1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1),
    Seq(1, 0, 1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1),
    Seq(1, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 1),
    Seq(1, 0, 1, 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 1, 0, 1),
    Seq(1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1),
    Seq(1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1)
  )

  var activeMaze = mazeLevel1
  var tileSize = 22
  var walls = Seq[Picture]()

  def drawMaze() {
    walls.foreach(_.erase())
    walls = Seq[Picture]()
    for (r <- 0 until activeMaze.length; c <- 0 until activeMaze(r).length) {
      if (activeMaze(r)(c) == 1) {
        val wall = Picture.rectangle(tileSize, tileSize)
        wall.setFillColor(ColorMaker.darkGray)
        wall.setPenColor(ColorMaker.black)
        wall.setPosition(offsetX + c * tileSize, offsetY - (r + 1) * tileSize)
        wall.draw()
        walls = walls :+ wall
      }
    }
  }

  var currentLevel = 1
  var gameOver = false
  var pCol = 1; var pRow = 17
  var k1Col = 5; var k1Row = 1; var k1Alive = true
  var k2Col = 14; var k2Row = 9; var k2Alive = true
  var k3Col = 10; var k3Row = 15; var k3Alive = true
  var exitCol = 18; var exitRow = 1

  val exitGoal = Picture.rectangle(tileSize - 4, tileSize - 4)
  exitGoal.setFillColor(ColorMaker.red)
  exitGoal.setPenColor(ColorMaker.white)

  val player = Picture.circle(tileSize / 2 - 3)
  player.setFillColor(ColorMaker.yellow)
  player.setPenColor(ColorMaker.darkGray)

  val killer1 = Picture.rectangle(tileSize - 6, tileSize - 6)
  killer1.setFillColor(ColorMaker.red)
  killer1.setPenColor(ColorMaker.darkRed)

  val killer2 = Picture.rectangle(tileSize - 6, tileSize - 6)
  killer2.setFillColor(ColorMaker.red)
  killer2.setPenColor(ColorMaker.darkRed)

  val killer3 = Picture.rectangle(tileSize - 6, tileSize - 6)
  killer3.setFillColor(ColorMaker.red)
  killer3.setPenColor(ColorMaker.darkRed)

  val bullet = Picture.circle(2)
  bullet.setFillColor(ColorMaker.white)
  bullet.setPenColor(ColorMaker.cyan)
  bullet.setPosition(-200, -200)
  bullet.draw()

  val banner = Picture.text("", 13)
  banner.setPenColor(ColorMaker.cyan)
  banner.setPosition(offsetX, offsetY + 25)

  banner.setText("LEVEL 1 BHOOL BHULAIYAA: Kill 3 enemies & find Exit!")
  banner.draw()
  drawMaze()
  exitGoal.setPosition(offsetX + exitCol * tileSize + 2, offsetY - (exitRow + 1) * tileSize + 2)
  exitGoal.draw()
  updatePlayerPosition()
  updateKillersPosition()
  player.draw()
  killer1.draw()
  killer2.draw()
  killer3.draw()

  def loadLevel(lvl: Int) {
    currentLevel = lvl
    if (lvl == 2) {
      tileSize = 17
      activeMaze = mazeLevel2
      pCol = 1; pRow = 17
      exitCol = 20; exitRow = 1
      k1Col = 6; k1Row = 2; k2Col = 15; k2Row = 10; k3Col = 10; k3Row = 14
      banner.setText("LEVEL 2 BHOOL BHULAIYAA: Bigger maze & faster killers!")
    } else if (lvl == 3) {
      tileSize = 13
      activeMaze = mazeLevel3
      pCol = 1; pRow = 17
      exitCol = 22; exitRow = 1
      k1Col = 8; k1Row = 3; k2Col = 14; k2Row = 12; k3Col = 18; k3Row = 16
      banner.setText("LEVEL 3 BHOOL BHULAIYAA: Ultimate Giant Maze! Survive!")
    }

    drawMaze()
    exitGoal.setPosition(offsetX + exitCol * tileSize + 2, offsetY - (exitRow + 1) * tileSize + 2)
    k1Alive = true; k2Alive = true; k3Alive = true
    exitGoal.setFillColor(ColorMaker.red)
    updatePlayerPosition()
    updateKillersPosition()
  }

  def updatePlayerPosition() {
    player.setPosition(
      offsetX + pCol * tileSize + tileSize / 2, 
      offsetY - (pRow + 1) * tileSize + tileSize / 2
    )
  }

  def updateKillersPosition() {
    if (k1Alive) killer1.setPosition(offsetX + k1Col * tileSize + 3, offsetY - (k1Row + 1) * tileSize + 3)
    else killer1.setPosition(-500, -500)

    if (k2Alive) killer2.setPosition(offsetX + k2Col * tileSize + 3, offsetY - (k2Row + 1) * tileSize + 3)
    else killer2.setPosition(-500, -500)

    if (k3Alive) killer3.setPosition(offsetX + k3Col * tileSize + 3, offsetY - (k3Row + 1) * tileSize + 3)
    else killer3.setPosition(-500, -500)
  }

  onKeyPress { k =>
    if (!gameOver) {
      var newCol = pCol
      var newRow = pRow

      if (k == Kc.VK_UP || k == 'w' || k == 'W') newRow -= 1
      else if (k == Kc.VK_DOWN || k == 's' || k == 'S') newRow += 1
      else if (k == Kc.VK_LEFT || k == 'a' || k == 'A') newCol -= 1
      else if (k == Kc.VK_RIGHT || k == 'd' || k == 'D') newCol += 1

      if (newRow >= 0 && newRow < activeMaze.length && newCol >= 0 && newCol < activeMaze(0).length) {
        if (activeMaze(newRow)(newCol) == 0) {
          pCol = newCol
          pRow = newRow
          updatePlayerPosition()
        }
      }

      if (k == 'z' || k == 'Z') {
        val pPos = player.position
        bullet.setPosition(pPos.x + 8, pPos.y + 8)

        if (k1Alive && math.abs(pCol - k1Col) <= 2 && math.abs(pRow - k1Row) <= 2) k1Alive = false
        if (k2Alive && math.abs(pCol - k2Col) <= 2 && math.abs(pRow - k2Row) <= 2) k2Alive = false
        if (k3Alive && math.abs(pCol - k3Col) <= 2 && math.abs(pRow - k3Row) <= 2) k3Alive = false

        updateKillersPosition()

        if (!k1Alive && !k2Alive && !k3Alive) {
          exitGoal.setFillColor(ColorMaker.green)
          banner.setText(s"Level $currentLevel Cleared! Green Exit Unlocked!")
        }
      }

      if (pCol == exitCol && pRow == exitRow) {
        if (!k1Alive && !k2Alive && !k3Alive) {
          if (currentLevel < 3) {
            loadLevel(currentLevel + 1)
          } else {
            gameOver = true
            val winText = Picture.text("? VICTORY! YOU ESCAPED ALL LEVELS! ?", 15)
            winText.setFillColor(ColorMaker.green)
            winText.setPenColor(ColorMaker.white)
            winText.setPosition(offsetX, offsetY + 50)
            winText.draw()
          }
        }
      }
    }
  }

  import java.awt.event.ActionListener
  import java.awt.event.ActionEvent

  val gameTimer = new javax.swing.Timer(550, new ActionListener {
    override def actionPerformed(e: ActionEvent): Unit = {
      if (!gameOver) {
        if (k1Alive) {
          var nc = k1Col; var nr = k1Row
          if (k1Col < pCol && activeMaze(k1Row)(k1Col + 1) == 0) nc += 1
          else if (k1Col > pCol && activeMaze(k1Row)(k1Col - 1) == 0) nc -= 1
          else if (k1Row < pRow && activeMaze(k1Row + 1)(k1Col) == 0) nr += 1
          else if (k1Row > pRow && activeMaze(k1Row - 1)(k1Col) == 0) nr -= 1
          k1Col = nc; k1Row = nr
        }

        if (k2Alive) {
          var nc = k2Col; var nr = k2Row
          if (k2Col < pCol && activeMaze(k2Row)(k2Col + 1) == 0) nc += 1
          else if (k2Col > pCol && activeMaze(k2Row)(k2Col - 1) == 0) nc -= 1
          else if (k2Row < pRow && activeMaze(k2Row + 1)(k2Col) == 0) nr += 1
          else if (k2Row > pRow && activeMaze(k2Row - 1)(k2Col) == 0) nr -= 1
          k2Col = nc; k2Row = nr
        }

        if (k3Alive) {
          var nc = k3Col; var nr = k3Row
          if (k3Col < pCol && activeMaze(k3Row)(k3Col + 1) == 0) nc += 1
          else if (k3Col > pCol && activeMaze(k3Row)(k3Col - 1) == 0) nc -= 1
          else if (k3Row < pRow && activeMaze(k3Row + 1)(k3Col) == 0) nr += 1
          else if (k3Row > pRow && activeMaze(k3Row - 1)(k3Col) == 0) nr -= 1
          k3Col = nc; k3Row = nr
        }

        updateKillersPosition()

        if ((k1Alive && k1Col == pCol && k1Row == pRow) ||
            (k2Alive && k2Col == pCol && k2Row == pRow) ||
            (k3Alive && k3Col == pCol && k3Row == pRow)) {
          gameOver = true
          val loseText = Picture.text("? GAME OVER! A killer caught you! ?", 16)
          loseText.setFillColor(ColorMaker.red)
          loseText.setPenColor(ColorMaker.white)
          loseText.setPosition(offsetX, offsetY + 50)
          loseText.draw()
        }
      }
    }
  })
  gameTimer.start()
}