Code Sketch


sniper
By: Mhalsakant School
Category: Art
// Clear canvas and configure stage setup
cleari()
disablePanAndZoom()
val cb = canvasBounds
drawStage(ColorMaker.black)

// 1. Create Field Elements using correct Kojo Picture constructors
val pitch = Picture.rectangle(120, 400).withFillColor(ColorMaker.tan).withPenColor(ColorMaker.white)
pitch.setPosition(cb.x + cb.width / 2 - 60, cb.y + 50)

val stumps = Picture.rectangle(30, 15).withFillColor(ColorMaker.yellow)
stumps.setPosition(cb.x + cb.width / 2 - 15, cb.y + 70)

val batsman = Picture {
  setPenColor(ColorMaker.blue)
  setFillColor(ColorMaker.blue)
  circle(12) // Head
  setPenColor(ColorMaker.brown)
  setPenThickness(6)
  forward(30) // Bat handle/blade
}
batsman.setPosition(cb.x + cb.width / 2, cb.y + 110)

val ball = Picture.circle(6).withFillColor(ColorMaker.red).withPenColor(ColorMaker.white)
var ballX = cb.x + cb.width / 2
var ballY = cb.y + cb.height - 50
var ballVelY = 0.0 // Ball starts stationary until you bowl
var isBallActive = false
var score = 0

// Draw everything onto the Kojo stage
draw(pitch, stumps, batsman, ball)

// State flags for gameplay mechanics
var isBatting = false

// 2. Main Animation & Game Loop
animate {
  // Check if user presses SPACE or W to bowl/release the ball
  if (!isBallActive && (isKeyPressed(Kc.VK_SPACE) || isKeyPressed(Kc.VK_W))) {
    ballX = cb.x + cb.width / 2 + (scala.util.Random.nextInt(40) - 20)
    ballY = cb.y + cb.height - 60
    ballVelY = -6.0 // Start bowling action
    isBallActive = true
  }

  // Move the ball if it is active
  if (isBallActive) {
    ballY = ballY + ballVelY
    ball.setPosition(ballX, ballY)
  }

  // Handle Batsman Swing Interaction via Up Arrow Key
  if (isKeyPressed(Kc.VK_UP)) {
    if (!isBatting) {
      isBatting = true
      batsman.rotate(45) // Swing bat forward
    }
  } else {
    if (isBatting) {
      batsman.rotate(-45) // Return bat to original stance
      isBatting = false
    }
  }

  // Collision Detection / Shot Evaluation (Batsman hits ball)
  val distanceToBat = Math.hypot(ballX - batsman.position.x, ballY - batsman.position.y)
  if (isBallActive && distanceToBat < 35 && isBatting && ballVelY < 0) {
    ballVelY = 8.0 // Hit back up the ground!
    score = score + 4
    println(s"Current Score: $score - Great Shot!")
  }

  // Reset ball if it goes past the limits
  if (ballY < cb.y || ballY > cb.y + cb.height) {
    isBallActive = false
    ballVelY = 0.0
    ball.setPosition(-100, -100) // Hide ball until next press
  }
}