Code Sketch
bhavesh
Category: Programming
// ============================================================
// BIXUU GAMING
// JUNGLE OF AMIGO
// AVATAR + AI ROBOT + 20 ENERGY DRONES
// FICTIONAL ARCADE GAME
// ============================================================
cleari()
originBottomLeft()
// ============================================================
// GAME STATES
// ============================================================
var screen = 0
// 0 = avatar selection
// 1 = robot briefing
// 2 = mission
// 3 = complete
var selectedAvatar = 0
var score = 0
var destroyed = 0
var launcherX = cwidth / 2.0
var launcherY = 100.0
var launcherAngle = math.Pi / 2.0
var messageTimer = 0
// ============================================================
// AVATAR DATA
// ============================================================
val avatarNames = Array(
"STONE AI",
"FIRE AI",
"WATER AI",
"AIR AI",
"SMART CRYSTAL AI"
)
val avatarR = Array(
130, 255, 40, 180, 220
)
val avatarG = Array(
130, 80, 150, 230, 80
)
val avatarB = Array(
140, 20, 255, 255, 255
)
// ============================================================
// DRONE
// ============================================================
class EnergyDrone(
var x: Double,
var y: Double,
val id: Int
) {
var active = true
var pulse = randomDouble(6.28)
var direction = 1.0
def step() {
pulse += 0.06
x += math.sin(pulse) * 0.8 * direction
if (x < 70) {
direction = 1.0
}
if (x > cwidth - 70) {
direction = -1.0
}
}
def view(canvas: CanvasDraw) {
if (active) {
// Drone glow
canvas.noStroke()
canvas.fill(
255,
80,
80,
35
)
canvas.ellipse(
x,
y,
60,
60
)
// Drone body
canvas.fill(
55,
65,
80
)
canvas.stroke(
180,
190,
210
)
canvas.strokeWeight(2)
canvas.ellipse(
x,
y,
34,
34
)
// Drone core
canvas.noStroke()
canvas.fill(
255,
80,
80
)
canvas.ellipse(
x,
y,
12,
12
)
// Drone arms
canvas.stroke(
130,
140,
160
)
canvas.strokeWeight(4)
canvas.line(
x - 22,
y + 18,
x + 22,
y - 18
)
canvas.line(
x - 22,
y - 18,
x + 22,
y + 18
)
// ID
canvas.noStroke()
canvas.fill(
255,
255,
255
)
canvas.text(
"D" + id.toString,
x - 8,
y + 32
)
}
}
}
val drones =
ArrayBuffer.empty[EnergyDrone]
// ============================================================
// CREATE 20 DRONES
// ============================================================
for (i <- 0 until 20) {
val row = i / 5
val column = i % 5
drones.append(
new EnergyDrone(
100.0 + column * 120.0,
cheight - 180.0 - row * 75.0,
i + 1
)
)
}
// ============================================================
// ENERGY PULSE
// ============================================================
class EnergyPulse(
var x: Double,
var y: Double,
val angle: Double,
val r: Int,
val g: Int,
val b: Int
) {
var active = true
val trail =
ArrayBuffer.empty[Vector2D]
def step() {
val speed = 9.0
x += math.cos(angle) * speed
y += math.sin(angle) * speed
trail.append(
Vector2D(x, y)
)
if (trail.length > 12) {
trail.remove(0)
}
if (
x < -50 ||
x > cwidth + 50 ||
y < -50 ||
y > cheight + 50
) {
active = false
}
}
def view(canvas: CanvasDraw) {
canvas.noStroke()
for (i <- 0 until trail.length) {
val a =
((i.toDouble / trail.length) * 180).toInt
canvas.fill(
r,
g,
b,
a
)
canvas.ellipse(
trail(i).x,
trail(i).y,
7,
7
)
}
canvas.fill(
255,
255,
255
)
canvas.ellipse(
x,
y,
18,
18
)
canvas.fill(
r,
g,
b
)
canvas.ellipse(
x,
y,
10,
10
)
}
}
val pulses =
ArrayBuffer.empty[EnergyPulse]
// ============================================================
// PARTICLES
// ============================================================
class Particle(
var x: Double,
var y: Double,
val r: Int,
val g: Int,
val b: Int
) {
var life = 35
def step() {
y += 1.5
life -= 1
}
def view(canvas: CanvasDraw) {
if (life > 0) {
canvas.noStroke()
canvas.fill(
r,
g,
b,
life * 6
)
canvas.ellipse(
x,
y,
8,
8
)
}
}
}
val particles =
ArrayBuffer.empty[Particle]
// ============================================================
// STARS
// ============================================================
class Star(
val x: Double,
val y: Double,
val size: Double
) {
var phase =
randomDouble(6.28)
def step() {
phase += 0.04
}
def view(canvas: CanvasDraw) {
val brightness =
130 +
(math.sin(phase) * 80).toInt
canvas.noStroke()
canvas.fill(
brightness,
brightness,
255,
200
)
canvas.ellipse(
x,
y,
size,
size
)
}
}
val stars =
ArrayBuffer.empty[Star]
for (i <- 0 until 80) {
stars.append(
new Star(
randomDouble(cwidth),
randomDouble(cheight),
1.0 + randomDouble(3.0)
)
)
}
// ============================================================
// AVATAR ROBOT
// ============================================================
def drawAvatarRobot(
canvas: CanvasDraw,
x: Double,
y: Double,
avatar: Int,
scale: Double
) {
val r = avatarR(avatar)
val g = avatarG(avatar)
val b = avatarB(avatar)
// Glow
canvas.noStroke()
canvas.fill(
r,
g,
b,
35
)
canvas.ellipse(
x,
y,
120 * scale,
120 * scale
)
// Body
canvas.fill(
45,
50,
65
)
canvas.stroke(
r,
g,
b
)
canvas.strokeWeight(3)
canvas.rect(
x - 32 * scale,
y - 42 * scale,
64 * scale,
70 * scale
)
// Head
canvas.fill(
65,
70,
90
)
canvas.ellipse(
x,
y + 45 * scale,
70 * scale,
55 * scale
)
// Eyes
canvas.noStroke()
canvas.fill(
r,
g,
b
)
canvas.ellipse(
x - 15 * scale,
y + 47 * scale,
10 * scale,
14 * scale
)
canvas.ellipse(
x + 15 * scale,
y + 47 * scale,
10 * scale,
14 * scale
)
// Core
canvas.fill(
255,
255,
255
)
canvas.ellipse(
x,
y - 8 * scale,
15 * scale,
15 * scale
)
canvas.fill(
r,
g,
b
)
canvas.ellipse(
x,
y - 8 * scale,
8 * scale,
8 * scale
)
// Arms
canvas.stroke(
r,
g,
b
)
canvas.strokeWeight(
8 * scale
)
canvas.line(
x - 32 * scale,
y + 5 * scale,
x - 55 * scale,
y - 25 * scale
)
canvas.line(
x + 32 * scale,
y + 5 * scale,
x + 55 * scale,
y - 25 * scale
)
}
// ============================================================
// JUNGLE BACKGROUND
// ============================================================
def drawJungle(
canvas: CanvasDraw
) {
// Ground
canvas.fill(
20,
90,
45
)
canvas.noStroke()
canvas.rect(
0,
0,
cwidth,
100
)
// Trees
for (i <- 0 until 8) {
val tx =
30.0 + i * 100.0
canvas.fill(
90,
55,
25
)
canvas.rect(
tx,
80,
22,
160
)
canvas.fill(
20,
150,
55
)
canvas.ellipse(
tx + 10,
240,
100,
100
)
}
}
// ============================================================
// LAUNCHER
// ============================================================
def drawLauncher(
canvas: CanvasDraw
) {
canvas.fill(
30,
35,
50
)
canvas.stroke(
150,
170,
190
)
canvas.strokeWeight(2)
canvas.ellipse(
launcherX,
launcherY,
80,
80
)
canvas.pushMatrix()
canvas.translate(
launcherX,
launcherY
)
canvas.rotate(
launcherAngle
)
canvas.fill(
55,
65,
90
)
canvas.rect(
-15,
-18,
75,
36
)
canvas.fill(
avatarR(selectedAvatar),
avatarG(selectedAvatar),
avatarB(selectedAvatar)
)
canvas.ellipse(
52,
0,
26,
26
)
canvas.fill(
255,
255,
255
)
canvas.ellipse(
52,
0,
9,
9
)
canvas.popMatrix()
}
// ============================================================
// CONTROL BUTTON
// ============================================================
def button(
canvas: CanvasDraw,
x: Double,
label: String,
r: Int,
g: Int,
b: Int
) {
canvas.fill(
r,
g,
b,
230
)
canvas.stroke(
220,
220,
230
)
canvas.strokeWeight(2)
canvas.rect(
x,
15,
70,
40
)
canvas.fill(
255,
255,
255
)
canvas.text(
label,
x + 12,
30
)
}
// ============================================================
// MISSION CONTROLS
// ============================================================
def drawMissionControls(
canvas: CanvasDraw
) {
canvas.fill(
8,
12,
25,
235
)
canvas.noStroke()
canvas.rect(
5,
5,
cwidth - 10,
70
)
button(
canvas,
15,
"<-",
40,
80,
130
)
button(
canvas,
95,
"->",
40,
80,
130
)
button(
canvas,
175,
"UP",
50,
80,
150
)
button(
canvas,
255,
"DOWN",
50,
80,
150
)
button(
canvas,
335,
"ROT-L",
130,
50,
150
)
button(
canvas,
415,
"ROT-R",
130,
50,
150
)
button(
canvas,
495,
"ENERGY",
180,
0,
170
)
}
// ============================================================
// AVATAR SELECTION
// ============================================================
def drawAvatarSelection(
canvas: CanvasDraw
) {
canvas.background(
5,
8,
20
)
repeatFor(stars) { s =>
s.view(canvas)
}
canvas.fill(
0,
220,
255
)
canvas.text(
"SELECT YOUR AVATAR",
cwidth / 2.0 - 130,
cheight - 55
)
val startX = 90.0
for (i <- 0 until 5) {
val x =
startX + i * 120.0
val y =
cheight / 2.0
drawAvatarRobot(
canvas,
x,
y,
i,
0.75
)
canvas.fill(
255,
255,
255
)
canvas.text(
avatarNames(i),
x - 50,
y - 80
)
canvas.stroke(
avatarR(i),
avatarG(i),
avatarB(i)
)
canvas.strokeWeight(2)
canvas.noFill()
canvas.rect(
x - 55,
y - 110,
110,
150
)
}
canvas.fill(
255,
255,
255
)
canvas.text(
"STONE ? FIRE ? WATER ? AIR ? SMART CRYSTAL",
cwidth / 2.0 - 210,
80
)
}
// ============================================================
// ROBOT BRIEFING
// ============================================================
def drawBriefing(
canvas: CanvasDraw
) {
canvas.background(
5,
8,
20
)
repeatFor(stars) { s =>
s.view(canvas)
}
drawAvatarRobot(
canvas,
110,
cheight / 2.0,
selectedAvatar,
1.15
)
canvas.fill(
8,
15,
30,
235
)
canvas.stroke(
avatarR(selectedAvatar),
avatarG(selectedAvatar),
avatarB(selectedAvatar)
)
canvas.strokeWeight(3)
canvas.rect(
210,
125,
cwidth - 245,
300
)
canvas.fill(
avatarR(selectedAvatar),
avatarG(selectedAvatar),
avatarB(selectedAvatar)
)
canvas.text(
"BIXUU AI ROBOT",
240,
390
)
canvas.fill(
255,
255,
255
)
canvas.text(
"WELCOME! YOUR MISSION STARTS NOW.",
240,
350
)
canvas.text(
"We received a letter from",
240,
320
)
canvas.text(
"JUNGLE OF AMIGO.",
240,
290
)
canvas.text(
"The jungle animals need your help.",
240,
255
)
canvas.text(
"Protect the animals from the",
240,
225
)
canvas.text(
"fictional energy drones.",
240,
195
)
canvas.fill(
0,
220,
255
)
canvas.text(
"CLICK START MISSION",
280,
150
)
}
// ============================================================
// COMPLETE SCREEN
// ============================================================
def drawComplete(
canvas: CanvasDraw
) {
canvas.background(
5,
8,
20
)
repeatFor(stars) { s =>
s.view(canvas)
}
canvas.fill(
0,
220,
255
)
canvas.text(
"BIXUU GAMING",
cwidth / 2.0 - 100,
cheight - 60
)
canvas.fill(
255,
255,
255
)
canvas.text(
"MISSION COMPLETE!",
cwidth / 2.0 - 120,
cheight / 2.0 + 90
)
canvas.fill(
255,
220,
0
)
canvas.text(
"VEER AWARD",
cwidth / 2.0 - 80,
cheight / 2.0 + 45
)
canvas.fill(
255,
255,
255
)
canvas.text(
"20 / 20 DRONES CLEARED",
cwidth / 2.0 - 110,
cheight / 2.0
)
canvas.text(
"SCORE: " + score.toString,
cwidth / 2.0 - 55,
cheight / 2.0 - 40
)
canvas.fill(
0,
220,
120
)
canvas.text(
"THANK YOU FOR PLAYING BIXUU GAMING!",
cwidth / 2.0 - 170,
cheight / 2.0 - 100
)
canvas.fill(
0,
255,
120
)
canvas.text(
"SAVE ANIMALS",
cwidth / 2.0 - 65,
110
)
canvas.text(
"SAVE NATURE",
cwidth / 2.0 - 60,
80
)
canvas.text(
"SAVE CULTURE",
cwidth / 2.0 - 65,
50
)
}
// ============================================================
// UPDATE
// ============================================================
def updateGame() {
repeatFor(stars) { s =>
s.step()
}
if (screen == 2) {
repeatFor(drones) { d =>
if (d.active) {
d.step()
}
}
pulses.filterInPlace(
_.active
)
repeatFor(pulses) { p =>
p.step()
}
particles.filterInPlace(
_.life > 0
)
repeatFor(particles) { p =>
p.step()
}
// Drone collision
repeatFor(pulses) { p =>
if (p.active) {
repeatFor(drones) { d =>
if (
d.active &&
math.abs(p.x - d.x) < 30 &&
math.abs(p.y - d.y) < 30
) {
d.active = false
p.active = false
destroyed += 1
score += 50
// Energy particles
for (k <- 0 until 15) {
particles.append(
new Particle(
d.x,
d.y,
avatarR(selectedAvatar),
avatarG(selectedAvatar),
avatarB(selectedAvatar)
)
)
}
if (destroyed >= 20) {
screen = 3
}
}
}
}
}
}
}
// ============================================================
// MOUSE CONTROL
// ============================================================
def handleClick(
x: Double,
y: Double
) {
// ========================================================
// AVATAR SELECTION
// ========================================================
if (screen == 0) {
for (i <- 0 until 5) {
val left =
35.0 + i * 120.0
val right =
left + 110.0
if (
x >= left &&
x <= right &&
y >= 100 &&
y <= 420
) {
selectedAvatar = i
screen = 1
}
}
}
// ========================================================
// BRIEFING
// ========================================================
else if (screen == 1) {
if (
x > 230 &&
y > 120 &&
y < 190
) {
screen = 2
}
}
// ========================================================
// MISSION
// ========================================================
else if (screen == 2) {
// LEFT
if (
x >= 15 &&
x <= 85 &&
y >= 15 &&
y <= 55
) {
launcherX -= 8
}
// RIGHT
else if (
x >= 95 &&
x <= 165 &&
y >= 15 &&
y <= 55
) {
launcherX += 8
}
// UP
else if (
x >= 175 &&
x <= 245 &&
y >= 15 &&
y <= 55
) {
launcherY += 8
}
// DOWN
else if (
x >= 255 &&
x <= 325 &&
y >= 15 &&
y <= 55
) {
launcherY -= 8
}
// ROTATE LEFT
else if (
x >= 335 &&
x <= 405 &&
y >= 15 &&
y <= 55
) {
launcherAngle -= 0.15
}
// ROTATE RIGHT
else if (
x >= 415 &&
x <= 485 &&
y >= 15 &&
y <= 55
) {
launcherAngle += 0.15
}
// ENERGY
else if (
x >= 495 &&
x <= 565 &&
y >= 15 &&
y <= 55
) {
val px =
launcherX +
math.cos(launcherAngle) * 65.0
val py =
launcherY +
math.sin(launcherAngle) * 65.0
pulses.append(
new EnergyPulse(
px,
py,
launcherAngle,
avatarR(selectedAvatar),
avatarG(selectedAvatar),
avatarB(selectedAvatar)
)
)
}
}
}
// ============================================================
// VIEW
// ============================================================
def viewGame(
canvas: CanvasDraw
) {
if (screen == 0) {
drawAvatarSelection(canvas)
}
else if (screen == 1) {
drawBriefing(canvas)
}
else if (screen == 2) {
canvas.background(
8,
30,
20
)
drawJungle(canvas)
repeatFor(stars) { s =>
s.view(canvas)
}
repeatFor(drones) { d =>
d.view(canvas)
}
repeatFor(particles) { p =>
p.view(canvas)
}
repeatFor(pulses) { p =>
p.view(canvas)
}
drawLauncher(canvas)
drawMissionControls(canvas)
canvas.fill(
255,
255,
255
)
canvas.text(
"JUNGLE OF AMIGO",
20,
cheight - 35
)
canvas.fill(
255,
220,
0
)
canvas.text(
"DRONES: " +
destroyed.toString +
" / 20",
cwidth - 130,
cheight - 35
)
}
else if (screen == 3) {
drawComplete(canvas)
}
}
// ============================================================
// CLICK EVENT
// ============================================================
onMouseClick { (x, y) =>
handleClick(
x,
y
)
}
// ============================================================
// MAIN LOOP
// ============================================================
animateWithCanvasDraw { canvas =>
updateGame()
viewGame(canvas)
}