Code Sketch
vedika kumbhar
Category: Programming
// ============================================================
// ? AI TV ROBOT - ULTRA ADVANCED ANIMATION
// KOJO / SCALA
// ============================================================
cleari()
originBottomLeft()
class Sketch {
// ----------------------------------------------------------
// MAIN ANIMATION VARIABLES
// ----------------------------------------------------------
var t = 0.0
var robotBob = 0.0
var robotHead = 0.0
var armWave = 0.0
var eyeBlink = 0.0
var screenGlow = 0.0
var scanLine = 0.0
var bubblePhase = 0.0
// Robot position inside TV
var robotX = cwidth / 2.0
var robotY = 185.0
// Click target
var targetX = robotX
var targetY = robotY
// Robot eye direction
var lookX = 0.0
var lookY = 0.0
// Robot state
var talking = true
var wave = false
var clicked = false
// ----------------------------------------------------------
// SMALL HELPERS
// ----------------------------------------------------------
def clamp(v: Double, lo: Double, hi: Double): Double = {
math.max(lo, math.min(hi, v))
}
def alpha(v: Double): Int = {
clamp(v, 0.0, 255.0).toInt
}
// ----------------------------------------------------------
// SETUP
// ----------------------------------------------------------
def setup(c: CanvasDraw): Unit = {
c.background(245, 245, 245)
}
// ----------------------------------------------------------
// OUTER BACKGROUND
// ----------------------------------------------------------
def drawBackground(c: CanvasDraw): Unit = {
c.background(238, 242, 246)
// soft floor
c.fill(220, 224, 230)
c.noStroke()
c.rect(0, 0, cwidth, 55)
// floor shine
c.fill(205, 210, 218, 100)
c.ellipse(
cwidth / 2.0,
48,
420,
30
)
// tiny floating AI particles
for (i <- 0 until 25) {
val px =
30.0 +
((i * 113) % (cwidth - 60))
val py =
75.0 +
((i * 71) % (cheight - 130))
val pulse =
1.0 +
math.sin(t * 2.0 + i) * 0.5
c.fill(
80,
130,
150,
70
)
c.noStroke()
c.ellipse(
px,
py,
pulse * 2,
pulse * 2
)
}
}
// ----------------------------------------------------------
// TV BODY
// ----------------------------------------------------------
def drawTV(c: CanvasDraw): Unit = {
val tvX = cwidth / 2.0
val tvY = 200.0
// TV shadow
c.fill(0, 0, 0, 35)
c.noStroke()
c.ellipse(
tvX,
68,
480,
35
)
// Main TV body
c.fill(
28,
35,
45
)
c.stroke(
5,
15,
25
)
c.strokeWeight(4)
c.rect(
tvX - 260,
tvY - 105,
520,
285
)
// outer highlight
c.noFill()
c.stroke(
75,
95,
110,
180
)
c.strokeWeight(2)
c.rect(
tvX - 250,
tvY - 95,
500,
265
)
// --------------------------------------------------------
// SCREEN
// --------------------------------------------------------
val glow =
alpha(
160.0 +
math.sin(screenGlow) * 60.0
)
c.fill(
7,
24,
34
)
c.stroke(
40,
185,
215,
glow
)
c.strokeWeight(4)
c.rect(
tvX - 225,
tvY - 70,
450,
220
)
// Screen inner area
c.fill(
10,
32,
43
)
c.noStroke()
c.rect(
tvX - 216,
tvY - 61,
432,
202
)
// --------------------------------------------------------
// SCREEN GLOW
// --------------------------------------------------------
c.fill(
0,
190,
220,
18
)
c.ellipse(
tvX,
tvY + 30,
380,
190
)
// --------------------------------------------------------
// SCAN LINES
// --------------------------------------------------------
val movingScanY =
tvY - 55 +
((scanLine % 195.0))
c.stroke(
80,
220,
255,
55
)
c.strokeWeight(1)
c.line(
tvX - 210,
movingScanY,
tvX + 210,
movingScanY
)
// static scanlines
for (i <- 0 until 18) {
val sy =
tvY - 55 + i * 11
c.stroke(
80,
220,
255,
15
)
c.line(
tvX - 210,
sy,
tvX + 210,
sy
)
}
// --------------------------------------------------------
// TV REFLECTION
// --------------------------------------------------------
c.fill(
255,
255,
255,
18
)
c.noStroke()
c.ellipse(
tvX - 145,
tvY + 100,
150,
40
)
// --------------------------------------------------------
// TV BUTTONS
// --------------------------------------------------------
c.fill(
50,
60,
70
)
c.stroke(
100,
110,
120
)
c.strokeWeight(1.5)
c.ellipse(
tvX - 38,
tvY - 87,
11,
11
)
c.ellipse(
tvX,
tvY - 87,
11,
11
)
c.ellipse(
tvX + 38,
tvY - 87,
11,
11
)
// power light
val powerGlow =
alpha(
140.0 +
math.sin(t * 4.0) * 80.0
)
c.fill(
0,
220,
255,
powerGlow
)
c.noStroke()
c.ellipse(
tvX + 205,
tvY - 87,
7,
7
)
// --------------------------------------------------------
// TV STAND
// --------------------------------------------------------
c.fill(
25,
35,
45
)
c.stroke(
10,
15,
20
)
c.strokeWeight(3)
c.rect(
tvX - 55,
45,
110,
30
)
c.rect(
tvX - 105,
32,
210,
13
)
// stand reflection
c.fill(
90,
110,
125,
80
)
c.noStroke()
c.rect(
tvX - 45,
51,
90,
5
)
}
// ----------------------------------------------------------
// ROBOT HEAD
// ----------------------------------------------------------
def drawRobotHead(c: CanvasDraw): Unit = {
val hx =
robotX + robotHead
val hy =
robotY + robotBob + 73
// head shadow
c.fill(
0,
0,
0,
50
)
c.noStroke()
c.ellipse(
hx + 3,
hy - 3,
72,
58
)
// head
c.fill(
225,
230,
235
)
c.stroke(
40,
50,
60
)
c.strokeWeight(2.5)
c.rect(
hx - 34,
hy - 28,
68,
56
)
// forehead panel
c.fill(
35,
105,
135
)
c.stroke(
90,
215,
240
)
c.strokeWeight(2)
c.ellipse(
hx,
hy + 20,
32,
9
)
// --------------------------------------------------------
// EYES
// --------------------------------------------------------
val blink =
if (math.sin(eyeBlink) > 0.985) 2.0 else 9.0
c.fill(
10,
20,
25
)
c.noStroke()
c.ellipse(
hx - 14,
hy + 3,
10,
blink
)
c.ellipse(
hx + 14,
hy + 3,
10,
blink
)
// eye cyan glow
c.fill(
65,
230,
255,
220
)
c.ellipse(
hx - 13 + lookX,
hy + 4 + lookY,
4,
4
)
c.ellipse(
hx + 15 + lookX,
hy + 4 + lookY,
4,
4
)
// mouth
c.stroke(
65,
75,
85
)
c.strokeWeight(2)
if (talking) {
val mouthOpen =
4.0 +
math.abs(math.sin(t * 7.0)) * 5.0
c.noFill()
c.ellipse(
hx,
hy - 14,
18,
mouthOpen
)
} else {
c.line(
hx - 8,
hy - 14,
hx + 8,
hy - 14
)
}
// ears
c.fill(
205,
210,
218
)
c.stroke(
55,
65,
75
)
c.strokeWeight(2)
c.ellipse(
hx - 38,
hy,
13,
22
)
c.ellipse(
hx + 38,
hy,
13,
22
)
// ear LEDs
c.fill(
0,
210,
255,
210
)
c.noStroke()
c.ellipse(
hx - 38,
hy,
5,
7
)
c.ellipse(
hx + 38,
hy,
5,
7
)
// --------------------------------------------------------
// ANTENNA
// --------------------------------------------------------
c.stroke(
75,
90,
100
)
c.strokeWeight(2)
c.line(
hx,
hy + 29,
hx,
hy + 45
)
val antGlow =
alpha(
120.0 +
math.sin(t * 5.0) * 100.0
)
c.fill(
0,
220,
255,
antGlow
)
c.noStroke()
c.ellipse(
hx,
hy + 49,
9,
9
)
}
// ----------------------------------------------------------
// ROBOT BODY
// ----------------------------------------------------------
def drawRobotBody(c: CanvasDraw): Unit = {
val bx = robotX
val by = robotY + robotBob
// torso
c.fill(
215,
220,
228
)
c.stroke(
45,
55,
65
)
c.strokeWeight(2)
c.ellipse(
bx,
by + 20,
90,
100
)
// shoulder armor
c.fill(
40,
105,
135
)
c.stroke(
80,
210,
235
)
c.strokeWeight(2)
c.ellipse(
bx - 45,
by + 43,
25,
28
)
c.ellipse(
bx + 45,
by + 43,
25,
28
)
// chest AI reactor
val reactor =
alpha(
150.0 +
math.sin(t * 3.0) * 90.0
)
c.fill(
0,
160,
215,
reactor
)
c.ellipse(
bx,
by + 28,
25,
25
)
c.fill(
210,
250,
255,
230
)
c.ellipse(
bx,
by + 28,
9,
9
)
// AI symbol
c.fill(
10,
75,
115
)
c.text(
"AI",
bx - 7,
by + 31
)
}
// ----------------------------------------------------------
// ROBOT ARMS
// ----------------------------------------------------------
def drawRobotArms(c: CanvasDraw): Unit = {
val bx = robotX
val by = robotY + robotBob
val swing =
if (wave) {
math.sin(armWave) * 15.0
} else {
math.sin(t * 1.8) * 3.0
}
// LEFT ARM
c.stroke(
225,
230,
235
)
c.strokeWeight(10)
c.line(
bx - 45,
by + 43,
bx - 64,
by + 12
)
c.fill(
35,
105,
135
)
c.stroke(
70,
205,
235
)
c.strokeWeight(2)
c.ellipse(
bx - 64,
by + 12,
17,
20
)
c.stroke(
225,
230,
235
)
c.strokeWeight(9)
c.line(
bx - 64,
by + 12,
bx - 73,
by - 18
)
// LEFT hand
c.fill(
225,
230,
235
)
c.stroke(
60,
70,
80
)
c.strokeWeight(1.5)
c.ellipse(
bx - 73,
by - 27,
16,
18
)
// RIGHT ARM
val handY =
by + 5 + swing
c.stroke(
225,
230,
235
)
c.strokeWeight(10)
c.line(
bx + 45,
by + 43,
bx + 65,
by + 15
)
c.fill(
35,
105,
135
)
c.stroke(
70,
205,
235
)
c.strokeWeight(2)
c.ellipse(
bx + 65,
by + 15,
17,
20
)
c.stroke(
225,
230,
235
)
c.strokeWeight(9)
c.line(
bx + 65,
by + 15,
bx + 74,
handY
)
// right hand
c.fill(
225,
230,
235
)
c.stroke(
60,
70,
80
)
c.strokeWeight(1.5)
c.ellipse(
bx + 74,
handY,
17,
19
)
// fingers
c.stroke(
80,
90,
100
)
c.strokeWeight(1)
for (i <- 0 until 3) {
c.line(
bx + 76,
handY - 5 + i * 4,
bx + 84,
handY - 6 + i * 4
)
}
}
// ----------------------------------------------------------
// ROBOT LOWER BODY
// ----------------------------------------------------------
def drawRobotBase(c: CanvasDraw): Unit = {
val bx = robotX
val by = robotY + robotBob
// hips
c.fill(
185,
192,
202
)
c.stroke(
55,
65,
75
)
c.strokeWeight(2)
c.ellipse(
bx - 24,
by - 28,
28,
18
)
c.ellipse(
bx + 24,
by - 28,
28,
18
)
// body lower support
c.fill(
160,
170,
182
)
c.rect(
bx - 25,
by - 58,
50,
28
)
// glowing base
c.fill(
0,
180,
240,
180
)
c.ellipse(
bx,
by - 62,
40,
9
)
}
// ----------------------------------------------------------
// AI SPEECH BUBBLE
// ----------------------------------------------------------
def drawSpeechBubble(c: CanvasDraw): Unit = {
val bx = robotX + 93
val by = robotY + 105
val pulse =
1.0 +
math.sin(bubblePhase) * 0.02
// bubble body
c.fill(
245,
250,
252,
245
)
c.stroke(
15,
110,
130
)
c.strokeWeight(2)
c.rect(
bx,
by,
180 * pulse,
83 * pulse
)
// tail
c.fill(
245,
250,
252
)
c.noStroke()
c.ellipse(
bx - 2,
by + 4,
20,
18
)
// title
c.fill(
10,
90,
110
)
c.text(
"AI IS ONLINE",
bx + 15,
by + 63
)
// animated message
c.fill(
35,
85,
105
)
c.text(
"I AM YOUR",
bx + 15,
by + 45
)
c.text(
"SMART ROBOT",
bx + 15,
by + 29
)
// typing dots
val dotPhase =
(math.sin(t * 5.0) + 1.0) * 0.5
c.fill(
0,
160,
205,
alpha(120 + dotPhase * 120)
)
c.ellipse(
bx + 140,
by + 18,
5,
5
)
c.ellipse(
bx + 151,
by + 18,
5,
5
)
c.ellipse(
bx + 162,
by + 18,
5,
5
)
}
// ----------------------------------------------------------
// AI STATUS TEXT
// ----------------------------------------------------------
def drawStatus(c: CanvasDraw): Unit = {
c.fill(
5,
70,
90
)
c.noStroke()
c.text(
"ARTIFICIAL INTELLIGENCE",
cwidth / 2.0 - 115,
20
)
c.fill(
30,
110,
130,
180
)
c.text(
"CLICK / TOUCH THE SCREEN TO TALK WITH ROBOT",
cwidth / 2.0 - 175,
cheight - 25
)
}
// ----------------------------------------------------------
// CLICK EFFECT
// ----------------------------------------------------------
def drawClickEffect(c: CanvasDraw): Unit = {
if (clicked) {
val p =
12.0 +
math.sin(t * 4.0) * 4.0
c.noFill()
c.stroke(
0,
210,
255,
130
)
c.strokeWeight(2)
c.ellipse(
targetX,
targetY,
p,
p
)
}
}
// ----------------------------------------------------------
// MAIN LOOP
// ----------------------------------------------------------
def drawLoop(c: CanvasDraw): Unit = {
// animation time
t += 0.04
screenGlow += 0.08
scanLine += 1.5
eyeBlink += 0.03
bubblePhase += 0.05
// --------------------------------------------------------
// BACKGROUND
// --------------------------------------------------------
drawBackground(c)
// --------------------------------------------------------
// TV
// --------------------------------------------------------
drawTV(c)
// --------------------------------------------------------
// CLICK / TOUCH
// --------------------------------------------------------
if (isMousePressed) {
targetX =
clamp(
mouseX.toDouble,
cwidth / 2.0 - 190.0,
cwidth / 2.0 + 190.0
)
targetY =
clamp(
mouseY.toDouble,
115.0,
315.0
)
clicked = true
wave = true
talking = true
}
// --------------------------------------------------------
// ROBOT LOOKS TOWARD TOUCH
// --------------------------------------------------------
lookX =
clamp(
(targetX - robotX) * 0.03,
-4.0,
4.0
)
lookY =
clamp(
(targetY - robotY) * 0.03,
-3.0,
3.0
)
// --------------------------------------------------------
// HEAD FOLLOW
// --------------------------------------------------------
robotHead +=
((targetX - robotX) * 0.015 -
robotHead) * 0.08
robotHead =
clamp(
robotHead,
-8.0,
8.0
)
// --------------------------------------------------------
// ROBOT BOB
// --------------------------------------------------------
robotBob =
math.sin(t * 2.0) * 2.0
// --------------------------------------------------------
// WAVE ARM
// --------------------------------------------------------
if (wave) {
armWave += 0.24
if (armWave > 12.0) {
wave = false
armWave = 0.0
}
}
// --------------------------------------------------------
// ROBOT PARTS
// --------------------------------------------------------
drawRobotBase(c)
drawRobotBody(c)
drawRobotArms(c)
drawRobotHead(c)
// --------------------------------------------------------
// SPEECH
// --------------------------------------------------------
drawSpeechBubble(c)
// --------------------------------------------------------
// EFFECTS
// --------------------------------------------------------
drawClickEffect(c)
// --------------------------------------------------------
// STATUS
// --------------------------------------------------------
drawStatus(c)
}
}
// ============================================================
// START
// ============================================================
val sketch = new Sketch
canvasSketch(sketch)