Code Sketch
yadnesh
Category: Programming
// ============================================================
// ? ULTRA CRICKET 2.5D - KOJO + SCALA
// ============================================================
//
// SPACE = Bowl
// W = Pull Shot
// S = Straight Drive
// A = Cover Drive
// D = Defence
// Q = Lofted Shot
// R = Restart
// P = Pause
//
// ============================================================
cleari()
drawStage(ColorMaker.darkGreen)
disablePanAndZoom()
val cb = canvasBounds
// ============================================================
// GAME STATE
// ============================================================
var score = 0
var wickets = 0
var balls = 0
val totalBalls = 30
val maxWickets = 5
var active = false
var hit = false
var shotPlayed = false
var gameOver = false
var paused = false
var message = "SPACE = BOWL"
var scoreText = "SCORE 0/0 OVER 0.0"
// ============================================================
// STADIUM
// ============================================================
val stadium = Picture.circle(650)
stadium.setFillColor(ColorMaker.green)
stadium.setPosition(
cb.x + cb.width / 2,
cb.y + 250
)
draw(stadium)
val boundary = Picture.circle(540)
boundary.setFillColor(ColorMaker.darkGreen)
boundary.setPosition(
cb.x + cb.width / 2,
cb.y + 250
)
draw(boundary)
// ============================================================
// PERSPECTIVE PITCH
// ============================================================
val pitch = Picture.rectangle(150, 500)
pitch.setFillColor(ColorMaker.tan)
pitch.setPosition(
cb.x + cb.width / 2 - 75,
cb.y + 30
)
draw(pitch)
// Pitch centre
val centreLine = Picture.rectangle(4, 500)
centreLine.setFillColor(ColorMaker.lightGray)
centreLine.setPosition(
cb.x + cb.width / 2 - 2,
cb.y + 30
)
draw(centreLine)
// ============================================================
// CREASES
// ============================================================
val topCrease = Picture.rectangle(150, 5)
topCrease.setFillColor(ColorMaker.white)
topCrease.setPosition(
cb.x + cb.width / 2 - 75,
cb.y + 90
)
draw(topCrease)
val bottomCrease = Picture.rectangle(150, 5)
bottomCrease.setFillColor(ColorMaker.white)
bottomCrease.setPosition(
cb.x + cb.width / 2 - 75,
cb.y + 410
)
draw(bottomCrease)
// ============================================================
// STUMPS
// ============================================================
val stump1 = Picture.rectangle(6, 45)
stump1.setFillColor(ColorMaker.saddleBrown)
stump1.setPosition(
cb.x + cb.width / 2 - 15,
cb.y + 50
)
draw(stump1)
val stump2 = Picture.rectangle(6, 45)
stump2.setFillColor(ColorMaker.saddleBrown)
stump2.setPosition(
cb.x + cb.width / 2 - 3,
cb.y + 50
)
draw(stump2)
val stump3 = Picture.rectangle(6, 45)
stump3.setFillColor(ColorMaker.saddleBrown)
stump3.setPosition(
cb.x + cb.width / 2 + 9,
cb.y + 50
)
draw(stump3)
// ============================================================
// BATSMAN SHADOW
// ============================================================
val batsmanShadow = Picture.ellipse(45, 15)
batsmanShadow.setFillColor(ColorMaker.black)
batsmanShadow.setPosition(
cb.x + cb.width / 2,
cb.y + 85
)
draw(batsmanShadow)
// ============================================================
// BATSMAN
// ============================================================
class Batsman {
val body = Picture.rectangle(25, 50)
body.setFillColor(ColorMaker.blue)
val head = Picture.circle(22)
head.setFillColor(ColorMaker.saddleBrown)
head.setPosition(0, -35)
val helmet = Picture.circle(25)
helmet.setFillColor(ColorMaker.black)
helmet.setPosition(0, -37)
val bat = Picture.rectangle(8, 65)
bat.setFillColor(ColorMaker.saddleBrown)
bat.setPosition(-18, -20)
val pic = picBatch(
body,
head,
helmet,
bat
)
pic.setPosition(
cb.x + cb.width / 2 - 12,
cb.y + 75
)
var swinging = false
var timer = 0
var swing = ""
def swingBat(kind: String): Unit = {
if (!swinging) {
swinging = true
timer = 8
swing = kind
if (kind == "pull") {
pic.rotate(-55)
}
if (kind == "straight") {
pic.rotate(45)
}
if (kind == "cover") {
pic.rotate(-40)
}
if (kind == "defence") {
pic.rotate(15)
}
if (kind == "loft") {
pic.rotate(70)
}
}
}
def update(): Unit = {
if (timer > 0) {
timer -= 1
if (timer == 0) {
if (swing == "pull") {
pic.rotate(55)
}
if (swing == "straight") {
pic.rotate(-45)
}
if (swing == "cover") {
pic.rotate(40)
}
if (swing == "defence") {
pic.rotate(-15)
}
if (swing == "loft") {
pic.rotate(-70)
}
swinging = false
}
}
}
}
val batsman = new Batsman()
draw(batsman.pic)
// ============================================================
// BALL + SHADOW
// ============================================================
val ballShadow = Picture.ellipse(22, 8)
ballShadow.setFillColor(ColorMaker.black)
ballShadow.setPosition(
cb.x + cb.width / 2,
cb.y + cb.height - 100
)
draw(ballShadow)
val ball = Picture.circle(12)
ball.setFillColor(ColorMaker.white)
ball.setPosition(
cb.x + cb.width / 2,
cb.y + cb.height - 100
)
draw(ball)
// ============================================================
// SCOREBOARD
// ============================================================
val scoreDisplay = Picture.text(scoreText, 22)
scoreDisplay.setFillColor(ColorMaker.white)
scoreDisplay.setPosition(
cb.x + 20,
cb.y + cb.height - 30
)
draw(scoreDisplay)
val messageDisplay = Picture.text(message, 16)
messageDisplay.setFillColor(ColorMaker.yellow)
messageDisplay.setPosition(
cb.x + 20,
cb.y + cb.height - 60
)
draw(messageDisplay)
// ============================================================
// BALL VARIABLES
// ============================================================
var ballX = cb.x + cb.width / 2
var ballY = cb.y + cb.height - 100
var ballVX = 0.0
var ballVY = 0.0
// ============================================================
// SCORE UPDATE
// ============================================================
def updateScore(): Unit = {
val over = balls / 6
val ballNo = balls % 6
scoreText =
"? SCORE " +
score +
"/" +
wickets +
" OVER " +
over +
"." +
ballNo
}
// ============================================================
// RESET BALL
// ============================================================
def resetBall(): Unit = {
active = false
hit = false
shotPlayed = false
balls += 1
ballX =
cb.x + cb.width / 2
ballY =
cb.y + cb.height - 100
ballVX = 0
ballVY = 0
ball.setPosition(
ballX,
ballY
)
ballShadow.setPosition(
ballX,
ballY + 8
)
updateScore()
if (
balls >= totalBalls ||
wickets >= maxWickets
) {
gameOver = true
message =
"? MATCH OVER! " +
score +
"/" +
wickets
} else {
message =
"SPACE = NEXT BALL"
}
}
// ============================================================
// BOWL
// ============================================================
def bowl(): Unit = {
if (
!active &&
!gameOver &&
!paused
) {
ballX =
cb.x + cb.width / 2
ballY =
cb.y + cb.height - 100
ballVX = 0
ballVY = -6.0
active = true
hit = false
shotPlayed = false
message =
"? BALL COMING!"
}
}
// ============================================================
// SHOT SYSTEM
// ============================================================
def playShot(kind: String): Unit = {
if (
active &&
!shotPlayed
) {
shotPlayed = true
hit = true
if (kind == "pull") {
batsman.swingBat("pull")
score += 4
ballVX = 4
ballVY = 5
message =
"? PERFECT PULL! FOUR!"
}
if (kind == "straight") {
batsman.swingBat("straight")
score += 6
ballVX = 0
ballVY = 7
message =
"? MASSIVE SIX!"
}
if (kind == "cover") {
batsman.swingBat("cover")
score += 4
ballVX = -4
ballVY = 5
message =
"? COVER DRIVE! FOUR!"
}
if (kind == "defence") {
batsman.swingBat("defence")
score += 1
ballVX = 1
ballVY = 6
message =
"? DEFENCE! 1 RUN"
}
if (kind == "loft") {
batsman.swingBat("loft")
score += 6
ballVX = 2
ballVY = 7
message =
"? LOFTED SIX!"
}
updateScore()
}
}
// ============================================================
// RESTART
// ============================================================
def restartGame(): Unit = {
score = 0
wickets = 0
balls = 0
active = false
hit = false
shotPlayed = false
gameOver = false
paused = false
ballX =
cb.x + cb.width / 2
ballY =
cb.y + cb.height - 100
ball.setPosition(
ballX,
ballY
)
ballShadow.setPosition(
ballX,
ballY + 8
)
updateScore()
message =
"SPACE = BOWL"
}
// ============================================================
// GAME LOOP
// ============================================================
animate {
// Restart
if (isKeyPressed(Kc.VK_R)) {
restartGame()
}
// Pause
if (isKeyPressed(Kc.VK_P)) {
paused = !paused
}
if (
!paused &&
!gameOver
) {
// Bowl
if (isKeyPressed(Kc.VK_SPACE)) {
bowl()
}
// Ball movement
if (active) {
ballX += ballVX
ballY += ballVY
ball.setPosition(
ballX,
ballY
)
// Shadow gives depth effect
ballShadow.setPosition(
ballX,
ballY + 10
)
// ------------------------------------------
// BATTING ZONE
// ------------------------------------------
if (
ballY > cb.y + 75 &&
ballY < cb.y + 140 &&
!shotPlayed
) {
if (isKeyPressed(Kc.VK_W)) {
playShot("pull")
} else if (isKeyPressed(Kc.VK_S)) {
playShot("straight")
} else if (isKeyPressed(Kc.VK_A)) {
playShot("cover")
} else if (isKeyPressed(Kc.VK_D)) {
playShot("defence")
} else if (isKeyPressed(Kc.VK_Q)) {
playShot("loft")
}
}
// ------------------------------------------
// MISSED BALL = WICKET
// ------------------------------------------
if (
ballY < cb.y + 40 &&
!shotPlayed
) {
wickets += 1
message =
"? WICKET! BALL MISSED!"
resetBall()
}
// ------------------------------------------
// HIT COMPLETED
// ------------------------------------------
if (
ballY > cb.y + cb.height - 40 &&
hit
) {
resetBall()
}
}
batsman.update()
}
// IMPORTANT KOJO API
// TextPic uses setText()
scoreDisplay.setText(scoreText)
messageDisplay.setText(message)
}
// ============================================================
// START
// ============================================================
println("======================================")
println(" ? ULTRA 2.5D CRICKET ?")
println("======================================")
println("SPACE = Bowl")
println("W = Pull Shot")
println("S = Straight Drive")
println("A = Cover Drive")
println("D = Defence")
println("Q = Lofted Shot")
println("P = Pause")
println("R = Restart")
println("======================================")