Code Sketch


Akash bankar
By: Mhalsakant School
Category: Art
import scala.math._

cleari()
originBottomLeft()

class Sketch {

  var t = 0.0
  var bob = 0.0
  var headTilt = 0.0
  var armPhase = 0.0
  var scan = 0.0
  var blink = 0.0
  var reactor = 0.0
  var pulse = 0.0

  var robotX = cwidth / 2.0
  var robotY = 188.0

  var targetX = robotX
  var targetY = robotY

  var eyeX = 0.0
  var eyeY = 0.0

  var waving = false
  var clicked = false

  def clamp(
    v: Double,
    lo: Double,
    hi: Double
  ): Double = max(lo, min(hi, v))

  def a(v: Double): Int =
    clamp(v, 0, 255).toInt

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

  // =====================================
  // CYBERPUNK BACKGROUND
  // =====================================

  def drawBackground(c: CanvasDraw): Unit = {

    c.background(5, 10, 25)

    // Floor
    c.noStroke()
    c.fill(10, 20, 38)
    c.rect(0, 0, cwidth, 65)

    // Perspective grid
    c.stroke(0, 180, 220, 28)
    c.strokeWeight(1)

    for (i <- 0 until 18) {
      val x = i * cwidth / 17.0

      c.line(
        cwidth / 2.0,
        65,
        x,
        0
      )
    }

    for (i <- 0 until 6) {
      val y = 8.0 + i * i * 1.6

      c.line(
        0, y,
        cwidth, y
      )
    }

    // Floating digital particles
    for (i <- 0 until 65) {

      val px =
        ((i * 97.0 + sin(t + i) * 18.0)
          % cwidth)

      val py =
        75.0 +
        ((i * 53.0 + t * (8 + i % 5))
          % max(100.0, cheight - 100.0))

      val glow =
        90.0 + 90.0 * sin(t * 2 + i)

      c.noStroke()
      c.fill(0, 220, 255, a(glow))

      val size =
        1.0 + abs(sin(t + i)) * 2.0

      c.ellipse(px, py, size, size)
    }

    // Ambient energy rings
    c.noFill()
    c.stroke(0, 170, 230, 35)
    c.strokeWeight(2)

    for (i <- 0 until 4) {
      val r =
        160.0 + i * 32.0 +
        sin(t + i) * 5.0

      c.ellipse(
        cwidth / 2.0,
        200,
        r * 2,
        r * 0.7
      )
    }
  }

  // =====================================
  // FUTURISTIC TV
  // =====================================

  def drawTV(c: CanvasDraw): Unit = {

    val x = cwidth / 2.0
    val y = 205.0

    // Shadow
    c.noStroke()
    c.fill(0, 0, 0, 100)
    c.ellipse(x, 55, 510, 38)

    // Outer chassis
    c.fill(13, 22, 36)
    c.stroke(0, 180, 230, 180)
    c.strokeWeight(3)

    c.rect(
      x - 265,
      y - 110,
      530,
      300
    )

    // Inner metallic border
    c.noFill()
    c.stroke(80, 110, 140, 150)
    c.strokeWeight(2)

    c.rect(
      x - 254,
      y - 99,
      508,
      278
    )

    // Screen
    c.fill(3, 15, 29)
    c.stroke(
      0,
      210,
      255,
      a(150 + sin(t * 2) * 80)
    )
    c.strokeWeight(4)

    c.rect(
      x - 230,
      y - 75,
      460,
      230
    )

    // Screen glow
    c.noStroke()
    c.fill(0, 130, 220, 18)

    c.ellipse(
      x,
      y + 15,
      420,
      200
    )

    // Animated scanlines
    for (i <- 0 until 24) {

      val sy =
        y - 65 +
        ((i * 10.0 + scan) % 205.0)

      c.stroke(
        0,
        220,
        255,
        20
      )
      c.strokeWeight(1)

      c.line(
        x - 220, sy,
        x + 220, sy
      )
    }

    // Main scanner beam
    val beamY =
      y - 65 + (scan % 205.0)

    c.stroke(0, 255, 255, 100)
    c.strokeWeight(2)

    c.line(
      x - 218, beamY,
      x + 218, beamY
    )

    // Top indicator LEDs
    for (i <- 0 until 7) {

      val led =
        100 + 155 * abs(
          sin(t * 3 + i * 0.8)
        )

      c.noStroke()
      c.fill(
        0,
        220,
        255,
        a(led)
      )

      c.ellipse(
        x - 35 + i * 12,
        y + 171,
        4,
        4
      )
    }

    // Power indicator
    c.fill(
      0,
      255,
      180,
      a(120 + 130 * sin(t * 4))
    )

    c.ellipse(
      x + 225,
      y + 170,
      8,
      8
    )

    // Stand
    c.fill(17, 30, 44)
    c.stroke(0, 160, 210)
    c.strokeWeight(2)

    c.rect(x - 45, 43, 90, 25)
    c.rect(x - 100, 30, 200, 13)
  }

  // =====================================
  // ENERGY REACTOR
  // =====================================

  def drawReactor(
    c: CanvasDraw,
    x: Double,
    y: Double
  ): Unit = {

    val r =
      18 + 3 * sin(t * 3)

    // Outer halo
    c.noFill()
    c.stroke(0, 220, 255, 75)
    c.strokeWeight(2)

    c.ellipse(
      x, y,
      r * 3.2,
      r * 3.2
    )

    // Rotating orbital markers
    for (i <- 0 until 4) {

      val angle =
        t * 2.0 + i * Pi / 2.0

      val ox =
        x + cos(angle) * r * 1.3

      val oy =
        y + sin(angle) * r * 1.3

      c.noStroke()
      c.fill(0, 255, 255, 220)

      c.ellipse(
        ox, oy,
        5, 5
      )
    }

    // Reactor core
    c.fill(
      0,
      190,
      255,
      a(130 + 100 * sin(t * 4))
    )

    c.ellipse(
      x, y,
      r * 1.5,
      r * 1.5
    )

    c.fill(220, 255, 255, 240)
    c.ellipse(x, y, 8, 8)
  }

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

  def drawBody(c: CanvasDraw): Unit = {

    val x = robotX
    val y = robotY + bob

    // Lower body
    c.fill(90, 115, 140)
    c.stroke(170, 220, 240)
    c.strokeWeight(2)

    c.ellipse(
      x - 20, y - 30,
      28, 22
    )

    c.ellipse(
      x + 20, y - 30,
      28, 22
    )

    // Torso
    c.fill(205, 222, 235)

    c.ellipse(
      x, y + 20,
      86, 96
    )

    // Chest armor
    c.fill(25, 55, 78)
    c.stroke(0, 220, 255)
    c.strokeWeight(2)

    c.rect(
      x - 28,
      y + 4,
      56,
      43
    )

    // Reactor
    drawReactor(
      c,
      x,
      y + 27
    )

    // AI label
    c.fill(220, 255, 255)
    c.noStroke()

    c.text(
      "AI",
      x - 7,
      y + 8
    )
  }

  // =====================================
  // ANIMATED ARMS
  // =====================================

  def drawArms(c: CanvasDraw): Unit = {

    val x = robotX
    val y = robotY + bob

    val waveAngle =
      if (waving) sin(armPhase) * 22.0
      else sin(t * 2) * 4.0

    // Left arm
    c.stroke(205, 222, 235)
    c.strokeWeight(10)

    c.line(
      x - 40, y + 43,
      x - 65, y + 10
    )

    c.fill(0, 175, 220)
    c.noStroke()

    c.ellipse(
      x - 65, y + 10,
      16, 16
    )

    c.stroke(205, 222, 235)
    c.strokeWeight(8)

    c.line(
      x - 65, y + 10,
      x - 76, y - 17
    )

    c.fill(220, 235, 245)
    c.noStroke()

    c.ellipse(
      x - 76, y - 20,
      16, 17
    )

    // Right arm
    val handX =
      x + 73 + waveAngle * 0.35

    val handY =
      y + 4 + waveAngle

    c.stroke(205, 222, 235)
    c.strokeWeight(10)

    c.line(
      x + 40, y + 43,
      x + 64, y + 13
    )

    c.fill(0, 175, 220)
    c.noStroke()

    c.ellipse(
      x + 64, y + 13,
      16, 16
    )

    c.stroke(205, 222, 235)
    c.strokeWeight(8)

    c.line(
      x + 64, y + 13,
      handX, handY
    )

    c.fill(230, 240, 248)
    c.noStroke()

    c.ellipse(
      handX, handY,
      17, 18
    )

    // Finger details
    c.stroke(0, 190, 230)
    c.strokeWeight(2)

    for (i <- 0 until 3) {
      c.line(
        handX + 4,
        handY - 4 + i * 4,
        handX + 10,
        handY - 5 + i * 4
      )
    }
  }

  // =====================================
  // ROBOT HEAD + TRACKING EYES
  // =====================================

  def drawHead(c: CanvasDraw): Unit = {

    val x = robotX + headTilt
    val y = robotY + bob + 91

    // Antenna
    c.stroke(150, 180, 200)
    c.strokeWeight(3)

    c.line(
      x, y + 28,
      x, y + 45
    )

    c.noStroke()
    c.fill(
      0, 255, 255,
      a(120 + 130 * sin(t * 5))
    )

    c.ellipse(
      x, y + 48,
      10, 10
    )

    // Ears
    c.fill(90, 130, 155)

    c.ellipse(
      x - 39, y,
      13, 24
    )

    c.ellipse(
      x + 39, y,
      13, 24
    )

    // Head
    c.fill(225, 235, 242)
    c.stroke(50, 85, 110)
    c.strokeWeight(2.5)

    c.rect(
      x - 35,
      y - 28,
      70,
      57
    )

    // Face visor
    c.fill(8, 28, 45)
    c.stroke(0, 210, 255)
    c.strokeWeight(2)

    c.rect(
      x - 27,
      y - 10,
      54,
      26
    )

    // Blink
    val eyeHeight =
      if (sin(blink) > 0.985) 2.0
      else 10.0

    // Eyes
    c.noStroke()
    c.fill(0, 235, 255)

    c.ellipse(
      x - 14 + eyeX,
      y + 3 + eyeY,
      10,
      eyeHeight
    )

    c.ellipse(
      x + 14 + eyeX,
      y + 3 + eyeY,
      10,
      eyeHeight
    )

    // Eye highlights
    c.fill(230, 255, 255)

    c.ellipse(
      x - 15 + eyeX,
      y + 5 + eyeY,
      3, 3
    )

    c.ellipse(
      x + 13 + eyeX,
      y + 5 + eyeY,
      3, 3
    )

    // Animated mouth
    c.stroke(0, 225, 255)
    c.strokeWeight(2)

    val mouth =
      3 + abs(sin(t * 7)) * 7

    c.noFill()

    c.ellipse(
      x, y - 18,
      13, mouth
    )

    // Head side LEDs
    c.noStroke()

    c.fill(
      0, 255, 190,
      a(130 + 120 * sin(t * 4))
    )

    c.ellipse(
      x - 34, y + 2,
      4, 8
    )

    c.ellipse(
      x + 34, y + 2,
      4, 8
    )
  }

  // =====================================
  // HOLOGRAPHIC HUD
  // =====================================

  def drawHUD(c: CanvasDraw): Unit = {

    val x = cwidth / 2.0
    val y = 190.0

    // Corner brackets
    c.stroke(0, 210, 255, 160)
    c.strokeWeight(2)
    c.noFill()

    val corners = Array(
      (-215.0, 95.0),
      (215.0, 95.0),
      (-215.0, -70.0),
      (215.0, -70.0)
    )

    for ((dx, dy) <- corners) {

      val sx =
        if (dx < 0) 1.0 else -1.0

      val sy =
        if (dy < 0) 1.0 else -1.0

      c.line(
        x + dx, y + dy,
        x + dx + sx * 17, y + dy
      )

      c.line(
        x + dx, y + dy,
        x + dx, y + dy + sy * 17
      )
    }

    // Audio waveform
    for (i <- 0 until 38) {

      val xx =
        x - 100 + i * 5.4

      val h =
        3 + abs(
          sin(t * 5 + i * 0.45)
        ) * 13

      c.stroke(
        0, 225, 255,
        a(100 + h * 8)
      )

      c.strokeWeight(2)

      c.line(
        xx, 105 - h / 2,
        xx, 105 + h / 2
      )
    }

    // Status text
    c.noStroke()
    c.fill(100, 240, 255)

    c.text(
      "AI CORE // ONLINE",
      x - 205,
      302
    )

    c.fill(255, 80, 180)

    c.text(
      "SYSTEM ACTIVE",
      x + 115,
      302
    )
  }

  // =====================================
  // SPEECH PANEL
  // =====================================

  def drawSpeech(c: CanvasDraw): Unit = {

    val x = cwidth / 2.0 + 105
    val y = 220.0

    c.fill(5, 25, 42, 235)
    c.stroke(0, 200, 240, 190)
    c.strokeWeight(2)

    c.rect(
      x, y,
      125, 67
    )

    c.noStroke()
    c.fill(0, 255, 220)

    c.text(
      "AI ASSISTANT",
      x + 10,
      y + 49
    )

    c.fill(230, 245, 255)

    c.text(
      "HELLO HUMAN",
      x + 10,
      y + 31
    )

    c.fill(0, 210, 255)

    for (i <- 0 until 3) {

      val radius =
        3 + abs(sin(t * 5 + i)) * 2

      c.ellipse(
        x + 15 + i * 13,
        y + 14,
        radius,
        radius
      )
    }
  }

  // =====================================
  // CLICK RIPPLE
  // =====================================

  def drawRipple(c: CanvasDraw): Unit = {

    if (clicked) {

      val radius =
        10 + (t * 20) % 70

      c.noFill()
      c.stroke(
        0, 235, 255,
        a(180 - radius * 2)
      )

      c.strokeWeight(2)

      c.ellipse(
        targetX,
        targetY,
        radius * 2,
        radius * 2
      )
    }
  }

  // =====================================
  // MAIN ANIMATION LOOP
  // =====================================

  def drawLoop(c: CanvasDraw): Unit = {

    t += 0.035
    scan += 1.4
    blink += 0.035
    reactor += 0.08
    pulse += 0.05

    // Background
    drawBackground(c)

    // TV
    drawTV(c)

    // Pointer interaction
    if (isMousePressed) {

      targetX = clamp(
        mouseX.toDouble,
        cwidth / 2.0 - 190,
        cwidth / 2.0 + 190
      )

      targetY = clamp(
        mouseY.toDouble,
        110,
        310
      )

      waving = true
      clicked = true
    }

    // Smooth eye tracking
    eyeX += (
      clamp(
        (targetX - robotX) * 0.035,
        -5, 5
      ) - eyeX
    ) * 0.12

    eyeY += (
      clamp(
        (targetY - robotY) * 0.025,
        -3, 3
      ) - eyeY
    ) * 0.12

    // Smooth head movement
    headTilt += (
      clamp(
        (targetX - robotX) * 0.018,
        -10, 10
      ) - headTilt
    ) * 0.06

    // Floating animation
    bob = sin(t * 2) * 2.5

    // Wave animation
    if (waving) {

      armPhase += 0.25

      if (armPhase > 12) {
        waving = false
        armPhase = 0
      }
    }

    // Robot layers
    drawBody(c)
    drawArms(c)
    drawHead(c)

    // HUD overlays
    drawHUD(c)
    drawSpeech(c)
    drawRipple(c)
  }
}

val sketch = new Sketch
canvasSketch(sketch)