Code Sketch


siddhi sabale
By: Mhalsakant School
Category: Art
cleari()
originBottomLeft()

// ============================================================
// FUTURISTIC HUMANOID ROBOT
// White + Green ISRO/Indian Tech Style
// Smooth Walking + Glowing LED + Floating Particles
// ============================================================

var robotX = cwidth / 2.0 //> var robotX: Double = 387.5
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 robotMoving = true //> var robotMoving: Boolean = true
var robotFacing = 1.0 //> var robotFacing: Double = 1.0

// ------------------------------------------------------------
// Background particles
// ------------------------------------------------------------

val particleCount = 70 //> val particleCount: Int = 70

val particleX = Array.fill(particleCount)(
  randomDouble(0, cwidth)
) //> val particleX: Array[Double] = Array(391.8611855047305, 45.88452263759922, 211.88538096175458, 769.4567349466328, 302.2637434192786, 94.7958551174746, 77.71649668506214, 89.16153510337246, 104.78170846067863, 34.65539025011075, 706.9182412320571, 291.45578491820635, 246.7289150802431, 196.6438003201785, 749.5333303303903, 507.436525021004, 151.6952741792427, 425.68452444457375, 734.2917038753615, 655.2842660524565, 728.889670385686, 537.2811434064788, 60.474903568652294, 341.9566814500125, 56.9114917554567, 651.3992177526851, 338.2749547615437, 577.2320214659142, 579.9198907428803, 591.3312110237911, 9.256853032494138, 689.0055086745774, 417.81747368760455, 605.9667880637394, 441.79081261532286, 733.2094677695351, 498.6811486899125, 631.0924100581487, 515.0462537334541, 420.414524588267...

val particleY = Array.fill(particleCount)(
  randomDouble(145, cheight)
) //> val particleY: Array[Double] = Array(457.7974620942811, 450.1831183008426, 507.63669696706097, 422.32739440985455, 230.0973743357377, 453.9471936622935, 456.2038343315856, 425.57195758784263, 271.69689063477773, 460.37021236814076, 379.29573332555253, 362.3693195984231, 250.9810060256379, 411.20971346264923, 485.18250948130077, 360.3680988780934, 179.81890368852655, 148.88038394920324, 406.60534804771964, 506.81780154847434, 472.9154442252858, 466.9129044711169, 213.22365201189618, 452.8096234368178, 495.19828560259265, 291.15641960506355, 417.76859442600926, 413.12389960124915, 304.8239204541667, 371.57902030435315, 375.96210306279715, 332.97508204262056, 284.1967191086168, 422.62809106861596, 228.53962914152106, 305.2714100758087, 442.6430049705462, 206.15738730619947, 199.43177116785...

val particleSpeed = Array.fill(particleCount)(
  randomDouble(0.3, 1.2)
) //> val particleSpeed: Array[Double] = Array(0.500675618233515, 1.1923539570322093, 0.4673672591932777, 0.4736347428060097, 0.8302688934778524, 0.5660553918925695, 0.8109317044567483, 0.4204299326736608, 0.7376930479724783, 0.8077553287954666, 0.734670155364143, 0.4111256224343734, 1.1953081138960397, 0.7899405008444076, 0.7303335744596944, 1.0188734249036622, 1.0085384260135775, 0.45374632678727966, 0.8140100355644007, 0.4115977034929539, 0.587049429251053, 0.4135456750211185, 0.8239569270705531, 1.1938283838654011, 0.6980570076563426, 1.145493143886518, 0.7597839670834011, 0.5480181177217187, 1.145425342515297, 0.6016537994710008, 1.1043472568768997, 0.9010062043465474, 0.5643994781096411, 0.3914431302268912, 1.1299688215484842, 1.117951146431215, 0.4211364073439216, 1.0503274994951637, 0...

// ------------------------------------------------------------
// 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))
val blueLED = cm.rgb(40, 180, 255) //> val blueLED: net.kogics.kojo.doodle.Color = RGBA(UnsignedByte(-88),UnsignedByte(52),UnsignedByte(127),Normalized(1.0))

// ------------------------------------------------------------
// UPDATE
// ------------------------------------------------------------

def updateRobot() {

  robotTime += 0.035
  robotWalk += 0.18
  robotGlow += 0.15

  if (robotMoving) {

    robotX += 1.25 * robotFacing

    // Smooth walking bob
    robotBob = math.sin(robotWalk * 2.0) * 3.5

    // Walking animation
    robotArmWave = math.sin(robotWalk) * 22.0

    // Head slight movement
    robotHeadTurn = math.sin(robotTime * 1.5) * 3.0

    // Screen boundary
    if (robotX > cwidth - 100) {
      robotFacing = -1.0
    }

    if (robotX < 100) {
      robotFacing = 1.0
    }

  } else {

    robotBob = math.sin(robotTime * 2.0) * 2.0
    robotArmWave = math.sin(robotTime) * 5.0
  }

  // Move particles upward
  for (i <- 0 until particleCount) {

    particleY(i) += particleSpeed(i)

    if (particleY(i) > cheight) {
      particleY(i) = 145
      particleX(i) = randomDouble(0, cwidth)
    }
  }
} //> def updateRobot(): Unit

// ============================================================
// BACKGROUND
// ============================================================

def drawRobotBackground(canvas: CanvasDraw) {

  // Sky
  canvas.fill(12, 20, 45)
  canvas.noStroke()
  canvas.rect(0, 0, cwidth, cheight)

  // Horizon glow
  canvas.fill(10, 55, 75)
  canvas.rect(0, 0, cwidth, 150)

  // Ground
  canvas.fill(30, 45, 48)
  canvas.rect(0, 0, cwidth, 145)

  // Ground strips
  canvas.stroke(60, 90, 90)
  canvas.strokeWeight(1.0)

  for (i <- 0 until 10) {
    canvas.line(
      0,
      15 + i * 13,
      cwidth,
      15 + i * 13
    )
  }

  // Futuristic buildings
  canvas.fill(25, 35, 55)

  canvas.rect(20, 145, 100, 240)
  canvas.rect(135, 145, 80, 180)
  canvas.rect(cwidth - 150, 145, 110, 260)

  // Building lights
  canvas.fill(70, 220, 150)

  for (i <- 0 until 6) {

    canvas.rect(
      40,
      175 + i * 32,
      15,
      8
    )

    canvas.rect(
      165,
      175 + i * 25,
      12,
      7
    )

    canvas.rect(
      cwidth - 125,
      180 + i * 30,
      15,
      8
    )
  }

  // Floating particles
  canvas.noStroke()

  for (i <- 0 until particleCount) {

    val glow =
      (math.sin(robotTime * 3 + i) * 2 + 4).toFloat

    canvas.fill(
      40,
      255,
      150,
      150
    )

    canvas.ellipse(
      particleX(i),
      particleY(i),
      glow,
      glow
    )
  }
} //> def drawRobotBackground(canvas: builtins.CanvasDraw): Unit

// ============================================================
// ROBOT SHADOW
// ============================================================

def drawRobotShadow(canvas: CanvasDraw) {

  canvas.fill(0, 0, 0, 100)
  canvas.noStroke()

  canvas.ellipse(
    robotX,
    145,
    125,
    22
  )
} //> def drawRobotShadow(canvas: builtins.CanvasDraw): Unit

// ============================================================
// ROBOT FOOT
// ============================================================

def drawRobotFoot(
  canvas: CanvasDraw,
  px: Double,
  py: Double,
  angle: Double
) {

  canvas.pushMatrix()
  canvas.translate(px, py)
  canvas.rotate(angle)

  // Glow
  canvas.fill(0, 255, 100, 35)
  canvas.noStroke()
  canvas.ellipse(0, 0, 58, 28)

  // Main shoe
  canvas.fill(whiteRobot)
  canvas.stroke(whiteShadow)
  canvas.strokeWeight(2.0)

  canvas.ellipse(
    0,
    0,
    60,
    32
  )

  // Green sole
  canvas.fill(greenMain)
  canvas.noStroke()

  canvas.rect(
    -25,
    -5,
    50,
    8
  )

  // Shoe front
  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

// ============================================================
// ROBOT LEG
// ============================================================

def drawRobotLeg(
  canvas: CanvasDraw,
  px: Double,
  py: Double,
  legAngle: Double
) {

  canvas.pushMatrix()
  canvas.translate(px, py)
  canvas.rotate(legAngle)

  // Upper leg
  canvas.fill(whiteRobot)
  canvas.stroke(whiteShadow)
  canvas.strokeWeight(2.0)

  canvas.rect(
    -13,
    -45,
    26,
    48
  )

  // Knee joint
  canvas.fill(greenMain)
  canvas.stroke(greenGlow)
  canvas.strokeWeight(1.5)

  canvas.ellipse(
    0,
    -48,
    22,
    22
  )

  // Lower leg
  canvas.fill(whiteRobot)
  canvas.stroke(whiteShadow)
  canvas.strokeWeight(2.0)

  canvas.rect(
    -15,
    -92,
    30,
    45
  )

  // Green mechanical strip
  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

// ============================================================
// ROBOT ARM
// ============================================================

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)

  // Shoulder joint
  canvas.fill(greenMain)
  canvas.stroke(greenGlow)
  canvas.strokeWeight(2)

  canvas.ellipse(
    0,
    0,
    30,
    30
  )

  // Upper arm
  canvas.fill(whiteRobot)
  canvas.stroke(whiteShadow)
  canvas.strokeWeight(2)

  canvas.rect(
    -12,
    -48,
    24,
    48
  )

  // Elbow
  canvas.fill(greenMain)
  canvas.noStroke()

  canvas.ellipse(
    0,
    -50,
    19,
    19
  )

  // Forearm
  canvas.fill(whiteRobot)
  canvas.stroke(whiteShadow)
  canvas.strokeWeight(2)

  canvas.rect(
    -11,
    -92,
    22,
    42
  )

  // Green forearm panel
  canvas.fill(greenMain)
  canvas.noStroke()

  canvas.rect(
    -11,
    -84,
    6,
    25
  )

  // Hand
  canvas.fill(whiteRobot)
  canvas.stroke(whiteShadow)
  canvas.strokeWeight(2)

  canvas.ellipse(
    0,
    -101,
    25,
    22
  )

  // Green palm
  canvas.fill(greenMain)
  canvas.noStroke()

  canvas.ellipse(
    0,
    -103,
    13,
    10
  )

  canvas.popMatrix()
} //> def drawRobotArm(canvas: builtins.CanvasDraw, px: Double, py: Double, armAngle: Double, flip: Boolean): Unit

// ============================================================
// ROBOT BODY
// ============================================================

def drawRobotBody(canvas: CanvasDraw) {

  val bx = robotX
  val by = robotY + robotBob

  // Body glow
  canvas.fill(0, 255, 100, 25)
  canvas.noStroke()

  canvas.ellipse(
    bx,
    by + 65,
    105,
    125
  )

  // Main chest
  canvas.fill(whiteRobot)
  canvas.stroke(whiteShadow)
  canvas.strokeWeight(2.5)

  canvas.rect(
    bx - 48,
    by + 20,
    96,
    105
  )

  // Chest green belt
  canvas.fill(greenMain)
  canvas.noStroke()

  canvas.rect(
    bx - 48,
    by + 28,
    96,
    13
  )

  // Chest center panel
  canvas.fill(235, 240, 242)
  canvas.stroke(180, 190, 195)
  canvas.strokeWeight(1.5)

  canvas.ellipse(
    bx,
    by + 90,
    38,
    38
  )

  // Glowing chest reactor
  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
  )

  // "BOT" logo
  canvas.fill(20, 30, 30)
  canvas.text(
    "BOT",
    bx - 18,
    by + 115
  )

  // Green waist
  canvas.fill(greenMain)
  canvas.noStroke()

  canvas.rect(
    bx - 38,
    by + 15,
    76,
    15
  )

  // Waist joint
  canvas.fill(whiteRobot)
  canvas.stroke(whiteShadow)
  canvas.strokeWeight(2)

  canvas.ellipse(
    bx,
    by + 10,
    35,
    22
  )
} //> def drawRobotBody(canvas: builtins.CanvasDraw): Unit

// ============================================================
// ROBOT HEAD
// ============================================================

def drawRobotHead(canvas: CanvasDraw) {

  val hx = robotX + robotHeadTurn
  val hy = robotY + robotBob + 170

  // Head glow
  canvas.fill(0, 255, 120, 25)
  canvas.noStroke()

  canvas.ellipse(
    hx,
    hy,
    100,
    75
  )

  // Neck
  canvas.fill(greenDark)
  canvas.stroke(greenMain)
  canvas.strokeWeight(2)

  canvas.rect(
    hx - 15,
    hy - 43,
    30,
    25
  )

  // Head shell
  canvas.fill(whiteRobot)
  canvas.stroke(whiteShadow)
  canvas.strokeWeight(2.5)

  canvas.rect(
    hx - 45,
    hy - 5,
    90,
    65
  )

  // Rounded-looking side panels
  canvas.fill(225, 230, 235)
  canvas.noStroke()

  canvas.ellipse(
    hx - 45,
    hy + 25,
    20,
    48
  )

  canvas.ellipse(
    hx + 45,
    hy + 25,
    20,
    48
  )

  // Face screen
  canvas.fill(blackScreen)
  canvas.stroke(20, 40, 50)
  canvas.strokeWeight(3)

  canvas.rect(
    hx - 35,
    hy + 5,
    70,
    42
  )

  // Green ear
  canvas.fill(greenMain)
  canvas.stroke(greenGlow)
  canvas.strokeWeight(2)

  canvas.ellipse(
    hx + 45,
    hy + 28,
    17,
    30
  )

  // LED eyes
  val eyeMove =
    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
  )

  // Digital mouth
  canvas.stroke(40, 180, 255)
  canvas.strokeWeight(2)

  canvas.line(
    hx - 15,
    hy + 15,
    hx + 15,
    hy + 15
  )

  // LED digital bars
  for (i <- 0 until 5) {

    canvas.line(
      hx - 25 + i * 12,
      hy + 48,
      hx - 20 + i * 12,
      hy + 48
    )
  }

  // Head highlight
  canvas.fill(255, 255, 255, 100)
  canvas.noStroke()

  canvas.ellipse(
    hx - 20,
    hy + 52,
    22,
    8
  )
} //> def drawRobotHead(canvas: builtins.CanvasDraw): Unit

// ============================================================
// COMPLETE ROBOT
// ============================================================

def drawFuturisticRobot(canvas: CanvasDraw) {

  val by = robotY + robotBob

  // Back arms first
  drawRobotArm(
    canvas,
    robotX - 48,
    by + 105,
    robotArmWave,
    false
  )

  drawRobotArm(
    canvas,
    robotX + 48,
    by + 105,
    -robotArmWave,
    true
  )

  // Legs
  val leftLegAngle =
    math.sin(robotWalk) * 15.0

  val rightLegAngle =
    -math.sin(robotWalk) * 15.0

  drawRobotLeg(
    canvas,
    robotX - 23,
    by + 10,
    leftLegAngle
  )

  drawRobotLeg(
    canvas,
    robotX + 23,
    by + 10,
    rightLegAngle
  )

  // Feet
  drawRobotFoot(
    canvas,
    robotX - 30 + math.sin(robotWalk) * 8,
    150,
    leftLegAngle
  )

  drawRobotFoot(
    canvas,
    robotX + 30 - math.sin(robotWalk) * 8,
    150,
    rightLegAngle
  )

  // Body
  drawRobotBody(canvas)

  // Head
  drawRobotHead(canvas)
} //> def drawFuturisticRobot(canvas: builtins.CanvasDraw): Unit

// ============================================================
// TITLE + HUD
// ============================================================

def drawRobotHUD(canvas: CanvasDraw) {

  canvas.fill(255, 255, 255)
  canvas.text(
    "INDIAN FUTURISTIC ROBOT",
    25,
    cheight - 30
  )

  canvas.fill(
    0,
    255,
    120
  )

  canvas.text(
    "AI SYSTEM : ONLINE",
    25,
    cheight - 55
  )

  canvas.fill(
    40,
    180,
    255
  )

  canvas.text(
    "MOTION : ACTIVE",
    25,
    cheight - 80
  )

  // Energy bar
  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 90%",
    cwidth - 180,
    cheight - 72
  )
} //> def drawRobotHUD(canvas: builtins.CanvasDraw): Unit

// ============================================================
// MAIN DRAW
// ============================================================

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)

}