Code Sketch


Bixuu02
By: Mhalsakant School
Category: Programming
// ============================================================
// BIXUU DAHI HANDI SPECIAL MISSION GAME
// SCALA SCRIPT FOR KOJO / SCALA CANVAS (HUMAN PYRAMID/STAIRS FIXED)
// ============================================================

cleari()
originBottomLeft()

// ============================================================
// GAME STATES & VARIABLES
// 0 = Intro Screen (Prize & Thanks)
// 1 = Mission Letter Screen (Dahi Handi Invitation)
// 2 = Team Selection Screen (3 Teams)
// 3 = Matka Decoration & Paint Screen (Designs & Colors)
// 4 = Dahi Handi Climbing & Breaking Game Scene (Human Pyramid Stairs)
// 5 = Final Screen (Happy Gokulashtami & Mission Complete)
// ============================================================

var screen = 0
var selectedTeam = "NONE"

// Matka Decoration Variables
var matkaColorR = 210
var matkaColorG = 140
var matkaColorB = 60
var selectedDesign = "NONE" // "DOTS", "ZIGZAG", "FLOWERS"
var isMatkaDecorated = false

// Climbing Game Variables (State 4)
var playerX = cwidth / 2.0
var playerY = 60.0
val handiX = cwidth / 2.0
val handiY = cheight - 120.0
var isHandiBroken = false

class Star(val x: Double, val y: Double, val size: Double) {
    var phase = randomDouble(6.28)
    def step() { phase += 0.04 }
    def view(canvas: CanvasDraw) {
        val brightness = 150 + (math.sin(phase) * 80).toInt
        canvas.noStroke()
        canvas.fill(brightness, brightness, 255, 200)
        canvas.ellipse(x, y, size, size)
    }
}

val stars = ArrayBuffer.empty[Star]
for (i <- 0 until 60) {
    stars.append(new Star(randomDouble(cwidth), randomDouble(cheight), 1.0 + randomDouble(3.0)))
}

// ============================================================
// DRAW CUSTOM MATKA (POT)
// ============================================================
def drawMatka(canvas: CanvasDraw, x: Double, y: Double, r: Int, g: Int, b: Int, design: String, isBroken: Boolean) {
    canvas.noStroke()

    if (!isBroken) {
        // Matka Body
        canvas.fill(r, g, b)
        canvas.ellipse(x, y, 90, 90) // Main belly
        canvas.rect(x - 25, y + 35, 50, 15) // Neck
        canvas.ellipse(x, y + 50, 60, 15) // Top Rim

        // White Curd/Dahi Top Cover
        canvas.fill(255, 255, 255)
        canvas.ellipse(x, y + 48, 52, 12)

        // Designs on Matka
        if (design == "DOTS") {
            canvas.fill(255, 255, 255)
            canvas.ellipse(x - 20, y, 10, 10)
            canvas.ellipse(x, y, 10, 10)
            canvas.ellipse(x + 20, y, 10, 10)
            canvas.ellipse(x - 10, y - 20, 10, 10)
            canvas.ellipse(x + 10, y - 20, 10, 10)
        } else if (design == "ZIGZAG") {
            canvas.stroke(255, 215, 0)
            canvas.strokeWeight(4)
            canvas.line(x - 35, y, x - 15, y + 15)
            canvas.line(x - 15, y + 15, x + 5, y - 5)
            canvas.line(x + 5, y - 5, x + 25, y + 15)
            canvas.noStroke()
        } else if (design == "FLOWERS") {
            canvas.fill(255, 100, 150)
            canvas.ellipse(x, y, 15, 15)
            canvas.fill(255, 255, 0)
            canvas.ellipse(x - 12, y, 10, 10)
            canvas.ellipse(x + 12, y, 10, 10)
            canvas.ellipse(x, y - 12, 10, 10)
            canvas.ellipse(x, y + 12, 10, 10)
        }
    } else {
        // Broken Matka & Dahi Splash
        canvas.fill(r, g, b)
        canvas.arc(x - 20, y - 10, 40, 50, 0, 3.14)
        canvas.arc(x + 20, y - 10, 40, 50, 0, 3.14)

        // Dahi Splash Effect
        canvas.fill(255, 255, 255)
        canvas.ellipse(x, y - 30, 80, 25)
        canvas.ellipse(x - 30, y - 45, 25, 15)
        canvas.ellipse(x + 25, y - 50, 30, 18)
    }
}

// ============================================================
// DRAW GOVINDA CHARACTER (FOR HUMAN PYRAMID & PLAYER)
// ============================================================
def drawGovinda(canvas: CanvasDraw, x: Double, y: Double, shirtR: Int, shirtG: Int, shirtB: Int) {
    // Head
    canvas.fill(255, 220, 180)
    canvas.ellipse(x, y + 25, 18, 18)
    
    // Shirt / Body
    canvas.fill(shirtR, shirtG, shirtB)
    canvas.rect(x - 10, y - 5, 20, 28)
    
    // Pants / Legs
    canvas.fill(30, 30, 80)
    canvas.rect(x - 8, y - 20, 7, 15)
    canvas.rect(x + 1, y - 20, 7, 15)
}

// ============================================================
// SCREENS
// ============================================================

// --- SCREEN 0: INTRO SCREEN ---
def drawIntroScreen(canvas: CanvasDraw) {
    canvas.background(25, 15, 45)
    repeatFor(stars) { s => s.view(canvas) }

    canvas.fill(255, 215, 0)
    canvas.text("WELCOME TO BIXUU DAHI HANDI MISSION!", cwidth/2 - 180, cheight - 50)

    canvas.fill(255, 255, 255)
    canvas.text("Bixuu Dahi Handi Utsav Game.", cwidth/2 - 120, cheight - 90)
    canvas.text("Join thousands of players in this festival!", cwidth/2 - 145, cheight - 120)

    // Prize Card
    canvas.fill(40, 30, 70)
    canvas.stroke(255, 215, 0)
    canvas.strokeWeight(3)
    canvas.rect(cwidth/2 - 170, cheight/2 - 70, 340, 140)

    canvas.noStroke()
    canvas.fill(255, 215, 0)
    canvas.text("UTSAV PRIZE ANNOUNCEMENT", cwidth/2 - 120, cheight/2 + 45)
    canvas.fill(255, 255, 255)
    canvas.text("1st Winner Team : 1 Lakh", cwidth/2 - 120, cheight/2 + 15)
    canvas.text("2nd Winner Team : 50,000", cwidth/2 - 120, cheight/2 - 10)
    canvas.text("3rd Winner Team : 20,000", cwidth/2 - 120, cheight/2 - 35)

    // Click Mission Button
    canvas.fill(220, 50, 50)
    canvas.rect(cwidth/2 - 110, 40, 220, 50)
    canvas.fill(255, 255, 255)
    canvas.text("PLEASE CLICK THE MISSION", cwidth/2 - 95, 70)
}

// --- SCREEN 1: DAHI HANDI INVITATION LETTER ---
def drawLetterScreen(canvas: CanvasDraw) {
    canvas.background(40, 20, 50)
    repeatFor(stars) { s => s.view(canvas) }

    canvas.fill(255, 248, 220)
    canvas.stroke(212, 175, 55)
    canvas.strokeWeight(4)
    canvas.rect(cwidth/2 - 210, cheight/2 - 160, 420, 320)

    canvas.fill(180, 0, 0)
    canvas.text("DAHI HANDI UTSAV INVITATION", cwidth/2 - 130, cheight/2 + 120)

    canvas.fill(30, 30, 30)
    canvas.text("You are invited to Dahi Handi Utsav!", cwidth/2 - 180, cheight/2 + 80)
    canvas.text("Thank you for participating in this competition.", cwidth/2 - 180, cheight/2 + 55)
    canvas.text("Mission Steps:", cwidth/2 - 180, cheight/2 + 25)
    canvas.text("1. Select your favorite Dahi Handi Team.", cwidth/2 - 180, cheight/2)
    canvas.text("2. Decorate & Paint the Matka with colors/designs.", cwidth/2 - 180, cheight/2 - 25)
    canvas.text("3. Climb up to top using keyboard & break it!", cwidth/2 - 180, cheight/2 - 50)

    // Accept Button (GREEN COLOR)
    canvas.fill(0, 180, 80)
    canvas.noStroke()
    canvas.rect(cwidth/2 - 110, cheight/2 - 130, 220, 50)
    canvas.fill(255, 255, 255)
    canvas.text("ACCEPT THIS MISSION", cwidth/2 - 85, cheight/2 - 98)
}

// --- SCREEN 2: TEAM SELECTION SCREEN ---
def drawTeamSelectScreen(canvas: CanvasDraw) {
    canvas.background(30, 30, 60)
    repeatFor(stars) { s => s.view(canvas) }

    canvas.fill(255, 215, 0)
    canvas.text("SELECT YOUR DAHI HANDI TEAM", cwidth/2 - 140, cheight - 60)

    // Team 1: Gokuldham Team
    canvas.fill(230, 80, 50)
    canvas.rect(cwidth/2 - 150, cheight - 160, 300, 50)
    canvas.fill(255, 255, 255)
    canvas.text("1. GOKULDHAM TEAM", cwidth/2 - 80, cheight - 128)

    // Team 2: Dahi Handi Team
    canvas.fill(40, 150, 220)
    canvas.rect(cwidth/2 - 150, cheight - 230, 300, 50)
    canvas.fill(255, 255, 255)
    canvas.text("2. DAHI HANDI TEAM", cwidth/2 - 75, cheight - 198)

    // Team 3: Jai Krishna Dahi Handi Team
    canvas.fill(150, 50, 200)
    canvas.rect(cwidth/2 - 150, cheight - 300, 300, 50)
    canvas.fill(255, 255, 255)
    canvas.text("3. JAI KRISHNA DAHI HANDI TEAM", cwidth/2 - 125, cheight - 268)
}

// --- SCREEN 3: MATKA DECORATION & PAINT ---
def drawMatkaPaintScreen(canvas: CanvasDraw) {
    canvas.background(35, 45, 55)

    canvas.fill(255, 215, 0)
    canvas.text(s"DECORATE THE MATKA (${selectedTeam})", cwidth/2 - 160, cheight - 35)

    // Colors Palette Top
    canvas.fill(200, 200, 200)
    canvas.rect(20, cheight - 110, cwidth - 40, 55)

    val colorNames = Array("TERRA", "BLUE", "RED", "GOLD", "PURPLE")
    val colorsR = Array(210, 30, 220, 255, 140)
    val colorsG = Array(140, 140, 40, 215, 40)
    val colorsB = Array(60, 230, 60, 0, 210)

    for (i <- 0 until 5) {
        val bx = 30 + i * 75
        canvas.fill(colorsR(i), colorsG(i), colorsB(i))
        canvas.rect(bx, cheight - 102, 65, 40)
        canvas.fill(255, 255, 255)
        canvas.text(colorNames(i), bx + 8, cheight - 77)
    }

    // Design Selection Options
    canvas.fill(220, 220, 220)
    canvas.rect(20, 100, cwidth - 40, 50)
    canvas.fill(0, 0, 0)
    canvas.text("SELECT DESIGN:", 30, 130)

    val designNames = Array("DOTS", "ZIGZAG", "FLOWERS")
    for (i <- 0 until 3) {
        val dx = 170 + i * 100
        if (selectedDesign == designNames(i)) canvas.fill(255, 180, 0) else canvas.fill(100, 100, 100)
        canvas.rect(dx, 108, 90, 35)
        canvas.fill(255, 255, 255)
        canvas.text(designNames(i), dx + 12, 130)
    }

    // Draw Main Matka Preview
    drawMatka(canvas, cwidth/2, cheight/2 - 10, matkaColorR, matkaColorG, matkaColorB, selectedDesign, false)

    // Ready to Hang Button
    canvas.fill(0, 180, 80)
    canvas.rect(cwidth/2 - 110, 30, 220, 45)
    canvas.fill(255, 255, 255)
    canvas.text("HANG DAHI HANDI", cwidth/2 - 75, 58)
}

// --- SCREEN 4: CLIMBING & BREAKING GAME (HUMAN PYRAMID / STAIRS) ---
def drawClimbingGameScene(canvas: CanvasDraw) {
    canvas.background(120, 180, 240)

    // Ground
    canvas.noStroke()
    canvas.fill(40, 160, 60)
    canvas.rect(0, 0, cwidth, 70)

    // Handi Ropes
    canvas.stroke(100, 60, 20)
    canvas.strokeWeight(4)
    canvas.line(handiX - 100, cheight, handiX, handiY + 50)
    canvas.line(handiX + 100, cheight, handiX, handiY + 50)
    canvas.noStroke()

    // Draw Handi (Top)
    drawMatka(canvas, handiX, handiY, matkaColorR, matkaColorG, matkaColorB, selectedDesign, isHandiBroken)

    // ============================================================
    // HUMAN PYRAMID / STAIRS (4 - 3 - 2 - 1 LAYER STRUCTURE)
    // ============================================================
    val baseX = cwidth / 2.0
    val startY = 85.0

    // Layer 1 (Bottom Base - 4 Govindas)
    drawGovinda(canvas, baseX - 60, startY, 220, 50, 50)
    drawGovinda(canvas, baseX - 20, startY, 40, 180, 80)
    drawGovinda(canvas, baseX + 20, startY, 220, 50, 50)
    drawGovinda(canvas, baseX + 60, startY, 40, 180, 80)

    // Layer 2 (Middle Tier - 3 Govindas)
    drawGovinda(canvas, baseX - 40, startY + 50, 230, 150, 40)
    drawGovinda(canvas, baseX, startY + 50, 150, 50, 200)
    drawGovinda(canvas, baseX + 40, startY + 50, 230, 150, 40)

    // Layer 3 (Upper Tier - 2 Govindas)
    drawGovinda(canvas, baseX - 20, startY + 100, 40, 150, 220)
    drawGovinda(canvas, baseX + 20, startY + 100, 40, 150, 220)

    // Layer 4 (Top Tier Support - 1 Govinda support)
    drawGovinda(canvas, baseX, startY + 150, 220, 80, 140)

    // ============================================================
    // CLIMBER (Player - Main Govinda Climbing the Pyramid)
    // ============================================================
    drawGovinda(canvas, playerX, playerY, 255, 215, 0) // Yellow Shirt Player

    // Controls Instructions UI
    canvas.fill(30, 30, 30, 180)
    canvas.rect(15, cheight - 90, 220, 75)
    canvas.fill(255, 255, 255)
    canvas.text("KEYBOARD CONTROLS:", 25, cheight - 25)
    canvas.text("Use UP, DOWN, LEFT, RIGHT", 25, cheight - 50)
    canvas.text("to climb human stairs to Matka!", 25, cheight - 70)

    // Distance calculation to Handi
    val dist = math.sqrt(math.pow(playerX - handiX, 2) + math.pow((playerY + 25) - handiY, 2))

    // Show STICK & CRACK Option when near Matka
    if (dist < 65 && !isHandiBroken) {
        canvas.fill(255, 215, 0)
        canvas.rect(cwidth - 170, cheight/2, 140, 45)
        canvas.fill(0, 0, 0)
        canvas.text("USE STICK", cwidth - 145, cheight/2 + 27)

        canvas.fill(220, 40, 40)
        canvas.rect(cwidth - 170, cheight/2 - 60, 140, 45)
        canvas.fill(255, 255, 255)
        canvas.text("CRACK!", cwidth - 135, cheight/2 - 33)
    }

    // Continue to End Screen if Handi is Broken
    if (isHandiBroken) {
        canvas.fill(0, 180, 80)
        canvas.rect(cwidth/2 - 90, 20, 180, 45)
        canvas.fill(255, 255, 255)
        canvas.text("NEXT SCREEN", cwidth/2 - 55, 47)
    }
}

// --- SCREEN 5: FINAL WINNER SCREEN ---
def drawFinalScreen(canvas: CanvasDraw) {
    canvas.background(20, 30, 50)
    repeatFor(stars) { s => s.view(canvas) }

    canvas.fill(255, 215, 0)
    canvas.text("HAPPY GOKULASHTAMI!", cwidth/2 - 130, cheight - 70)

    canvas.fill(255, 255, 255)
    canvas.text("THANK YOU FOR PLAYING THIS GAME!", cwidth/2 - 160, cheight/2 + 40)

    canvas.fill(0, 220, 120)
    canvas.text("BIXUU MISSION IS COMPLETE!", cwidth/2 - 140, cheight/2 - 10)

    canvas.fill(255, 215, 0)
    canvas.text(s"VICTORIOUS TEAM: ${selectedTeam}", cwidth/2 - 150, cheight/2 - 60)
}

// ============================================================
// CLICK & KEYBOARD HANDLERS
// ============================================================
def handleClick(x: Double, y: Double) {
    if (screen == 0) {
        if (x >= cwidth/2 - 110 && x <= cwidth/2 + 110 && y >= 40 && y <= 90) {
            screen = 1
        }
    } else if (screen == 1) {
        if (x >= cwidth/2 - 110 && x <= cwidth/2 + 110 && y >= cheight/2 - 130 && y <= cheight/2 - 80) {
            screen = 2
        }
    } else if (screen == 2) {
        if (x >= cwidth/2 - 150 && x <= cwidth/2 + 150) {
            if (y >= cheight - 160 && y <= cheight - 110) {
                selectedTeam = "GOKULDHAM TEAM"
                screen = 3
            } else if (y >= cheight - 230 && y <= cheight - 180) {
                selectedTeam = "DAHI HANDI TEAM"
                screen = 3
            } else if (y >= cheight - 300 && y <= cheight - 250) {
                selectedTeam = "JAI KRISHNA DAHI HANDI TEAM"
                screen = 3
            }
        }
    } else if (screen == 3) {
        if (y >= cheight - 102 && y <= cheight - 62) {
            val colorsR = Array(210, 30, 220, 255, 140)
            val colorsG = Array(140, 140, 40, 215, 40)
            val colorsB = Array(60, 230, 60, 0, 210)
            for (i <- 0 until 5) {
                val bx = 30 + i * 75
                if (x >= bx && x <= bx + 65) {
                    matkaColorR = colorsR(i)
                    matkaColorG = colorsG(i)
                    matkaColorB = colorsB(i)
                }
            }
        }

        if (y >= 108 && y <= 143) {
            val designNames = Array("DOTS", "ZIGZAG", "FLOWERS")
            for (i <- 0 until 3) {
                val dx = 170 + i * 100
                if (x >= dx && x <= dx + 90) {
                    selectedDesign = designNames(i)
                }
            }
        }

        if (x >= cwidth/2 - 110 && x <= cwidth/2 + 110 && y >= 30 && y <= 75) {
            screen = 4
        }
    } else if (screen == 4) {
        val dist = math.sqrt(math.pow(playerX - handiX, 2) + math.pow((playerY + 25) - handiY, 2))
        
        if (dist < 65 && !isHandiBroken) {
            if (x >= cwidth - 170 && x <= cwidth - 30 && y >= cheight/2 - 60 && y <= cheight/2 + 45) {
                isHandiBroken = true
            }
        }

        if (isHandiBroken && x >= cwidth/2 - 90 && x <= cwidth/2 + 90 && y >= 20 && y <= 65) {
            screen = 5
        }
    }
}

onMouseClick { (x, y) => handleClick(x, y) }

// Keyboard Controls for Climbing
onKeyPress { keyCode =>
    if (screen == 4 && !isHandiBroken) {
        val keyName = keyCode.toString.toUpperCase
        
        if (keyName == "UP" || keyCode == 38) playerY += 12.0
        if ((keyName == "DOWN" || keyCode == 40) && playerY > 60) playerY -= 12.0
        if ((keyName == "LEFT" || keyCode == 37) && playerX > 50) playerX -= 12.0
        if ((keyName == "RIGHT" || keyCode == 39) && playerX < cwidth - 50) playerX += 12.0

        val dist = math.sqrt(math.pow(playerX - handiX, 2) + math.pow((playerY + 25) - handiY, 2))
        if (dist < 65 && (keyName == "SPACE" || keyCode == 32)) {
            isHandiBroken = true
        }
    }
}

// ============================================================
// MAIN ANIMATION LOOP
// ============================================================
animateWithCanvasDraw { canvas =>
    repeatFor(stars) { s => s.step() }

    if (screen == 0) drawIntroScreen(canvas)
    else if (screen == 1) drawLetterScreen(canvas)
    else if (screen == 2) drawTeamSelectScreen(canvas)
    else if (screen == 3) drawMatkaPaintScreen(canvas)
    else if (screen == 4) drawClimbingGameScene(canvas)
    else if (screen == 5) drawFinalScreen(canvas)
}