Code Sketch
nag [alok]
Category: Art
import scala.collection.mutable.ArrayBuffer
cleari()
originBottomLeft()
// ============================================================
// NAG PANCHAMI - GROWING SNAKE GAME V14.0
// ============================================================
var globalTime = 0.0
var waveAngle = 0.0
var currentStoryStage = 0 // 0: Welcome, 1: Mandir/Sheti Darshan, 2: Snake Game Play
// Game Variables & Snake Body Segments (ArrayBuffer of (x, y) coordinates)
var snakeX = cwidth / 2.0
var snakeY = cheight / 2.0
var snakeDir = "RIGHT"
var score = 0
var snakeLength = 3 // Initial segments
val snakeSegments = ArrayBuffer.empty[(Double, Double)]
var flowerX = randomDouble(100, cwidth - 100)
var flowerY = randomDouble(100, cheight - 100)
// Nag Panchami Theme Tunes
val nagPanchamiTune = ArrayBuffer((60,300),(62,300),(65,400),(65,300),(67,400),(65,300),(62,300),(60,500),(65,300),(67,400),(69,500),(67,400),(65,400),(62,400),(60,600))
var nagIndex = 0
var nagTuneFinished = false
var audioEnabled = false
try {
setNoteInstrument(Instrument.FLUTE)
audioEnabled = true
} catch {
case _: Exception => audioEnabled = false
}
def playSoundFx(note: Int, duration: Int): Unit = {
if (audioEnabled) {
try { playNote(note, duration) } catch { case _: Exception => }
}
}
// Festival Sparkles
case class FestivalParticle(var x: Double, var y: Double, var vx: Double, var vy: Double, var life: java.awt.Color, var size: Double)
val festivalParticles = ArrayBuffer.empty[FestivalParticle]
def spawnFestivalParticles(x: Double, y: Double, count: Int): Unit = {
var i = 0
while (i < count && festivalParticles.length < 300) {
val col = if (randomBoolean) Color(255, 255, 0) else Color(255, 140, 0)
festivalParticles.append(FestivalParticle(x, y, randomDouble(-3.0, 3.0), randomDouble(1.0, 4.0), col, randomDouble(3.0, 7.0)))
i += 1
}
}
// Main Animation & Render Loop
animateWithState(0.0) { angle =>
erasePictures()
globalTime += 0.03
waveAngle += 0.05
// Update particles
festivalParticles.filterInPlace(_.life.getAlpha > 0.0)
festivalParticles.foreach { p =>
p.x += p.vx
p.y += p.vy
}
// Play festival tune
if (!nagTuneFinished && audioEnabled) {
if (nagIndex < nagPanchamiTune.length) {
val (n, d) = nagPanchamiTune(nagIndex)
playSoundFx(n, d)
nagIndex += 1
} else {
nagTuneFinished = true
}
}
// Set Background (Sky)
setBackground(Color(20, 35, 60))
if (currentStoryStage == 0) {
// --- WELCOME SCREEN ---
val titlePic = Picture.text("NAG PANCHAMI & SHREE KSHETRA UTSAV", 26)
titlePic.setPenColor(Color(255, 215, 0))
titlePic.setPosition(cwidth / 2.0 - 200, cheight - 100)
draw(titlePic)
val subPic = Picture.text("Worship Nag Devta in Sacred Fields & Play Festival Snake Game!", 14)
subPic.setPenColor(Color(200, 230, 255))
subPic.setPosition(cwidth / 2.0 - 210, cheight - 140)
draw(subPic)
var i = 0
while (i < 12) {
val px = cwidth / 2.0 - 150 + (i * 25.0)
val py = cheight / 2.0 + math.sin(waveAngle + (i * 0.5)) * 40.0
val bodyPart = Picture.circle(10.0)
bodyPart.setFillColor(Color(34, 139, 34))
bodyPart.setPenColor(Color(255, 215, 0))
bodyPart.setPosition(px, py)
draw(bodyPart)
i += 1
}
val promptPic = Picture.text("Click anywhere or press Enter to Start Mandir & Snake Game", 14)
promptPic.setPenColor(Color(255, 180, 50))
promptPic.setPosition(cwidth / 2.0 - 220, 60)
draw(promptPic)
} else if (currentStoryStage == 1) {
// --- MANDIR & SHETI SCENE ---
val fieldBase = Picture.rect(cwidth, 120)
fieldBase.setFillColor(Color(45, 100, 45))
fieldBase.setPenColor(Color(60, 140, 60))
fieldBase.setPosition(0, 0)
draw(fieldBase)
var f = 0
while (f < cwidth) {
val cropLine = Picture.line(0, 20)
cropLine.setPenColor(Color(100, 200, 80))
cropLine.setPenThickness(2.0)
cropLine.setPosition(f, 20)
draw(cropLine)
f += 40
}
val mandirWall = Picture.rect(160, 100)
mandirWall.setFillColor(Color(180, 180, 190))
mandirWall.setPenColor(Color(220, 220, 230))
mandirWall.setPosition(cwidth / 2.0 - 80, 60)
draw(mandirWall)
val shikhar = Picture.rect(100, 70)
shikhar.setFillColor(Color(210, 180, 140))
shikhar.setPenColor(Color(255, 215, 0))
shikhar.setPosition(cwidth / 2.0 - 50, 160)
draw(shikhar)
val flag = Picture.line(0, 25)
flag.setPenColor(Color(255, 69, 0))
flag.setPenThickness(3.0)
flag.setPosition(cwidth / 2.0, 230)
draw(flag)
val templeHeading = Picture.text("=== SHRI KSHETRA MANDIR & NAG DEVTA ===", 18)
templeHeading.setPenColor(Color(255, 220, 100))
templeHeading.setPosition(cwidth / 2.0 - 180, cheight - 50)
draw(templeHeading)
val blessingText = Picture.text("Press Enter or Click to Play Festival Snake Game!", 16)
blessingText.setPenColor(Color(255, 255, 100))
blessingText.setPosition(cwidth / 2.0 - 180, cheight - 90)
draw(blessingText)
} else {
// --- STAGE 2: FESTIVAL GROWING SNAKE GAME PLAY SCENE ---
// Update snake movement based on direction
if (snakeDir == "RIGHT") snakeX += 3.5
if (snakeDir == "LEFT") snakeX -= 3.5
if (snakeDir == "UP") snakeY += 3.5
if (snakeDir == "DOWN") snakeY -= 3.5
// Screen wrapping / boundaries
if (snakeX > cwidth) snakeX = 0.0
if (snakeX < 0) snakeX = cwidth
if (snakeY > cheight) snakeY = 0.0
if (snakeY < 0) snakeY = cheight
// Maintain snake segments (growth mechanism)
snakeSegments.prepend((snakeX, snakeY))
if (snakeSegments.length > snakeLength) {
snakeSegments.remove(snakeSegments.length - 1)
}
// Check collision with flower (food)
val dist = math.hypot(snakeX - flowerX, snakeY - flowerY)
if (dist < 22.0) {
score += 1
snakeLength += 5 // Increase snake body length as points are collected!
flowerX = randomDouble(50, cwidth - 50)
flowerY = randomDouble(50, cheight - 50)
spawnFestivalParticles(snakeX, snakeY, 20)
}
// Draw Flower / Offering
val flowerPic = Picture.circle(9.0)
flowerPic.setFillColor(Color(255, 105, 180))
flowerPic.setPenColor(Color(255, 255, 255))
flowerPic.setPosition(flowerX, flowerY)
draw(flowerPic)
// Draw Growing Snake Body Segments
snakeSegments.foreach { case (sx, sy) =>
val bodyPart = Picture.circle(12.0)
bodyPart.setFillColor(Color(34, 139, 34))
bodyPart.setPenColor(Color(255, 215, 0))
bodyPart.setPosition(sx, sy)
draw(bodyPart)
}
// Draw Snake Head (Nag Devta Head)
val snakeHead = Picture.circle(15.0)
snakeHead.setFillColor(Color(46, 139, 87))
snakeHead.setPenColor(Color(255, 215, 0))
snakeHead.setPosition(snakeX, snakeY)
draw(snakeHead)
// Draw Score & Instructions
val scorePic = Picture.text(s"Nag Score (Flowers Collected): $score | Snake Size: $snakeLength", 16)
scorePic.setPenColor(Color(255, 220, 100))
scorePic.setPosition(50, cheight - 50)
draw(scorePic)
val controlHint = Picture.text("Use D (Right), A (Left), W (Up), S (Down) to Grow Snake!", 14)
controlHint.setPenColor(Color(200, 230, 255))
controlHint.setPosition(50, cheight - 80)
draw(controlHint)
}
angle + 1.0
}
// Mouse click handler to advance stages
onMouseClick { (x, y) =>
if (currentStoryStage == 0) {
currentStoryStage = 1
} else if (currentStoryStage == 1) {
currentStoryStage = 2
snakeSegments.clear()
snakeSegments.append((snakeX, snakeY))
spawnFestivalParticles(cwidth / 2.0, cheight / 2.0, 30)
}
}
// Keyboard Controls for both Stage Transition & Snake Movement
onKeyPress { k =>
if (currentStoryStage < 2) {
if (k == '\n' || k == '\r') {
if (currentStoryStage == 0) {
currentStoryStage = 1
} else if (currentStoryStage == 1) {
currentStoryStage = 2
snakeSegments.clear()
snakeSegments.append((snakeX, snakeY))
spawnFestivalParticles(cwidth / 2.0, cheight / 2.0, 30)
}
}
} else {
// Snake Direction Controls using D, A, W, S
if (k == 'd' || k == 'D') snakeDir = "RIGHT"
else if (k == 'a' || k == 'A') snakeDir = "LEFT"
else if (k == 'w' || k == 'W') snakeDir = "UP"
else if (k == 's' || k == 'S') snakeDir = "DOWN"
}
}
println("=== NAG PANCHAMI GROWING SNAKE GAME LOADED SUCCESSFULLY ===")