Code Sketch
Siddhi sabale
Category: Programming
cleari()
originBottomLeft()
// ============================================================
// ISRO MARS MISSION - WORKING ROBOT EDITION
// Scanning, Collecting Samples, Moon, Vikram Lander & Indian Flag
// ============================================================
var robotX = 220.0 //> var robotX: Double = 220.0
var robotY = 145.0 //> var robotY: Double = 145.0
var robotWalk = 0.0 //> var robotWalk: Double = 0.0
var robotBob = 0.0 //> var robotBob: Double = 0.0
var robotGlow = 0.0 //> var robotGlow: Double = 0.0
var robotHeadTurn = 0.0 //> var robotHeadTurn: Double = 0.0
var robotArmWave = 0.0 //> var robotArmWave: Double = 0.0
var robotTime = 0.0 //> var robotTime: Double = 0.0
var robotFacing = 1.0 //> var robotFacing: Double = 1.0
// ------------------------------------------------------------
// Task / Work Logic (??? ???????? ??????)
// 0: Walk, 1: Scan, 2: Collect
// ------------------------------------------------------------
var robotState = 0 //> var robotState: Int = 0
var stateTimer = 0.0 //> var stateTimer: Double = 0.0
var scanAngle = 0.0 //> var scanAngle: Double = 0.0
var armBend = 0.0 //> var armBend: Double = 0.0
// ------------------------------------------------------------
// Meteor / Shooting Star Variables
// ------------------------------------------------------------
var meteorX = cwidth + 50.0 //> var meteorX: Double = 983.0
var meteorY = cheight - 50.0 //> var meteorY: Double = 586.0
var meteorActive = false //> var meteorActive: Boolean = false
var meteorTimer = 0.0 //> var meteorTimer: Double = 0.0
// ------------------------------------------------------------
// Martian Footprints Array
// ------------------------------------------------------------
val maxFootprints = 16 //> val maxFootprints: Int = 16
val fpX = Array.fill(maxFootprints)(-100.0) //> val fpX: Array[Double] = Array(-100.0, -100.0, -100.0, -100.0, -100.0, -100.0, -100.0, -100.0, -100.0, -100.0, -100.0, -100.0, -100.0, -100.0, -100.0, -100.0)
val fpY = Array.fill(maxFootprints)(140.0) //> val fpY: Array[Double] = Array(140.0, 140.0, 140.0, 140.0, 140.0, 140.0, 140.0, 140.0, 140.0, 140.0, 140.0, 140.0, 140.0, 140.0, 140.0, 140.0)
var fpIndex = 0 //> var fpIndex: Int = 0
var lastStepX = robotX //> var lastStepX: Double = 220.0
// ------------------------------------------------------------
// Background Dust & Space Particles
// ------------------------------------------------------------
val particleCount = 70 //> val particleCount: Int = 70
val particleX = Array.fill(particleCount)(randomDouble(0, cwidth)) //> val particleX: Array[Double] = Array(478.11775863389795, 694.3791370989925, 802.9396943127675, 855.1733921637399, 603.8970757421289, 517.5934476658514, 39.56127371996218, 155.5957524851566, 240.61612473926053, 149.78382799585117, 650.8487934483676, 464.4411413691633, 81.812048799087, 82.51096771054041, 52.740621435642595, 304.2073607306411, 42.83027228099717, 349.4110745317351, 720.5932962376811, 547.8881470457093, 668.5956589025639, 351.8359276789348, 65.70259524422477, 884.9324373597506, 925.8245098888092, 176.26725215663745, 903.7117212293451, 204.54163748412938, 96.3175054774039, 264.226028733711, 560.685854513917, 818.8873160751805, 846.8532051175182, 910.2845860092001, 502.3404131158318, 435.6720503562793, 638.9886814702015, 243.83354504669114, 132.02424479139665, 916.953784424772...
val particleY = Array.fill(particleCount)(randomDouble(145, cheight)) //> val particleY: Array[Double] = Array(319.66238187583394, 609.1435291094774, 454.4048417850193, 259.24632551617265, 565.7202980205559, 433.6686992593609, 249.70814839226335, 417.18591409419395, 439.7423049681038, 149.05256699053874, 261.3079881714854, 503.25842346605026, 381.4712187012723, 378.19884389635047, 372.2600502867654, 371.4304891979601, 346.34670851459646, 245.59217192236207, 461.7270757010179, 152.48249017588117, 419.59495645912784, 215.68706255287952, 457.4691783247651, 543.0725898827136, 393.9413073921612, 442.7446688973726, 629.9310953233237, 304.0780322144692, 230.24831312060013, 226.847290289128, 412.9180271913911, 518.0348836830178, 198.40795912660758, 178.08890368389345, 250.54929096723768, 364.3126676380116, 439.93670950678097, 540.0525698581234, 383.47149450035255, 36...
val particleSpeed = Array.fill(particleCount)(randomDouble(0.15, 0.6)) //> val particleSpeed: Array[Double] = Array(0.342608962905256, 0.18775006119326795, 0.3851182316932292, 0.5287425244313773, 0.5517709721584296, 0.37800043404811856, 0.1892715699079466, 0.389984258080623, 0.16534817848350555, 0.5553119838524545, 0.5965239716336354, 0.29336688486652207, 0.24175833758976945, 0.23072125326245174, 0.22558154258803537, 0.2965904390034177, 0.551442449933913, 0.5785523031052398, 0.552126905382487, 0.2884203230969745, 0.3544095594629118, 0.15277366907568304, 0.28423436064495755, 0.27933603677785745, 0.41336630376427974, 0.23654918190540036, 0.4998413717664967, 0.3724815627335132, 0.36091408313264195, 0.18210111149502942, 0.5163463405180908, 0.5511616842061061, 0.36161132873740576, 0.46602133073386853, 0.3292483455666179, 0.16292725194427948, 0.5835752224010691, 0.1...
// ------------------------------------------------------------
// Robot Colors
// ------------------------------------------------------------
val whiteRobot = cm.rgb(245, 248, 250) //> val whiteRobot: net.kogics.kojo.doodle.Color = RGBA(UnsignedByte(117),UnsignedByte(120),UnsignedByte(122),Normalized(1.0))
val whiteShadow = cm.rgb(190, 200, 205) //> val whiteShadow: net.kogics.kojo.doodle.Color = RGBA(UnsignedByte(62),UnsignedByte(72),UnsignedByte(77),Normalized(1.0))
val greenMain = cm.rgb(0, 210, 80) //> val greenMain: net.kogics.kojo.doodle.Color = RGBA(UnsignedByte(-128),UnsignedByte(82),UnsignedByte(-48),Normalized(1.0))
val greenDark = cm.rgb(0, 105, 45) //> val greenDark: net.kogics.kojo.doodle.Color = RGBA(UnsignedByte(-128),UnsignedByte(-23),UnsignedByte(-83),Normalized(1.0))
val greenGlow = cm.rgb(40, 255, 120) //> val greenGlow: net.kogics.kojo.doodle.Color = RGBA(UnsignedByte(-88),UnsignedByte(127),UnsignedByte(-8),Normalized(1.0))
val blackScreen = cm.rgb(5, 8, 18) //> val blackScreen: net.kogics.kojo.doodle.Color = RGBA(UnsignedByte(-123),UnsignedByte(-120),UnsignedByte(-110),Normalized(1.0))
// ------------------------------------------------------------
// UPDATE LOGIC (??? ???????? ?????)
// ------------------------------------------------------------
def updateRobot() {
robotTime += 0.018
robotGlow += 0.08
stateTimer += 0.018
// Shooting Star Logic
meteorTimer += 0.018
if (!meteorActive && meteorTimer > 3.5) {
meteorActive = true
meteorX = randomDouble(cwidth * 0.4, cwidth + 50)
meteorY = randomDouble(cheight - 80, cheight + 20)
meteorTimer = 0.0
}
if (meteorActive) {
meteorX -= 9.0
meteorY -= 5.5
if (meteorY < 180 || meteorX < -50) {
meteorActive = false
}
}
// ----------------------------------------------------------
// State Machine: ????? -> ????? ???? -> ??? ?????
// ----------------------------------------------------------
if (robotState == 0) { // WALKING
robotWalk += 0.09
robotX += 0.5 * robotFacing
robotBob = math.sin(robotWalk * 2.0) * 3.5
robotArmWave = math.sin(robotWalk) * 22.0
robotHeadTurn = math.sin(robotTime * 1.5) * 3.0
// Footprints
if (math.abs(robotX - lastStepX) > 22.0) {
fpX(fpIndex) = robotX - (15.0 * robotFacing)
fpY(fpIndex) = 142.0 + randomDouble(-2, 2)
fpIndex = (fpIndex + 1) % maxFootprints
lastStepX = robotX
}
// 5 ????? ??????????? ????? ??? ???? ???
if (stateTimer > 5.0) {
robotState = 1
stateTimer = 0.0
}
if (robotX > cwidth - 100) robotFacing = -1.0
if (robotX < 100) robotFacing = 1.0
} else if (robotState == 1) { // SCANNING ROCK (????????)
robotBob = math.sin(robotTime * 2.0) * 1.5
robotArmWave = 10.0
scanAngle = math.sin(robotTime * 4.0) * 25.0
robotHeadTurn = -10.0 * robotFacing
// 4 ????? ????? ?????????? ?????? ????
if (stateTimer > 4.0) {
robotState = 2
stateTimer = 0.0
}
} else if (robotState == 2) { // COLLECTING SAMPLE (??? ???? ????)
robotBob = -8.0 // ???? ?????
armBend = math.sin(robotTime * 3.0) * 15.0
robotHeadTurn = -15.0 * robotFacing
// 4 ????? ???? ?????????? ?????? ????? ???? ???
if (stateTimer > 4.0) {
robotState = 0
stateTimer = 0.0
}
}
// Floating Dust Particles
for (i <- 0 until particleCount) {
particleY(i) += particleSpeed(i)
if (particleY(i) > cheight) {
particleY(i) = 145
particleX(i) = randomDouble(0, cwidth)
}
}
} //> def updateRobot(): Unit
// ============================================================
// VIKRAM LANDER
// ============================================================
def drawVikramLander(canvas: CanvasDraw, lx: Double, ly: Double) {
canvas.stroke(180, 180, 190)
canvas.strokeWeight(3.0)
canvas.line(lx - 25, ly, lx - 45, ly - 22)
canvas.line(lx + 25, ly, lx + 45, ly - 22)
canvas.line(lx - 12, ly, lx - 20, ly - 22)
canvas.line(lx + 12, ly, lx + 20, ly - 22)
canvas.fill(120, 120, 130)
canvas.noStroke()
canvas.ellipse(lx - 45, ly - 22, 12, 5)
canvas.ellipse(lx + 45, ly - 22, 12, 5)
canvas.fill(220, 165, 30)
canvas.stroke(180, 130, 20)
canvas.strokeWeight(1.5)
canvas.rect(lx - 28, ly, 56, 32)
canvas.fill(190, 140, 20)
canvas.rect(lx - 20, ly + 32, 40, 14)
canvas.fill(20, 70, 160)
canvas.stroke(40, 100, 200)
canvas.strokeWeight(1)
canvas.rect(lx - 48, ly + 6, 18, 26)
canvas.rect(lx + 30, ly + 6, 18, 26)
canvas.fill(210, 215, 220)
canvas.noStroke()
canvas.ellipse(lx, ly + 52, 16, 10)
canvas.stroke(200, 200, 210)
canvas.strokeWeight(2)
canvas.line(lx, ly + 46, lx, ly + 52)
canvas.fill(255, 153, 51); canvas.noStroke(); canvas.rect(lx - 10, ly + 20, 20, 3)
canvas.fill(255, 255, 255); canvas.rect(lx - 10, ly + 17, 20, 3)
canvas.fill(19, 136, 8); canvas.rect(lx - 10, ly + 14, 20, 3)
} //> def drawVikramLander(canvas: builtins.CanvasDraw, lx: Double, ly: Double): Unit
// ============================================================
// INDIAN TRICOLOR FLAG
// ============================================================
def drawIndianFlag(canvas: CanvasDraw, fx: Double, fy: Double) {
canvas.stroke(210, 215, 220)
canvas.strokeWeight(3.5)
canvas.line(fx, fy, fx, fy + 80)
canvas.fill(255, 215, 0)
canvas.noStroke()
canvas.ellipse(fx, fy + 81, 7, 7)
val wave = math.sin(robotTime * 4.0) * 3.0
canvas.fill(255, 153, 51)
canvas.rect(fx, fy + 58 + wave, 44, 11)
canvas.fill(255, 255, 255)
canvas.rect(fx, fy + 47 + wave, 44, 11)
canvas.stroke(0, 0, 128)
canvas.strokeWeight(1.2)
canvas.ellipse(fx + 22, fy + 52.5 + wave, 7.5, 7.5)
canvas.fill(19, 136, 8)
canvas.noStroke()
canvas.rect(fx, fy + 36 + wave, 44, 11)
} //> def drawIndianFlag(canvas: builtins.CanvasDraw, fx: Double, fy: Double): Unit
// ============================================================
// BACKGROUND & MARS ROCK FOR WORK
// ============================================================
def drawRobotBackground(canvas: CanvasDraw) {
canvas.fill(20, 5, 12)
canvas.noStroke()
canvas.rect(0, 0, cwidth, cheight)
canvas.fill(80, 25, 20)
canvas.rect(0, 0, cwidth, 180)
// Stars
canvas.fill(255, 230, 220)
for (i <- 0 until 40) {
val sx = (i * 37) % cwidth
val sy = 160 + ((i * 53) % (cheight - 160))
canvas.ellipse(sx, sy, 2, 2)
}
// Shooting Star
if (meteorActive) {
canvas.stroke(255, 240, 180, 220)
canvas.strokeWeight(2.5)
canvas.line(meteorX, meteorY, meteorX + 35, meteorY + 22)
canvas.fill(255, 255, 255)
canvas.noStroke()
canvas.ellipse(meteorX, meteorY, 4, 4)
}
// Moon
val mx = cwidth - 130
val my = cheight - 100
canvas.fill(255, 230, 200, 30); canvas.ellipse(mx, my, 110, 110)
canvas.fill(255, 240, 220, 60); canvas.ellipse(mx, my, 85, 85)
canvas.fill(240, 235, 220); canvas.ellipse(mx, my, 65, 65)
canvas.fill(200, 195, 180)
canvas.ellipse(mx - 10, my + 8, 14, 12)
canvas.ellipse(mx + 12, my - 10, 18, 15)
canvas.ellipse(mx + 5, my + 15, 10, 10)
// Earth
canvas.fill(70, 130, 200, 180)
canvas.ellipse(100, cheight - 70, 20, 20)
// Distant Mountains
canvas.fill(90, 30, 25)
canvas.ellipse(100, 145, 320, 120)
canvas.ellipse(350, 145, 450, 160)
canvas.ellipse(650, 145, 380, 140)
drawVikramLander(canvas, 130, 155)
canvas.fill(130, 45, 30)
canvas.ellipse(220, 145, 280, 100)
canvas.ellipse(550, 145, 320, 110)
// Mars Surface
canvas.fill(160, 55, 35)
canvas.rect(0, 0, cwidth, 145)
drawIndianFlag(canvas, 210, 145)
// Craters & Work Rock (???????????? ???)
canvas.fill(120, 40, 25)
canvas.ellipse(80, 60, 90, 25)
canvas.ellipse(340, 40, 130, 30)
canvas.ellipse(620, 80, 110, 28)
// Target Rock for Scanning & Collection (????? ???? ?????? ??? ????)
val targetRockX = robotX + (45.0 * robotFacing)
canvas.fill(80, 25, 15)
canvas.ellipse(targetRockX, 130, 28, 16)
canvas.fill(110, 35, 20)
canvas.ellipse(targetRockX - 3, 132, 18, 10)
// Footprints
canvas.fill(100, 30, 20, 160)
canvas.noStroke()
for (i <- 0 until maxFootprints) {
if (fpX(i) > 0) {
canvas.ellipse(fpX(i), fpY(i), 14, 6)
}
}
// Ground Texture
canvas.stroke(180, 70, 45)
canvas.strokeWeight(1.0)
for (i <- 0 until 8) {
canvas.line(0, 15 + i * 16, cwidth, 15 + i * 16)
}
// Floating Dust
canvas.noStroke()
for (i <- 0 until particleCount) {
val glow = (math.sin(robotTime * 3 + i) * 2 + 3).toFloat
canvas.fill(255, 140, 90, 160)
canvas.ellipse(particleX(i), particleY(i), glow, glow)
}
} //> def drawRobotBackground(canvas: builtins.CanvasDraw): Unit
// ============================================================
// SCANNING LASER EFFECT (???? ??? ??? ????????)
// ============================================================
def drawLaserScan(canvas: CanvasDraw) {
if (robotState == 1) { // Laser Scan State
val hx = robotX + robotHeadTurn
val hy = robotY + robotBob + 198
val targetX = robotX + (45.0 * robotFacing) + scanAngle
// Laser Beam (????????? ??????? ????)
canvas.stroke(0, 255, 100, 200)
canvas.strokeWeight(3.0)
canvas.line(hx, hy, targetX, 130)
// Scanning Cone Glow
canvas.fill(0, 255, 120, 40)
canvas.noStroke()
canvas.ellipse(targetX, 130, 35, 12)
// Laser Dot on Rock
canvas.fill(255, 255, 255)
canvas.ellipse(targetX, 130, 6, 6)
}
} //> def drawLaserScan(canvas: builtins.CanvasDraw): Unit
// ============================================================
// ROBOT PARTS
// ============================================================
def drawRobotShadow(canvas: CanvasDraw) {
canvas.fill(30, 10, 10, 120)
canvas.noStroke()
canvas.ellipse(robotX, 145, 125, 22)
} //> def drawRobotShadow(canvas: builtins.CanvasDraw): Unit
def drawRobotFoot(canvas: CanvasDraw, px: Double, py: Double, angle: Double) {
canvas.pushMatrix()
canvas.translate(px, py)
canvas.rotate(angle)
canvas.fill(0, 255, 100, 35); canvas.noStroke(); canvas.ellipse(0, 0, 58, 28)
canvas.fill(whiteRobot); canvas.stroke(whiteShadow); canvas.strokeWeight(2.0)
canvas.ellipse(0, 0, 60, 32)
canvas.fill(greenMain); canvas.noStroke(); canvas.rect(-25, -5, 50, 8)
canvas.fill(220, 225, 230); canvas.ellipse(18, 3, 25, 18)
canvas.popMatrix()
} //> def drawRobotFoot(canvas: builtins.CanvasDraw, px: Double, py: Double, angle: Double): Unit
def drawRobotLeg(canvas: CanvasDraw, px: Double, py: Double, legAngle: Double) {
canvas.pushMatrix()
canvas.translate(px, py)
canvas.rotate(legAngle)
canvas.fill(whiteRobot); canvas.stroke(whiteShadow); canvas.strokeWeight(2.0)
canvas.rect(-13, -45, 26, 48)
canvas.fill(greenMain); canvas.stroke(greenGlow); canvas.strokeWeight(1.5)
canvas.ellipse(0, -48, 22, 22)
canvas.fill(whiteRobot); canvas.stroke(whiteShadow); canvas.strokeWeight(2.0)
canvas.rect(-15, -92, 30, 45)
canvas.fill(greenMain); canvas.noStroke(); canvas.rect(-15, -88, 7, 35)
canvas.popMatrix()
} //> def drawRobotLeg(canvas: builtins.CanvasDraw, px: Double, py: Double, legAngle: Double): Unit
def drawRobotArm(canvas: CanvasDraw, px: Double, py: Double, armAngle: Double, flip: Boolean) {
canvas.pushMatrix()
canvas.translate(px, py)
if (flip) canvas.scale(-1, 1)
canvas.rotate(armAngle)
canvas.fill(greenMain); canvas.stroke(greenGlow); canvas.strokeWeight(2); canvas.ellipse(0, 0, 30, 30)
canvas.fill(whiteRobot); canvas.stroke(whiteShadow); canvas.strokeWeight(2); canvas.rect(-12, -48, 24, 48)
canvas.fill(greenMain); canvas.noStroke(); canvas.ellipse(0, -50, 19, 19)
canvas.fill(whiteRobot); canvas.stroke(whiteShadow); canvas.strokeWeight(2); canvas.rect(-11, -92, 22, 42)
canvas.fill(greenMain); canvas.noStroke(); canvas.rect(-11, -84, 6, 25)
// Hand / Collector Claw
canvas.fill(whiteRobot); canvas.stroke(whiteShadow); canvas.strokeWeight(2); canvas.ellipse(0, -101, 25, 22)
canvas.fill(greenMain); canvas.noStroke(); canvas.ellipse(0, -103, 13, 10)
// Sample Container in Hand during Collection
if (robotState == 2 && flip) {
canvas.fill(220, 150, 30)
canvas.ellipse(0, -110, 10, 10)
}
canvas.popMatrix()
} //> def drawRobotArm(canvas: builtins.CanvasDraw, px: Double, py: Double, armAngle: Double, flip: Boolean): Unit
def drawRobotBody(canvas: CanvasDraw) {
val bx = robotX
val by = robotY + robotBob
canvas.fill(0, 255, 100, 25); canvas.noStroke(); canvas.ellipse(bx, by + 65, 105, 125)
canvas.fill(whiteRobot); canvas.stroke(whiteShadow); canvas.strokeWeight(2.5); canvas.rect(bx - 48, by + 20, 96, 105)
canvas.fill(greenMain); canvas.noStroke(); canvas.rect(bx - 48, by + 28, 96, 13)
// Reactor Core
canvas.fill(235, 240, 242); canvas.stroke(180, 190, 195); canvas.strokeWeight(1.5); canvas.ellipse(bx, by + 90, 38, 38)
val reactorGlow = (math.sin(robotGlow * 2) * 5 + 18).toFloat
canvas.fill(0, 255, 100, 60); canvas.noStroke(); canvas.ellipse(bx, by + 90, 38 + reactorGlow, 38 + reactorGlow)
canvas.fill(0, 220, 80); canvas.ellipse(bx, by + 90, 18, 18)
canvas.fill(220, 255, 230); canvas.ellipse(bx - 4, by + 94, 6, 6)
// ISRO Branding
canvas.fill(20, 30, 30); canvas.text("ISRO", bx - 18, by + 115)
canvas.fill(greenMain); canvas.noStroke(); canvas.rect(bx - 38, by + 15, 76, 15)
canvas.fill(whiteRobot); canvas.stroke(whiteShadow); canvas.strokeWeight(2); canvas.ellipse(bx, by + 10, 35, 22)
} //> def drawRobotBody(canvas: builtins.CanvasDraw): Unit
def drawRobotHead(canvas: CanvasDraw) {
val hx = robotX + robotHeadTurn
val hy = robotY + robotBob + 170
// Signal Antenna
canvas.stroke(180, 190, 200)
canvas.strokeWeight(2.5)
canvas.line(hx, hy + 60, hx, hy + 88)
val blink = math.sin(robotTime * 12.0)
if (blink > 0 || robotState != 0) {
canvas.fill(255, 40, 40, 100); canvas.noStroke(); canvas.ellipse(hx, hy + 88, 18, 18)
canvas.fill(255, 50, 50); canvas.ellipse(hx, hy + 88, 9, 9)
} else {
canvas.fill(40, 255, 120, 100); canvas.noStroke(); canvas.ellipse(hx, hy + 88, 18, 18)
canvas.fill(0, 255, 100); canvas.ellipse(hx, hy + 88, 9, 9)
}
// Head Base
canvas.fill(0, 255, 120, 25); canvas.noStroke(); canvas.ellipse(hx, hy, 100, 75)
canvas.fill(greenDark); canvas.stroke(greenMain); canvas.strokeWeight(2); canvas.rect(hx - 15, hy - 43, 30, 25)
canvas.fill(whiteRobot); canvas.stroke(whiteShadow); canvas.strokeWeight(2.5); canvas.rect(hx - 45, hy - 5, 90, 65)
// Face Screen & LED Eyes
canvas.fill(blackScreen); canvas.stroke(20, 40, 50); canvas.strokeWeight(3); canvas.rect(hx - 35, hy + 5, 70, 42)
canvas.fill(greenMain); canvas.stroke(greenGlow); canvas.strokeWeight(2); canvas.ellipse(hx + 45, hy + 28, 17, 30)
val eyeMove = if (robotState == 1) scanAngle * 0.2 else math.sin(robotTime * 2) * 2.0
canvas.fill(40, 180, 255); canvas.ellipse(hx - 17, hy + 28 + eyeMove, 7, 7); canvas.ellipse(hx + 17, hy + 28 + eyeMove, 7, 7)
canvas.stroke(40, 180, 255); canvas.strokeWeight(2); canvas.line(hx - 15, hy + 15, hx + 15, hy + 15)
for (i <- 0 until 5) {
canvas.line(hx - 25 + i * 12, hy + 48, hx - 20 + i * 12, hy + 48)
}
} //> def drawRobotHead(canvas: builtins.CanvasDraw): Unit
// ============================================================
// MAIN DRAW
// ============================================================
def drawFuturisticRobot(canvas: CanvasDraw) {
val by = robotY + robotBob
// Working Arms Motion Based on State
var rightArmAngle = -robotArmWave
var leftArmAngle = robotArmWave
if (robotState == 1) { // Scanning
rightArmAngle = 45.0
leftArmAngle = -20.0
} else if (robotState == 2) { // Collecting
rightArmAngle = 75.0 + armBend
leftArmAngle = 30.0
}
drawRobotArm(canvas, robotX - 48, by + 105, leftArmAngle, false)
drawRobotArm(canvas, robotX + 48, by + 105, rightArmAngle, true)
val leftLegAngle = if (robotState == 0) math.sin(robotWalk) * 15.0 else 0.0
val rightLegAngle = if (robotState == 0) -math.sin(robotWalk) * 15.0 else 0.0
drawRobotLeg(canvas, robotX - 23, by + 10, leftLegAngle)
drawRobotLeg(canvas, robotX + 23, by + 10, rightLegAngle)
drawRobotFoot(canvas, robotX - 30 + math.sin(robotWalk) * 8, 150, leftLegAngle)
drawRobotFoot(canvas, robotX + 30 - math.sin(robotWalk) * 8, 150, rightLegAngle)
drawRobotBody(canvas)
drawRobotHead(canvas)
drawLaserScan(canvas)
} //> def drawFuturisticRobot(canvas: builtins.CanvasDraw): Unit
// ============================================================
// HUD STATUS FOR WORK
// ============================================================
def drawRobotHUD(canvas: CanvasDraw) {
canvas.fill(255, 220, 200)
canvas.text("ISRO MARS EXPLORER MISSION", 25, cheight - 30)
// dynamic status update based on robot work
if (robotState == 0) {
canvas.fill(0, 255, 120)
canvas.text("SYSTEM : ONLINE | SEARCHING FOR SAMPLE ROCKS", 25, cheight - 55)
} else if (robotState == 1) {
canvas.fill(255, 200, 0)
canvas.text("SYSTEM : SCANNING ROCK SAMPLE WITH LASER...", 25, cheight - 55)
} else if (robotState == 2) {
canvas.fill(0, 200, 255)
canvas.text("SYSTEM : COLLECTING & STORING MARS SOIL...", 25, cheight - 55)
}
// Energy HUD
canvas.fill(30, 40, 45); canvas.stroke(0, 255, 120); canvas.strokeWeight(2); canvas.rect(cwidth - 190, cheight - 65, 150, 18)
canvas.fill(0, 230, 90); canvas.rect(cwidth - 186, cheight - 61, 135, 10)
canvas.fill(255, 255, 255); canvas.text("ENERGY 95%", cwidth - 180, cheight - 72)
} //> def drawRobotHUD(canvas: builtins.CanvasDraw): Unit
def viewRobot(canvas: CanvasDraw) {
canvas.fill(0, 0, 0); canvas.noStroke(); canvas.rect(0, 0, cwidth, cheight)
drawRobotBackground(canvas)
drawRobotShadow(canvas)
drawFuturisticRobot(canvas)
drawRobotHUD(canvas)
} //> def viewRobot(canvas: builtins.CanvasDraw): Unit
// ============================================================
// START ANIMATION
// ============================================================
animateWithCanvasDraw { canvas =>
updateRobot()
viewRobot(canvas)
}