Code Sketch


Bixuu02
By: Mhalsakant School
Category: Programming
// ============================================================
// TEACHER'S DAY ANIMATED MISSION GAME - SCHOOL & Q-BOT EDITION
// ============================================================

cleari()
originBottomLeft()

// ============================================================
// GAME STATES & ANIMATION VARIABLES
// ============================================================
var screen = 0
var selectedStandard = ""
var selectedSection = ""
var showSpaceFactModal = false
var factMode = 1 // 1: Saturn Facts, 2: Eclipse & Solar Facts

// Car and Animation Variables
var carX = -120.0
var carY = 100.0
var isCarLeaving = 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 DETAILED AVATARS (TEACHER, STUDENT, & Q-BOT)
// ============================================================
def drawDetailedAvatar(canvas: CanvasDraw, x: Double, y: Double, gender: String, scale: Double) {
    canvas.noStroke()
    if (gender == "WOMAN") {
        canvas.fill(30, 20, 15)
        canvas.ellipse(x, y + 20 * scale, 75 * scale, 85 * scale)
        canvas.fill(255, 220, 180)
        canvas.ellipse(x, y + 25 * scale, 55 * scale, 60 * scale)
        canvas.fill(100, 30, 180) 
        canvas.rect(x - 30 * scale, y - 60 * scale, 60 * scale, 70 * scale)
        canvas.fill(255, 215, 0) 
        canvas.line(x - 30 * scale, y - 60 * scale, x + 20 * scale, y + 5 * scale)
    } else {
        canvas.fill(30, 30, 30)
        canvas.ellipse(x, y + 40 * scale, 60 * scale, 30 * scale)
        canvas.fill(255, 220, 180)
        canvas.ellipse(x, y + 20 * scale, 55 * scale, 55 * scale)
        canvas.fill(30, 50, 100)
        canvas.rect(x - 25 * scale, y - 60 * scale, 50 * scale, 60 * scale)
    }

    // Eyes & Smile
    canvas.fill(0, 0, 0)
    canvas.ellipse(x - 12 * scale, y + 22 * scale, 6 * scale, 8 * scale)
    canvas.ellipse(x + 12 * scale, y + 22 * scale, 6 * scale, 8 * scale)
    canvas.stroke(180, 50, 50)
    canvas.strokeWeight(2 * scale)
    canvas.line(x - 10 * scale, y + 8 * scale, x + 10 * scale, y + 8 * scale)
}

def drawQBot(canvas: CanvasDraw, x: Double, y: Double) {
    canvas.noStroke()
    // Robot Body & Head
    canvas.fill(0, 180, 216)
    canvas.rect(x - 25, y - 10, 50, 45)
    canvas.fill(144, 224, 239)
    canvas.rect(x - 20, y + 40, 40, 35)
    
    // Antenna
    canvas.stroke(0, 119, 182)
    canvas.strokeWeight(3)
    canvas.line(x, y + 75, x, y + 90)
    canvas.fill(247, 127, 0)
    canvas.noStroke()
    canvas.ellipse(x, y + 92, 10, 10)

    // Robot Screen Face & Glowing Eyes
    canvas.fill(3, 4, 94)
    canvas.rect(x - 15, y + 48, 30, 20)
    canvas.fill(0, 255, 204)
    canvas.ellipse(x - 7, y + 58, 6, 6)
    canvas.ellipse(x + 7, y + 58, 6, 6)
}

// ============================================================
// CAR ANIMATION DRAWING
// ============================================================
def drawDetailedCarWithTeacher(canvas: CanvasDraw, x: Double, y: Double) {
    canvas.noStroke()
    canvas.fill(50, 50, 50, 100)
    canvas.ellipse(x + 75, y - 5, 160, 20)

    // Main Body
    canvas.fill(30, 144, 255)
    canvas.rect(x, y + 10, 150, 45)
    canvas.rect(x + 30, y + 55, 85, 35)

    // Windows & Teacher
    canvas.fill(180, 220, 255)
    canvas.rect(x + 35, y + 58, 35, 28)
    canvas.rect(x + 75, y + 58, 35, 28)
    drawDetailedAvatar(canvas, x + 92, y + 68, "WOMAN", 0.35)

    // Wheels
    canvas.noStroke()
    val wheelPositions = Array(x + 35, x + 115)
    for (wx <- wheelPositions) {
        canvas.fill(20, 20, 20)
        canvas.ellipse(wx, y + 8, 36, 36)
        canvas.fill(200, 200, 200)
        canvas.ellipse(wx, y + 8, 20, 20)
    }
}

// ============================================================
// SCREEN 0: LETTER SCREEN (ENGLISH TRANSLATED)
// ============================================================
def drawLetterScreen(canvas: CanvasDraw) {
    canvas.background(20, 30, 50)
    repeatFor(stars) { s => s.view(canvas) }

    // Letter Card
    canvas.fill(255, 248, 220)
    canvas.stroke(212, 175, 55)
    canvas.strokeWeight(4)
    canvas.rect(cwidth/2 - 240, cheight/2 - 180, 480, 370)

    canvas.fill(180, 0, 0)
    canvas.text("HAPPY TEACHER'S DAY!", cwidth/2 - 140, cheight/2 + 140)

    canvas.fill(40, 40, 40)
    canvas.text("Dear Teacher,", cwidth/2 - 210, cheight/2 + 100)
    canvas.text("You have been selected to become our teacher!", cwidth/2 - 210, cheight/2 + 70)
    canvas.text("We hope you will teach and guide us with wisdom.", cwidth/2 - 210, cheight/2 + 45)
    canvas.text("Thank you so much for participating in this mission!", cwidth/2 - 210, cheight/2 + 20)
    
    canvas.fill(0, 120, 50)
    canvas.text("Thank You Teacher!", cwidth/2 - 210, cheight/2 - 15)

    // Mission Button
    canvas.fill(220, 50, 50)
    canvas.noStroke()
    canvas.rect(cwidth/2 - 150, cheight/2 - 120, 300, 50)
    canvas.fill(255, 255, 255)
    canvas.text("COMPLETE TEACHER'S DAY MISSION", cwidth/2 - 135, cheight/2 - 90)
}

// ============================================================
// SCREEN 1: STANDARD / CLASS SELECTION (5th, 6th, 7th, 8th)
// ============================================================
def drawClassSelection(canvas: CanvasDraw) {
    canvas.background(30, 30, 60)
    canvas.fill(255, 255, 255)
    canvas.text("SELECT CLASS / STANDARD", cwidth/2 - 120, cheight - 80)

    val standards = Array("5th Standard", "6th Standard", "7th Standard", "8th Standard")
    val colors = Array((0, 150, 136), (230, 81, 0), (123, 31, 162), (25, 118, 210))

    for (i <- 0 until 4) {
        val bx = if (i % 2 == 0) cwidth/2 - 190 else cwidth/2 + 20
        val by = if (i < 2) cheight/2 + 20 else cheight/2 - 80
        val (r, g, b) = colors(i)
        
        canvas.fill(r, g, b)
        canvas.rect(bx, by, 170, 70)
        canvas.fill(255, 255, 255)
        canvas.text(standards(i), bx + 25, by + 30)
    }
}

// ============================================================
// SCREEN 2: SECTION / TUKDI SELECTION (A, B, C)
// ============================================================
def drawSectionSelection(canvas: CanvasDraw) {
    canvas.background(40, 40, 70)
    canvas.fill(255, 255, 255)
    canvas.text(s"SELECT SECTION FOR $selectedStandard", cwidth/2 - 140, cheight - 80)

    val sections = Array(s"$selectedStandard - A", s"$selectedStandard - B", s"$selectedStandard - C")
    
    for (i <- 0 until 3) {
        val bx = cwidth/2 - 110
        val by = cheight/2 + 60 - (i * 70)
        canvas.fill(0, 120, 200)
        canvas.rect(bx, by, 220, 50)
        canvas.fill(255, 255, 255)
        canvas.text(sections(i), bx + 45, by + 20)
    }
}

// ============================================================
// SCREEN 3: CLASSROOM ENTRANCE SCENE
// ============================================================
def drawClassroomEntranceScreen(canvas: CanvasDraw) {
    canvas.background(135, 206, 235)

    // Ground and School Wall
    canvas.fill(60, 140, 60)
    canvas.rect(0, 0, cwidth, 150)
    canvas.fill(235, 200, 150)
    canvas.rect(cwidth/2 - 180, 150, 360, 200)
    
    // Classroom Door
    canvas.fill(120, 60, 20)
    canvas.rect(cwidth/2 - 45, 150, 90, 140)
    canvas.fill(255, 215, 0)
    canvas.ellipse(cwidth/2 + 25, 210, 12, 12)

    // Name Plate
    canvas.fill(40, 40, 40)
    canvas.rect(cwidth/2 - 70, 300, 140, 35)
    canvas.fill(255, 255, 255)
    canvas.text(s"CLASS $selectedSection", cwidth/2 - 50, 312)

    // Teacher standing at the door
    drawDetailedAvatar(canvas, cwidth/2 - 110, 180, "WOMAN", 0.6)

    // ENTER CLASSROOM BUTTON
    canvas.fill(0, 180, 80)
    canvas.noStroke()
    canvas.rect(cwidth / 2 - 100, 30, 200, 50)
    canvas.fill(255, 255, 255)
    canvas.text("ENTER CLASSROOM", cwidth / 2 - 75, 52)
}

// ============================================================
// SCREEN 4: INSIDE CLASSROOM & Q-BOT KBC ASTRONOMY QUIZ
// ============================================================
def drawClassroomScreen(canvas: CanvasDraw) {
    canvas.background(240, 230, 210)

    // RED EXIT BUTTON (TOP RIGHT)
    canvas.fill(220, 20, 20)
    canvas.noStroke()
    canvas.rect(cwidth - 160, cheight - 50, 140, 40)
    canvas.fill(255, 255, 255)
    canvas.text("EXIT CLASSROOM", cwidth - 150, cheight - 26)

    // Blackboard
    canvas.fill(30, 70, 40)
    canvas.stroke(120, 70, 20)
    canvas.strokeWeight(8)
    canvas.rect(60, 160, cwidth - 120, 220)

    canvas.noStroke()
    canvas.fill(255, 255, 255)
    canvas.text(s"WELCOME TO CLASS $selectedSection!", 80, 355)
    
    // KBC Space Question on Board
    canvas.fill(255, 215, 0)
    canvas.text("Q-BOT ASTRONOMY QUIZ (KBC STYLE):", 80, 320)
    canvas.fill(255, 255, 255)
    canvas.text("Question: What is the real color and appearance of Saturn?", 80, 290)
    
    // Q-Bot Answer
    canvas.fill(100, 255, 100)
    canvas.text("Q-Bot Answer: Saturn appears yellowish-gold due to ammonia", 80, 250)
    canvas.text("crystals in its atmosphere, surrounded by icy rings!", 80, 225)

    // Draw Characters inside Classroom
    drawDetailedAvatar(canvas, 120, 50, "WOMAN", 0.6) // Teacher
    drawQBot(canvas, cwidth/2, 50)                     // Q-Bot
    drawDetailedAvatar(canvas, cwidth - 140, 50, "MAN", 0.5) // Student

    // TWO INTERACTIVE BUTTONS
    canvas.fill(0, 120, 210)
    canvas.rect(70, 70, 210, 45)
    canvas.fill(255, 255, 255)
    canvas.text("LEARN REAL SPACE FACTS", 82, 88)

    canvas.fill(156, 39, 176)
    canvas.rect(300, 70, 210, 45)
    canvas.fill(255, 255, 255)
    canvas.text("EXPLORE PLANET DETAILS", 310, 88)

    // REAL SPACE FACTS POPUP MODAL
    if (showSpaceFactModal) {
        canvas.fill(10, 15, 30, 230)
        canvas.rect(100, 110, cwidth - 200, 220)
        canvas.fill(255, 215, 0)
        
        if (factMode == 1) {
            canvas.text("REAL SPACE FACT: SATURN & PLANETS", 120, 300)
            canvas.fill(255, 255, 255)
            canvas.text("1. Saturn's rings are made mostly of ice chunks and dust.", 120, 260)
            canvas.text("2. Saturn is so light it could float in a giant bathtub of water!", 120, 230)
            canvas.text("3. It takes Saturn 29.5 Earth years to orbit the Sun once.", 120, 200)
        } else {
            canvas.text("REAL SPACE FACT: ECLIPSES & MOONS", 120, 300)
            canvas.fill(255, 255, 255)
            canvas.text("1. A Solar Eclipse happens when the Moon blocks the Sun.", 120, 260)
            canvas.text("2. Saturn has over 140 confirmed moons, Titan being largest!", 120, 230)
            canvas.text("3. Space is completely silent because there is no atmosphere.", 120, 200)
        }

        canvas.fill(220, 50, 50)
        canvas.rect(cwidth/2 - 50, 125, 100, 35)
        canvas.fill(255, 255, 255)
        canvas.text("CLOSE", cwidth/2 - 22, 137)
    }
}

// ============================================================
// SCREEN 5: EXIT SCENE (CAR DRIVING AWAY)
// ============================================================
def drawExitCarAnimation(canvas: CanvasDraw) {
    canvas.background(135, 206, 235)

    canvas.noStroke()
    canvas.fill(40, 160, 60)
    canvas.rect(0, 0, cwidth, 160)
    canvas.fill(70, 70, 75)
    canvas.rect(0, 80, cwidth, 70) 

    // School Building in background
    canvas.fill(235, 200, 150)
    canvas.rect(100, 140, 220, 130)
    canvas.fill(120, 60, 20)
    canvas.rect(180, 140, 60, 80)

    drawDetailedCarWithTeacher(canvas, carX, carY)

    canvas.fill(0, 0, 0)
    canvas.text("Teacher is returning home after a great class...", cwidth/2 - 150, cheight - 50)
}

// ============================================================
// SCREEN 6: COMPLETION / THANK YOU SCREEN
// ============================================================
def drawCompletionScreen(canvas: CanvasDraw) {
    canvas.background(20, 60, 30)
    repeatFor(stars) { s => s.view(canvas) }

    canvas.fill(255, 215, 0)
    canvas.text("MISSION COMPLETED SUCCESSFULLY!", cwidth/2 - 150, cheight/2 + 60)

    canvas.fill(255, 255, 255)
    canvas.text("Thank you for being an inspiring teacher,", cwidth/2 - 140, cheight/2 + 15)
    canvas.text(s"and teaching Class $selectedSection with fun games and facts!", cwidth/2 - 180, cheight/2 - 15)
}

// ============================================================
// ANIMATION UPDATER
// ============================================================
def updateDeliveryAnimation() {
    if (screen == 5) {
        carX += 4.5
        if (carX > cwidth + 100) {
            screen = 6 
        }
    }
}

// ============================================================
// CLICK HANDLER
// ============================================================
def handleClick(x: Double, y: Double) {
    if (screen == 0) {
        // Complete Mission Button
        if (x >= cwidth/2 - 150 && x <= cwidth/2 + 150 && y >= cheight/2 - 120 && y <= cheight/2 - 70) {
            screen = 1
        }
    } else if (screen == 1) {
        // Class Selection
        val standards = Array("5th Standard", "6th Standard", "7th Standard", "8th Standard")
        for (i <- 0 until 4) {
            val bx = if (i % 2 == 0) cwidth/2 - 190 else cwidth/2 + 20
            val by = if (i < 2) cheight/2 + 20 else cheight/2 - 80
            if (x >= bx && x <= bx + 170 && y >= by && y <= by + 70) {
                selectedStandard = standards(i)
                screen = 2
            }
        }
    } else if (screen == 2) {
        // Section Selection
        for (i <- 0 until 3) {
            val bx = cwidth/2 - 110
            val by = cheight/2 + 60 - (i * 70)
            if (x >= bx && x <= bx + 220 && y >= by && y <= by + 50) {
                val secLetter = if (i == 0) "A" else if (i == 1) "B" else "C"
                selectedSection = s"$selectedStandard - $secLetter"
                screen = 3
            }
        }
    } else if (screen == 3) {
        // Enter Classroom Button
        if (x >= cwidth / 2 - 100 && x <= cwidth / 2 + 100 && y >= 30 && y <= 80) {
            screen = 4
        }
    } else if (screen == 4) {
        // Modal Close Button
        if (showSpaceFactModal) {
            if (x >= cwidth/2 - 50 && x <= cwidth/2 + 50 && y >= 125 && y <= 160) {
                showSpaceFactModal = false
            }
        } else {
            // RED EXIT BUTTON
            if (x >= cwidth - 160 && x <= cwidth - 20 && y >= cheight - 50 && y <= cheight - 10) {
                carX = -120.0
                screen = 5
            }
            // LEARN REAL SPACE FACTS Button
            else if (x >= 70 && x <= 280 && y >= 70 && y <= 115) {
                factMode = 1
                showSpaceFactModal = true
            }
            // EXPLORE PLANET DETAILS Button
            else if (x >= 300 && x <= 510 && y >= 70 && y <= 115) {
                factMode = 2
                showSpaceFactModal = true
            }
        }
    }
}

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

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

    if (screen == 0) drawLetterScreen(canvas)
    else if (screen == 1) drawClassSelection(canvas)
    else if (screen == 2) drawSectionSelection(canvas)
    else if (screen == 3) drawClassroomEntranceScreen(canvas)
    else if (screen == 4) drawClassroomScreen(canvas)
    else if (screen == 5) drawExitCarAnimation(canvas)
    else if (screen == 6) drawCompletionScreen(canvas)
}