Code Sketch
bixuu
Category: Programming
import java.awt.{AlphaComposite, BasicStroke, Color, Cursor, Dimension, Font, Graphics, Graphics2D, GradientPaint, Polygon, RenderingHints}
import java.awt.event.{ActionEvent, ActionListener, KeyAdapter, KeyEvent, MouseAdapter, MouseEvent}
import java.awt.geom.{Ellipse2D, RoundRectangle2D}
import java.util.Random
import javax.swing.{JFrame, JPanel, SwingUtilities, Timer, WindowConstants}
import scala.collection.mutable
import scala.collection.mutable.ArrayBuffer
// ================================================================
// SPRING SEASON: CYBER BLOOM - GLITCH IN THE GARDEN
// Original, self-contained Scala + Java Swing animated mini-game.
// No external images, libraries, game engine or network are required.
// Controls: WASD / arrows = move, E = interact, SPACE = dash,
// F = glow mode, M = mini-map, ESC = pause, R = restart.
// ================================================================
object SpringSeasonCyberBloomGlitch {
val APP_TITLE = "SPRING SEASON: CYBER BLOOM - GLITCH IN THE GARDEN"
val WORLD_W = 1900
val WORLD_H = 1320
val START_W = 1180
val START_H = 760
val GOAL_COUNT = 6
final class Bloom(val x: Double, val y: Double, val hue: Int, val label: String) {
var collected = false
}
final class GardenFlower(val x: Double, val y: Double, val size: Double, val hue: Int, val phase: Double, val glitch: Boolean)
final class GardenTree(val x: Double, val y: Double, val size: Double, val hue: Int)
final class Particle(var x: Double, var y: Double, var vx: Double, var vy: Double, val size: Double, val hue: Int, var life: Double)
val keys = mutable.Set[Int]()
val blooms = ArrayBuffer[Bloom]()
val gardenFlowers = ArrayBuffer[GardenFlower]()
val trees = ArrayBuffer[GardenTree]()
val particles = ArrayBuffer[Particle]()
val random = new Random(2782013L)
val BG_TOP = new Color(7, 13, 31)
val BG_BOTTOM = new Color(18, 57, 62)
val DEEP = new Color(13, 27, 43)
val CYAN = new Color(70, 244, 231)
val MINT = new Color(139, 255, 187)
val PINK = new Color(255, 91, 194)
val PURPLE = new Color(162, 103, 255)
val GOLD = new Color(255, 222, 123)
val WHITE = new Color(238, 250, 255)
val MUTED = new Color(166, 197, 209)
var playerX = 900.0
var playerY = 1050.0
var facingX = 0.0
var facingY = -1.0
var cameraX = 0.0
var cameraY = 0.0
var frames = 0L
var secondsPlayed = 0.0
var remainingSeconds = 360.0
var started = false
var paused = false
var won = false
var lost = false
var glowMode = true
var showMap = true
var dashTime = 0.0
var dashCooldown = 0.0
var toast = "Find the six Cyber Blooms to awaken the Garden Portal."
var toastTime = 5.0
var glitchTime = 0.0
var glitchActive = false
var panel: GardenPanel = null
var window: JFrame = null
var gameTimer: Timer = null
val portalX = 900.0
val portalY = 235.0
def clamp(v: Double, low: Double, high: Double): Double = math.max(low, math.min(high, v))
def dist(x1: Double, y1: Double, x2: Double, y2: Double): Double = {
val dx = x1 - x2
val dy = y1 - y2
math.sqrt(dx * dx + dy * dy)
}
def hueColor(hue: Int, saturation: Float = 0.82f, brightness: Float = 1.0f): Color =
Color.getHSBColor((hue.toDouble / 360.0).toFloat, saturation, brightness)
def showToast(text: String, duration: Double = 2.8): Unit = {
toast = text
toastTime = duration
try { java.awt.Toolkit.getDefaultToolkit.beep() } catch { case _: Throwable => () }
}
def setupWorld(): Unit = {
blooms.clear()
blooms += new Bloom(590, 890, 166, "NEON ROSE")
blooms += new Bloom(300, 735, 190, "PIXEL TULIP")
blooms += new Bloom(835, 610, 138, "MINT ORCHID")
blooms += new Bloom(1450, 500, 292, "GLITCH DAISY")
blooms += new Bloom(1210, 360, 325, "CYBER LILY")
blooms += new Bloom(900, 430, 48, "SPRING STAR")
gardenFlowers.clear()
trees.clear()
particles.clear()
val flowerZones = Array((120.0, 150.0, 650.0, 340.0), (1200.0, 140.0, 500.0, 300.0),
(70.0, 1030.0, 650.0, 200.0), (1150.0, 930.0, 620.0, 260.0),
(430.0, 380.0, 250.0, 170.0), (1420.0, 690.0, 280.0, 220.0),
(620.0, 680.0, 270.0, 140.0), (1040.0, 480.0, 230.0, 100.0))
var i = 0
while (i < 145) {
val zone = flowerZones(random.nextInt(flowerZones.length))
val x = zone._1 + random.nextDouble() * zone._3
val y = zone._2 + random.nextDouble() * zone._4
val hue = Array(145, 164, 188, 282, 315, 48)(random.nextInt(6))
gardenFlowers += new GardenFlower(x, y, 5.0 + random.nextDouble() * 8.0,
hue, random.nextDouble() * 6.28, random.nextInt(9) == 0)
i += 1
}
val treeData = Array(
(135.0,180.0,1.12,150),(390.0,220.0,0.92,164),(740.0,145.0,0.85,142),
(1110.0,155.0,0.92,162),(1605.0,170.0,1.12,154),(1770.0,410.0,0.95,168),
(1735.0,900.0,1.12,152),(1550.0,1130.0,0.95,165),(1190.0,1110.0,0.92,150),
(720.0,1150.0,1.06,163),(350.0,1120.0,1.04,152),(130.0,850.0,1.00,165),
(530.0,430.0,0.82,152),(1050.0,760.0,0.90,166),(1640.0,720.0,0.90,150),
(240.0,560.0,0.82,160),(1320.0,245.0,0.76,155),(650.0,980.0,0.88,145))
treeData.foreach(t => trees += new GardenTree(t._1,t._2,t._3,t._4))
var p = 0
while (p < 90) {
particles += new Particle(random.nextDouble() * WORLD_W, random.nextDouble() * WORLD_H,
(random.nextDouble() - 0.5) * 0.7, -0.25 - random.nextDouble() * 0.7,
1.5 + random.nextDouble() * 3.5, Array(150,168,185,285,320,48)(random.nextInt(6)),
2.0 + random.nextDouble() * 7.0)
p += 1
}
}
def resetGame(): Unit = {
playerX = 900.0; playerY = 1050.0
facingX = 0.0; facingY = -1.0
frames = 0L; secondsPlayed = 0.0; remainingSeconds = 360.0
started = false; paused = false; won = false; lost = false
glowMode = true; showMap = true
dashTime = 0.0; dashCooldown = 0.0
blooms.foreach(_.collected = false)
showToast("Welcome to Cyber Bloom Garden! Press ENTER to start.", 4.5)
}
def collectedCount: Int = blooms.count(_.collected)
def triggerDash(): Unit = {
if (started && !paused && !won && !lost && dashCooldown <= 0.0) {
dashTime = 0.22
dashCooldown = 1.0
showToast("CYBER DASH!", 0.75)
}
}
def interact(): Unit = {
if (!started || paused || won || lost) return
val nearest = blooms.filter(!_.collected).sortBy(b => dist(playerX,playerY,b.x,b.y)).headOption
nearest match {
case Some(b) if dist(playerX, playerY, b.x, b.y) < 95.0 =>
b.collected = true
showToast("CYBER BLOOM RESTORED: " + b.label + " [" + collectedCount + "/" + GOAL_COUNT + "]", 2.7)
spawnBurst(b.x, b.y, b.hue, 24)
if (collectedCount >= GOAL_COUNT) showToast("ALL SIX BLOOMS RESTORED! Reach the portal at the top of the garden.", 4.2)
case _ if dist(playerX, playerY, portalX, portalY) < 125.0 && collectedCount >= GOAL_COUNT =>
won = true
showToast("GARDEN RESTORED! YOU CLEARED THE CYBER BLOOM EVENT!", 10.0)
case _ if dist(playerX, playerY, portalX, portalY) < 125.0 =>
showToast("PORTAL LOCKED: collect all six Cyber Blooms first.", 2.8)
case _ => showToast("Move close to a glowing bloom or the Garden Portal, then press E.", 2.4)
}
}
def spawnBurst(x: Double, y: Double, hue: Int, amount: Int): Unit = {
var i = 0
while (i < amount) {
val a = random.nextDouble() * math.Pi * 2.0
val speed = 25.0 + random.nextDouble() * 130.0
particles += new Particle(x, y, math.cos(a)*speed, math.sin(a)*speed,
2.0 + random.nextDouble()*4.0, hue, 0.5 + random.nextDouble()*1.2)
i += 1
}
}
def updateGame(dt: Double): Unit = {
frames += 1
if (toastTime > 0.0) toastTime = math.max(0.0, toastTime - dt)
if (dashTime > 0.0) dashTime = math.max(0.0, dashTime - dt)
if (dashCooldown > 0.0) dashCooldown = math.max(0.0, dashCooldown - dt)
glitchTime -= dt
if (glitchTime <= 0.0) {
glitchTime = 1.8 + random.nextDouble()*3.6
glitchActive = random.nextInt(5) == 0
}
particles.foreach { p =>
p.x += p.vx * dt
p.y += p.vy * dt
p.life -= dt
if (p.y < 0) p.y = WORLD_H
if (p.x < 0) p.x = WORLD_W
if (p.x > WORLD_W) p.x = 0
}
particles --= particles.filter(_.life <= 0.0)
if (particles.length < 65) {
particles += new Particle(random.nextDouble()*WORLD_W, WORLD_H-10,
(random.nextDouble()-0.5)*18.0, -8.0-random.nextDouble()*23.0,
1.5+random.nextDouble()*3.0, Array(150,170,188,285,318,48)(random.nextInt(6)), 3.5)
}
if (!started || paused || won || lost) return
secondsPlayed += dt
remainingSeconds = math.max(0.0, remainingSeconds-dt)
if (remainingSeconds <= 0.0) {
lost = true
showToast("EVENT TIME EXPIRED - PRESS R TO TRY AGAIN", 12.0)
return
}
var mx = 0.0
var my = 0.0
if (keys.contains(KeyEvent.VK_W) || keys.contains(KeyEvent.VK_UP)) my -= 1.0
if (keys.contains(KeyEvent.VK_S) || keys.contains(KeyEvent.VK_DOWN)) my += 1.0
if (keys.contains(KeyEvent.VK_A) || keys.contains(KeyEvent.VK_LEFT)) mx -= 1.0
if (keys.contains(KeyEvent.VK_D) || keys.contains(KeyEvent.VK_RIGHT)) mx += 1.0
val length = math.sqrt(mx*mx + my*my)
if (length > 0.0) {
mx /= length; my /= length
facingX = mx; facingY = my
val speed = if (dashTime > 0.0) 430.0 else 205.0
playerX = clamp(playerX + mx*speed*dt, 60.0, WORLD_W-60.0)
playerY = clamp(playerY + my*speed*dt, 60.0, WORLD_H-60.0)
}
if (collectedCount >= GOAL_COUNT && dist(playerX, playerY, portalX, portalY) < 82.0) {
won = true
showToast("GARDEN RESTORED! YOU CLEARED THE CYBER BLOOM EVENT!", 10.0)
spawnBurst(portalX, portalY, 165, 70)
}
if (glitchActive && random.nextInt(8) == 0) {
val b = blooms.filter(!_.collected).headOption
b.foreach(x => { /* visual glitch is only atmospheric; no progress is removed */ })
}
}
def drawGlow(g: Graphics2D, x: Int, y: Int, radius: Int, color: Color, alpha: Float): Unit = {
val old = g.getComposite
g.setComposite(AlphaComposite.SrcOver.derive(alpha))
g.setColor(color)
g.fillOval(x-radius, y-radius, radius*2, radius*2)
g.setComposite(old)
}
def drawCentered(g: Graphics2D, text: String, x: Int, y: Int): Unit = {
val width = g.getFontMetrics.stringWidth(text)
g.drawString(text, x-width/2, y)
}
def screenX(x: Double): Int = math.round(x-cameraX).toInt
def screenY(y: Double): Int = math.round(y-cameraY).toInt
def drawPath(g: Graphics2D): Unit = {
val oldStroke = g.getStroke
val oldColor = g.getColor
val oldComposite = g.getComposite
val pts = Array((900.0,1080.0,900.0,890.0),(900.0,890.0,300.0,890.0),
(300.0,890.0,300.0,610.0),(300.0,610.0,1450.0,610.0),
(1450.0,610.0,1450.0,360.0),(1450.0,360.0,900.0,360.0),(900.0,360.0,900.0,250.0))
g.setStroke(new BasicStroke(118.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND))
g.setColor(new Color(10,28,40))
pts.foreach(p => g.drawLine(screenX(p._1),screenY(p._2),screenX(p._3),screenY(p._4)))
g.setStroke(new BasicStroke(88.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND))
g.setComposite(AlphaComposite.SrcOver.derive(0.72f))
g.setColor(new Color(31,76,80))
pts.foreach(p => g.drawLine(screenX(p._1),screenY(p._2),screenX(p._3),screenY(p._4)))
g.setStroke(new BasicStroke(3.0f, BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND))
g.setColor(new Color(70,196,184,150))
pts.foreach(p => g.drawLine(screenX(p._1),screenY(p._2),screenX(p._3),screenY(p._4)))
g.setComposite(oldComposite)
g.setStroke(oldStroke)
g.setColor(oldColor)
}
def drawTree(g: Graphics2D, tree: GardenTree): Unit = {
val x = screenX(tree.x); val y = screenY(tree.y)
val s = tree.size
if (x < -100 || y < -150 || x > START_W+100 || y > START_H+100) return
drawGlow(g,x,y-28,(45*s).toInt,hueColor(tree.hue),0.07f)
g.setColor(new Color(54,66,56))
g.fillRoundRect((x-8*s).toInt,y-(35*s).toInt,(16*s).toInt,(54*s).toInt,7,7)
val canopy = hueColor(tree.hue,0.60f,0.52f)
g.setColor(canopy)
g.fillOval((x-34*s).toInt,y-(92*s).toInt,(68*s).toInt,(70*s).toInt)
g.setColor(hueColor(tree.hue,0.58f,0.72f))
g.fillOval((x-26*s).toInt,y-(102*s).toInt,(47*s).toInt,(48*s).toInt)
g.setColor(new Color(162,255,218,130))
g.drawArc((x-27*s).toInt,y-(99*s).toInt,(52*s).toInt,(49*s).toInt,40,115)
g.setColor(new Color(14,24,38,90))
g.fillOval((x-39*s).toInt,y-(28*s).toInt,(78*s).toInt,(18*s).toInt)
}
def drawSmallFlower(g: Graphics2D, x: Int, y: Int, size: Double, hue: Int, phase: Double, special: Boolean): Unit = {
if (x < -40 || y < -40 || x > START_W+40 || y > START_H+40) return
val color = hueColor(hue, if(special) 0.70f else 0.64f, 1.0f)
val pulse = 0.82 + 0.18*math.sin(frames*0.065 + phase)
val r = math.max(2,(size*pulse).toInt)
if (special && glowMode) drawGlow(g,x,y,r*5,color,0.12f)
g.setColor(new Color(28,105,76))
g.setStroke(new BasicStroke(2.0f))
g.drawLine(x,y+2,x,y+r*2+3)
val old = g.getTransform
g.rotate(frames*0.004+phase,x.toDouble,y.toDouble)
g.setColor(color)
var i=0
val petals = if(special) 8 else 5
while(i<petals) {
val a=i*math.Pi*2.0/petals
val px=x+math.round(math.cos(a)*r*0.78).toInt
val py=y+math.round(math.sin(a)*r*0.78).toInt
g.fillOval(px-r/2,py-r/2,math.max(3,r),math.max(3,r))
i+=1
}
g.setTransform(old)
g.setColor(if(special) GOLD else new Color(255,239,181))
g.fillOval(x-r/3,y-r/3,math.max(3,2*r/3),math.max(3,2*r/3))
}
def drawBloom(g: Graphics2D, b: Bloom): Unit = {
val x=screenX(b.x); val y=screenY(b.y)
if (b.collected || x < -100 || y < -100 || x > START_W+100 || y > START_H+100) return
val color=hueColor(b.hue,0.76f,1.0f)
val pulse=1.0+0.14*math.sin(frames*0.09+b.hue)
val r=(15*pulse).toInt
if(glowMode) {
drawGlow(g,x,y,r*5,color,0.09f)
drawGlow(g,x,y,r*3,CYAN,0.07f)
}
g.setColor(new Color(12,25,42,210))
g.fillOval(x-r-7,y-r-7,(r+7)*2,(r+7)*2)
g.setColor(color)
g.setStroke(new BasicStroke(2.0f))
g.drawOval(x-r-8,y-r-8,(r+8)*2,(r+8)*2)
drawSmallFlower(g,x,y,r.toDouble,colorHueValue(b.hue),b.hue*0.01,true)
g.setFont(new Font("SansSerif",Font.BOLD,10))
g.setColor(WHITE)
drawCentered(g,b.label, x, y-r-22)
g.setColor(CYAN)
drawCentered(g,"E / COLLECT",x,y+r+25)
if(glitchActive) {
g.setColor(new Color(255,65,197,150))
g.fillRect(x-r-12,y-2,r*2+24,2)
g.setColor(new Color(59,245,255,140))
g.fillRect(x-r-6,y+5,r*2+12,2)
}
}
def colorHueValue(hue: Int): Int = hue
def drawPortal(g: Graphics2D): Unit = {
val x=screenX(portalX); val y=screenY(portalY)
val ready=collectedCount>=GOAL_COUNT
val pulse=1.0+math.sin(frames*0.05)*0.06
val w=(118*pulse).toInt; val h=(152*pulse).toInt
if(glowMode) drawGlow(g,x,y,105,if(ready) MINT else PURPLE,0.10f)
g.setColor(new Color(8,13,31,220))
g.fillOval(x-w/2,y-h/2,w,h)
g.setColor(if(ready) MINT else PURPLE)
g.setStroke(new BasicStroke(5.0f))
g.drawOval(x-w/2,y-h/2,w,h)
g.setColor(new Color(56,232,236,100))
g.setStroke(new BasicStroke(2.0f))
g.drawOval(x-w/2+11,y-h/2+12,w-22,h-24)
g.setColor(new Color(201,123,255,90))
g.drawOval(x-w/2+23,y-h/2+22,w-46,h-44)
var i=0
while(i<7) {
val a=frames*0.027+i*math.Pi*2.0/7.0
val px=x+math.round(math.cos(a)*42).toInt
val py=y+math.round(math.sin(a)*60).toInt
g.setColor(if(i%2==0) CYAN else PINK)
g.fillOval(px-3,py-3,6,6)
i+=1
}
g.setFont(new Font("SansSerif",Font.BOLD,12))
g.setColor(if(ready) MINT else WHITE)
drawCentered(g,if(ready) "PORTAL READY" else "GARDEN PORTAL",x,y+h/2+23)
}
def drawPlayer(g: Graphics2D): Unit = {
val x=screenX(playerX); val y=screenY(playerY)
val bob=math.sin(frames*0.22)*2.3
if(glowMode) drawGlow(g,x,y,38,CYAN,0.09f)
g.setColor(new Color(0,0,0,100))
g.fillOval(x-20,y+16,40,12)
// boots / legs
g.setColor(new Color(24,40,65))
g.fillRoundRect(x-13,y+2+(bob.toInt),10,21,5,5)
g.fillRoundRect(x+3,y+2-(bob.toInt),10,21,5,5)
g.setColor(CYAN)
g.fillRoundRect(x-14,y+17,12,6,3,3)
g.fillRoundRect(x+2,y+17,12,6,3,3)
// body and backpack
g.setColor(new Color(23,46,83))
g.fillRoundRect(x-17,y-23+bob.toInt,34,33,12,12)
g.setColor(new Color(44,182,201))
g.fillRoundRect(x-14,y-20+bob.toInt,28,26,9,9)
g.setColor(new Color(170,255,238))
g.fillRoundRect(x-5,y-18+bob.toInt,10,20,4,4)
g.setColor(PURPLE)
g.fillRoundRect(x+12,y-18+bob.toInt,8,21,5,5)
// head / visor
g.setColor(new Color(232,199,166))
g.fillOval(x-11,y-43+bob.toInt,22,23)
g.setColor(new Color(25,38,61))
g.fillRoundRect(x-13,y-39+bob.toInt,26,10,7,7)
g.setColor(CYAN)
g.fillRoundRect(x-8,y-36+bob.toInt,16,4,3,3)
// animated direction marker
g.setColor(new Color(255,255,255,190))
g.drawLine(x,y-48+bob.toInt,x+(facingX*15).toInt,y-48+(facingY*15).toInt+bob.toInt)
if(dashTime>0) {
g.setColor(new Color(91,250,245,130))
g.setStroke(new BasicStroke(3.0f))
g.drawLine(x-(facingX*42).toInt,y+8-(facingY*42).toInt,x,y+8)
}
}
def drawParticles(g: Graphics2D): Unit = {
particles.foreach { p =>
val x=screenX(p.x); val y=screenY(p.y)
if (x >= -5 && y >= -5 && x < START_W + 5 && y < START_H + 5) {
val alpha=clamp(p.life/2.0,0.0,0.8).toFloat
val old=g.getComposite
g.setComposite(AlphaComposite.SrcOver.derive(alpha))
g.setColor(hueColor(p.hue,0.55f,1.0f))
g.fillOval(x,y,math.max(2,p.size.toInt),math.max(2,p.size.toInt))
g.setComposite(old)
}
}
}
def drawHUD(g: Graphics2D, w: Int, h: Int): Unit = {
val old=g.getComposite
g.setComposite(AlphaComposite.SrcOver.derive(0.88f))
g.setColor(new Color(7,15,31))
g.fillRoundRect(16,15,465,93,20,20)
g.setColor(new Color(61,226,213,180))
g.drawRoundRect(16,15,465,93,20,20)
g.setComposite(old)
g.setFont(new Font("SansSerif",Font.BOLD,19))
g.setColor(CYAN)
g.drawString("CYBER BLOOM",31,43)
g.setFont(new Font("SansSerif",Font.BOLD,11))
g.setColor(WHITE)
g.drawString("GLITCH IN THE GARDEN / SPRING SEASON",31,62)
g.setColor(MUTED)
g.drawString("BLOOMS RESTORED " + collectedCount + " / " + GOAL_COUNT,31,86)
val barX=206; val barY=76; val barW=245; val barH=9
g.setColor(new Color(35,56,73)); g.fillRoundRect(barX,barY,barW,barH,8,8)
g.setColor(if(collectedCount==GOAL_COUNT) MINT else PINK)
g.fillRoundRect(barX,barY,math.max(0,(barW*collectedCount/GOAL_COUNT)),barH,8,8)
g.setColor(new Color(7,15,31,220))
g.fillRoundRect(w-190,18,170,74,17,17)
g.setColor(new Color(61,226,213,180))
g.drawRoundRect(w-190,18,170,74,17,17)
val mins=(remainingSeconds.toInt/60)
val secs=remainingSeconds.toInt%60
g.setFont(new Font("Monospaced",Font.BOLD,22))
g.setColor(if(remainingSeconds<45) PINK else GOLD)
g.drawString(f"$mins%02d:$secs%02d",w-168,52)
g.setFont(new Font("SansSerif",Font.PLAIN,10))
g.setColor(MUTED)
g.drawString("EVENT TIME LEFT",w-166,72)
val bottomY=h-57
g.setColor(new Color(6,13,27,225))
g.fillRoundRect(15,bottomY,w-30,42,14,14)
g.setColor(new Color(71,153,177,160))
g.drawRoundRect(15,bottomY,w-30,42,14,14)
g.setFont(new Font("SansSerif",Font.BOLD,11))
g.setColor(WHITE)
g.drawString("WASD / ARROWS MOVE",30,bottomY+17)
g.setColor(CYAN); g.drawString("E INTERACT",220,bottomY+17)
g.setColor(PINK); g.drawString("SPACE DASH",335,bottomY+17)
g.setColor(GOLD); g.drawString("F GLOW",458,bottomY+17)
g.setColor(MUTED); g.drawString("M MAP | ESC PAUSE | R RESTART",565,bottomY+17)
if(toastTime>0.0) {
val tw=math.min(w-60,math.max(400,g.getFontMetrics.stringWidth(toast)+42))
val tx=(w-tw)/2
g.setColor(new Color(8,18,34,230))
g.fillRoundRect(tx,h-103,tw,34,15,15)
g.setColor(new Color(71,238,220,170))
g.drawRoundRect(tx,h-103,tw,34,15,15)
g.setFont(new Font("SansSerif",Font.BOLD,12))
g.setColor(WHITE)
drawCentered(g,toast,w/2,h-82)
}
if(showMap) drawMiniMap(g,w)
if(glitchActive && frames%4<2 && started && !paused && !won && !lost) {
val oldC=g.getComposite
g.setComposite(AlphaComposite.SrcOver.derive(0.10f))
g.setColor(PINK); g.fillRect(0,116,w,3)
g.setColor(CYAN); g.fillRect(0,120,w,2)
g.setComposite(oldC)
}
}
def drawMiniMap(g: Graphics2D,w: Int): Unit = {
val x=w-190; val y=110; val mw=168; val mh=116
g.setColor(new Color(6,14,29,210)); g.fillRoundRect(x,y,mw,mh,12,12)
g.setColor(new Color(60,211,206,160)); g.drawRoundRect(x,y,mw,mh,12,12)
def mx(v: Double): Int = x+8+(v/WORLD_W* (mw-16)).toInt
def my(v: Double): Int = y+8+(v/WORLD_H*(mh-16)).toInt
g.setStroke(new BasicStroke(4.0f)); g.setColor(new Color(48,106,111))
val paths=Array((900.0,1080.0,900.0,890.0),(900.0,890.0,300.0,890.0),(300.0,890.0,300.0,610.0),
(300.0,610.0,1450.0,610.0),(1450.0,610.0,1450.0,360.0),(1450.0,360.0,900.0,360.0),(900.0,360.0,900.0,250.0))
paths.foreach(p=>g.drawLine(mx(p._1),my(p._2),mx(p._3),my(p._4)))
blooms.filter(!_.collected).foreach(b=>{g.setColor(hueColor(b.hue));g.fillOval(mx(b.x)-2,my(b.y)-2,5,5)})
g.setColor(MINT);g.fillOval(mx(portalX)-4,my(portalY)-4,8,8)
g.setColor(WHITE);g.fillOval(mx(playerX)-3,my(playerY)-3,6,6)
g.setFont(new Font("SansSerif",Font.BOLD,9));g.setColor(MUTED);g.drawString("GARDEN MAP",x+9,y+12)
}
def drawIntroOverlay(g: Graphics2D,w: Int,h: Int): Unit = {
g.setColor(new Color(3,8,22,188))
g.fillRect(0,0,w,h)
val cx=w/2; val cy=h/2
drawGlow(g,cx,cy-90,180,PURPLE,0.08f)
g.setFont(new Font("SansSerif",Font.BOLD,17)); g.setColor(MINT)
drawCentered(g,"SPRING SEASON EVENT / LIMITED-TIME GARDEN QUEST",cx,cy-185)
g.setFont(new Font("SansSerif",Font.BOLD,42)); g.setColor(CYAN)
drawCentered(g,"CYBER BLOOM",cx,cy-126)
g.setFont(new Font("SansSerif",Font.BOLD,29)); g.setColor(PINK)
drawCentered(g,"GLITCH IN THE GARDEN",cx,cy-85)
g.setFont(new Font("SansSerif",Font.PLAIN,15)); g.setColor(WHITE)
drawCentered(g,"A corrupted spring has hidden six Cyber Blooms across the garden.",cx,cy-40)
drawCentered(g,"Restore the flowers, avoid the glitch, and awaken the Garden Portal.",cx,cy-17)
val bw=260; val bh=54; val bx=cx-bw/2; val by=cy+25
g.setColor(new Color(17,55,72,240));g.fillRoundRect(bx,by,bw,bh,20,20)
g.setStroke(new BasicStroke(2.5f));g.setColor(CYAN);g.drawRoundRect(bx,by,bw,bh,20,20)
g.setFont(new Font("SansSerif",Font.BOLD,18));g.setColor(WHITE)
drawCentered(g,"ENTER THE GARDEN",cx,by+34)
g.setFont(new Font("SansSerif",Font.PLAIN,12));g.setColor(MUTED)
drawCentered(g,"ENTER / SPACE / CLICK TO START",cx,by+bh+30)
drawCentered(g,"Controls: WASD move ? E collect ? SPACE dash ? F glow ? M map",cx,by+bh+54)
g.setColor(new Color(255,255,255,120));g.setFont(new Font("SansSerif",Font.PLAIN,10))
drawCentered(g,"ORIGINAL SCALA SWING MINI-GAME ? OFFLINE ? NO EXTERNAL ASSETS",cx,h-18)
}
def drawEndOverlay(g: Graphics2D,w: Int,h: Int): Unit = {
g.setColor(new Color(3,8,22,205));g.fillRect(0,0,w,h)
val title=if(won) "SPRING RESTORED!" else if(lost) "THE GLITCH WON THIS ROUND" else "PAUSED"
g.setFont(new Font("SansSerif",Font.BOLD,36));g.setColor(if(won) MINT else if(lost) PINK else CYAN)
drawCentered(g,title,w/2,h/2-46)
g.setFont(new Font("SansSerif",Font.PLAIN,16));g.setColor(WHITE)
val subtitle=if(won) "You gathered all six Cyber Blooms and opened the Garden Portal." else if(lost) "Time ran out. The garden can still be restored on another attempt." else "The garden is waiting. Press ESC to continue."
drawCentered(g,subtitle,w/2,h/2-12)
g.setFont(new Font("SansSerif",Font.BOLD,15));g.setColor(GOLD)
drawCentered(g,"PRESS R TO RESTART",w/2,h/2+35)
}
final class GardenPanel extends JPanel {
setPreferredSize(new Dimension(START_W,START_H))
setBackground(BG_TOP)
setFocusable(true)
setDoubleBuffered(true)
setCursor(new Cursor(Cursor.CROSSHAIR_CURSOR))
addKeyListener(new KeyAdapter {
override def keyPressed(e: KeyEvent): Unit = {
val k=e.getKeyCode
keys += k
if(!started && (k==KeyEvent.VK_ENTER || k==KeyEvent.VK_SPACE)) {
started=true; paused=false; showToast("Quest started! Restore all six Cyber Blooms.",3.2)
} else if(k==KeyEvent.VK_E) interact()
else if(k==KeyEvent.VK_SPACE && started) triggerDash()
else if(k==KeyEvent.VK_F) glowMode = !glowMode
else if(k==KeyEvent.VK_M) showMap = !showMap
else if(k==KeyEvent.VK_ESCAPE && started && !won && !lost) paused = !paused
else if(k==KeyEvent.VK_R) resetGame()
}
override def keyReleased(e: KeyEvent): Unit = { keys -= e.getKeyCode }
})
addMouseListener(new MouseAdapter {
override def mouseClicked(e: MouseEvent): Unit = {
requestFocusInWindow()
if(!started) {started=true; showToast("Quest started! Restore all six Cyber Blooms.",3.2)}
else if(!paused && !won && !lost) interact()
}
})
override protected def paintComponent(graphics: Graphics): Unit = {
super.paintComponent(graphics)
val g=graphics.create().asInstanceOf[Graphics2D]
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON)
g.setRenderingHint(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY)
val w=getWidth; val h=getHeight
g.setPaint(new GradientPaint(0f,0f,BG_TOP,0f,h.toFloat,BG_BOTTOM))
g.fillRect(0,0,w,h)
cameraX=clamp(playerX-w/2.0,0.0,WORLD_W-w)
cameraY=clamp(playerY-h/2.0,0.0,WORLD_H-h)
drawGround(g,w,h)
drawPath(g)
trees.foreach(t=>drawTree(g,t))
gardenFlowers.foreach(f=>drawSmallFlower(g,screenX(f.x),screenY(f.y),f.size,f.hue,f.phase,f.glitch))
blooms.foreach(b=>drawBloom(g,b))
drawPortal(g)
drawParticles(g)
drawPlayer(g)
if(started) drawHUD(g,w,h)
if(!started) drawIntroOverlay(g,w,h)
else if(paused || won || lost) drawEndOverlay(g,w,h)
g.dispose()
}
}
def drawGround(g: Graphics2D,w: Int,h: Int): Unit = {
g.setColor(new Color(17,49,53))
g.fillRect(-cameraX.toInt,-cameraY.toInt,WORLD_W,WORLD_H)
// Glowing ground grid in world coordinates.
val old=g.getComposite
g.setComposite(AlphaComposite.SrcOver.derive(0.11f))
g.setColor(new Color(59,211,202))
val step=80
var x=(cameraX/step).toInt*step
while(x<cameraX+w+step) {g.drawLine((x-cameraX).toInt,0,(x-cameraX).toInt,h);x+=step}
var y=(cameraY/step).toInt*step
while(y<cameraY+h+step) {g.drawLine(0,(y-cameraY).toInt,w,(y-cameraY).toInt);y+=step}
g.setComposite(old)
// softly illuminated flower-bed islands
val beds=Array((250.0,260.0,460.0,260.0,160),(1310.0,255.0,470.0,260.0,285),
(260.0,1080.0,500.0,180.0,150),(1350.0,1050.0,460.0,280.0,165),
(605.0,440.0,310.0,190.0,318),(1470.0,750.0,310.0,260.0,48),(1090.0,500.0,280.0,170.0,188))
beds.foreach { b =>
val c=hueColor(b._5,0.58f,0.75f)
g.setColor(new Color(c.getRed,c.getGreen,c.getBlue,18))
g.fillOval(screenX(b._1).toInt-(b._3/2).toInt,screenY(b._2).toInt-(b._4/2).toInt,b._3.toInt,b._4.toInt)
g.setColor(new Color(c.getRed,c.getGreen,c.getBlue,70))
g.drawOval(screenX(b._1).toInt-(b._3/2).toInt,screenY(b._2).toInt-(b._4/2).toInt,b._3.toInt,b._4.toInt)
}
// slim cyber fence markers at the edge of the map
g.setColor(new Color(70,222,207,100))
g.setStroke(new BasicStroke(3.0f))
g.drawRect(screenX(35).toInt,screenY(35).toInt,WORLD_W-70,WORLD_H-70)
}
def main(args: Array[String]): Unit = {
setupWorld()
SwingUtilities.invokeLater(new Runnable {
override def run(): Unit = {
window = new JFrame(APP_TITLE)
panel = new GardenPanel()
window.setContentPane(panel)
window.setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE)
window.setMinimumSize(new Dimension(900,620))
window.setSize(START_W,START_H)
window.setLocationRelativeTo(null)
window.setVisible(true)
panel.requestFocusInWindow()
gameTimer = new Timer(33,new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = {
updateGame(0.033)
if(panel!=null) panel.repaint()
}
})
gameTimer.start()
}
})
}
}
SpringSeasonCyberBloomGlitch.main(Array[String]())