Code Sketch


AP CINEMATIC
By: Mhalsakant School
clear()
cleari()
originBottomLeft()

class Sketch {

  var t = 0.0
  var bob = 0.0
  var glow = 0.0
  var wave = 0.0
  var scan = 0.0

  def alpha(v: Double): Int =
    math.max(0, math.min(255, v.toInt))

  def setup(c: CanvasDraw): Unit = {
    c.background(5, 10, 28)
  }

  // BACKGROUND
  def drawBackground(c: CanvasDraw): Unit = {
    c.background(5, 10, 28)

    // Stars
    for (i <- 0 until 70) {
      val x = (i * 97) % cwidth
      val y = 60 + ((i * 67) % (cheight - 100))
      val pulse = 1.0 + math.sin(t * 3 + i) * 0.7

      c.noStroke()
      c.fill(70, 210, 255, 180)
      c.ellipse(x, y, pulse * 2, pulse * 2)
    }

    // Cyber floor
    c.stroke(0, 180, 255, 90)
    c.strokeWeight(1)

    for (i <- 0 until 11) {
      val y = 20 + i * 12
      c.line(0, y, cwidth, y)
    }

    for (i <- 0 until 15) {
      val x = i * (cwidth / 14.0)
      c.line(cwidth / 2.0, 20, x, 150)
    }
  }

  // ENERGY POD
  def drawEnergyPod(c: CanvasDraw): Unit = {
    val x = cwidth / 2.0
    val y = 200.0

    c.fill(10, 20, 40)
    c.stroke(0, 180, 255)
    c.strokeWeight(4)
    c.rect(x - 190, y - 120, 380, 240)

    c.fill(0, 70, 100, 80)
    c.noStroke()
    c.rect(x - 180, y - 110, 360, 220)

    // Moving laser scan
    val sy = y - 100 + (scan % 200)

    c.stroke(0, 240, 255, 160)
    c.strokeWeight(2)
    c.line(x - 175, sy, x + 175, sy)

    // Pod lights
    for (i <- 0 until 7) {
      val lx = x - 140 + i * 45

      c.noStroke()
      c.fill(0, 200, 255, alpha(100 + math.sin(t * 4 + i) * 100))
      c.ellipse(lx, y + 100, 7, 7)
      c.ellipse(lx, y - 100, 7, 7)
    }
  }

  // ROBOT HEAD
  def drawHead(c: CanvasDraw): Unit = {
    val x = cwidth / 2.0
    val y = 230.0 + bob

    // Antenna
    c.stroke(130, 200, 230)
    c.strokeWeight(4)
    c.line(x, y + 45, x, y + 70)

    c.noStroke()
    c.fill(0, 240, 255, alpha(130 + math.sin(t * 5) * 120))
    c.ellipse(x, y + 75, 13, 13)

    // Head shadow
    c.fill(0, 0, 0, 90)
    c.ellipse(x + 5, y - 5, 100, 75)

    // Head
    c.fill(175, 195, 215)
    c.stroke(40, 100, 140)
    c.strokeWeight(3)
    c.rect(x - 48, y - 35, 96, 70)

    // Face visor
    c.fill(5, 20, 40)
    c.stroke(0, 220, 255)
    c.strokeWeight(2)
    c.rect(x - 38, y - 22, 76, 43)

    // Eyes
    c.noStroke()
    c.fill(0, 240, 255, alpha(160 + math.sin(glow) * 90))
    c.ellipse(x - 19, y + 1, 15, 17)
    c.ellipse(x + 19, y + 1, 15, 17)

    // Mouth
    c.stroke(0, 220, 255)
    c.strokeWeight(3)
    c.line(x - 13, y - 15, x + 13, y - 15)

    // Side ears
    c.fill(50, 120, 160)
    c.stroke(0, 220, 255)
    c.rect(x - 57, y - 15, 9, 30)
    c.rect(x + 48, y - 15, 9, 30)
  }

  // ROBOT BODY
  def drawBody(c: CanvasDraw): Unit = {
    val x = cwidth / 2.0
    val y = 160.0 + bob

    // Neck
    c.fill(100, 130, 155)
    c.stroke(30, 80, 110)
    c.strokeWeight(2)
    c.rect(x - 18, y + 35, 36, 18)

    // Torso
    c.fill(155, 180, 200)
    c.stroke(0, 190, 240)
    c.strokeWeight(3)
    c.ellipse(x, y, 100, 95)

    // Chest core
    c.fill(0, 100, 160, 150)
    c.ellipse(x, y + 5, 47, 47)

    c.fill(0, 240, 255, alpha(140 + math.sin(glow) * 110))
    c.ellipse(x, y + 5, 29, 29)

    c.fill(240, 255, 255)
    c.ellipse(x, y + 5, 10, 10)

    // Chest label
    c.fill(10, 40, 70)
    c.noStroke()
    c.text("AI", x - 7, y - 20)
  }

  // ROBOT ARMS
  def drawArms(c: CanvasDraw): Unit = {
    val x = cwidth / 2.0
    val y = 160.0 + bob

    val swing = math.sin(wave) * 22

    // Left arm
    c.stroke(170, 195, 215)
    c.strokeWeight(13)
    c.line(x - 43, y + 28, x - 70, y - 5)

    c.fill(0, 180, 220)
    c.noStroke()
    c.ellipse(x - 70, y - 5, 20, 20)

    c.stroke(170, 195, 215)
    c.strokeWeight(10)
    c.line(x - 70, y - 5, x - 77, y - 35)

    c.fill(210, 225, 235)
    c.noStroke()
    c.ellipse(x - 77, y - 39, 17, 17)

    // Right arm
    c.stroke(170, 195, 215)
    c.strokeWeight(13)
    c.line(x + 43, y + 28, x + 70, y - 5)

    c.fill(0, 180, 220)
    c.noStroke()
    c.ellipse(x + 70, y - 5, 20, 20)

    c.stroke(170, 195, 215)
    c.strokeWeight(10)
    c.line(x + 70, y - 5, x + 78, y - 30 + swing)

    c.fill(210, 225, 235)
    c.noStroke()
    c.ellipse(x + 78, y - 35 + swing, 19, 19)

    // Fingers
    c.stroke(0, 220, 255)
    c.strokeWeight(2)

    for (i <- 0 until 3) {
      c.line(
        x + 82,
        y - 38 + swing + i * 4,
        x + 91,
        y - 40 + swing + i * 4
      )
    }
  }

  // HOLOGRAM
  def drawHologram(c: CanvasDraw): Unit = {
    val x = cwidth / 2.0 + 115
    val y = 180.0

    c.noFill()
    c.stroke(0, 200, 255, 130)
    c.strokeWeight(2)

    c.ellipse(x, y, 65, 65)
    c.ellipse(x, y, 48, 48)
    c.ellipse(x, y, 30, 30)

    c.line(x - 35, y, x + 35, y)
    c.line(x, y - 35, x, y + 35)

    c.fill(0, 240, 255)
    c.noStroke()
    c.text("SYSTEM", x - 22, y + 48)
    c.text("ONLINE", x - 22, y + 35)
  }

  // STATUS
  def drawStatus(c: CanvasDraw): Unit = {
    c.fill(0, 230, 255)
    c.noStroke()
    c.text("CYBER ROBOT // AI CORE", cwidth / 2.0 - 100, 35)

    c.fill(150, 230, 255)
    c.text("POWER: 100%", 25, cheight - 30)
    c.text("SYSTEM: ACTIVE", cwidth - 125, cheight - 30)
  }

  // MAIN ANIMATION
  def drawLoop(c: CanvasDraw): Unit = {
    t += 0.04
    glow += 0.09
    scan += 1.5
    wave += 0.12

    bob = math.sin(t * 2) * 3

    drawBackground(c)
    drawEnergyPod(c)
    drawBody(c)
    drawArms(c)
    drawHead(c)
    drawHologram(c)
    drawStatus(c)
  }
}

val sketch = new Sketch
canvasSketch(sketch)