Code Sketch


Bixuu InfinityRealmFinalAwakeningEvent10
By: Mhalsakant School
Category: Programming
import java.awt.{BasicStroke, BorderLayout, Color, Dimension, FlowLayout, Font, GradientPaint, Graphics, Graphics2D, Polygon, RenderingHints}
import java.awt.event.{ActionEvent, ActionListener, KeyAdapter, KeyEvent, MouseAdapter, MouseEvent, WindowAdapter, WindowEvent}
import javax.swing.{BorderFactory, JButton, JFrame, JLabel, JPanel, JTextField, SwingConstants, SwingUtilities, Timer, WindowConstants}
import scala.collection.mutable.ArrayBuffer
import scala.util.Random

object InfinityRealmFinalAwakeningEvent10 {
  def main(args: Array[String]): Unit = {
    SwingUtilities.invokeLater(new Runnable {
      def run(): Unit = openWindow()
    })
  }

  def openWindow(): Unit = {
    val frame = new JFrame("INFINITY REALMS SEASON 10 - FINAL AWAKENING")
    frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE)
    frame.setSize(1120, 760)
    frame.setResizable(false)
    frame.setLocationRelativeTo(null)

    var activeGame: InfinityFinalGamePanel = null
    var loginPanel: InfinityFinalLoginPanel = null
    loginPanel = new InfinityFinalLoginPanel((chosenName: String) => {
      activeGame = new InfinityFinalGamePanel(chosenName, () => {
        if (activeGame != null) activeGame.stopGame()
        frame.setContentPane(loginPanel)
        frame.revalidate()
        frame.repaint()
      })
      frame.setContentPane(activeGame)
      frame.revalidate()
      frame.repaint()
      activeGame.startGame()
      activeGame.arenaCanvas.requestFocusInWindow()
    })

    frame.addWindowListener(new WindowAdapter {
      override def windowClosing(e: WindowEvent): Unit = {
        if (activeGame != null) activeGame.stopGame()
      }
    })

    frame.setContentPane(loginPanel)
    frame.setVisible(true)
  }
}

class InfinityFinalLoginPanel(onStart: String => Unit) extends JPanel {
  setPreferredSize(new Dimension(1120, 760))
  setLayout(null)
  setBackground(new Color(8, 13, 29))

  val titleLabel = new JLabel("INFINITY REALM: FINAL AWAKENING", SwingConstants.CENTER)
  titleLabel.setFont(new Font("SansSerif", Font.BOLD, 36))
  titleLabel.setForeground(new Color(245, 246, 255))
  titleLabel.setBounds(120, 115, 880, 58)
  add(titleLabel)

  val seasonLabel = new JLabel("INFINITY REALMS SEASON 10  |  ULTIMATE FINALE", SwingConstants.CENTER)
  seasonLabel.setFont(new Font("SansSerif", Font.BOLD, 17))
  seasonLabel.setForeground(new Color(255, 211, 130))
  seasonLabel.setBounds(180, 180, 760, 32)
  add(seasonLabel)

  val storyLabel = new JLabel("Unite every realm. Collect the five Eternal Seals. Awaken the Infinity Core.", SwingConstants.CENTER)
  storyLabel.setFont(new Font("SansSerif", Font.PLAIN, 16))
  storyLabel.setForeground(new Color(205, 220, 245))
  storyLabel.setBounds(170, 235, 780, 34)
  add(storyLabel)

  val nameLabel = new JLabel("ENTER YOUR HERO NAME", SwingConstants.CENTER)
  nameLabel.setFont(new Font("SansSerif", Font.BOLD, 15))
  nameLabel.setForeground(new Color(236, 241, 255))
  nameLabel.setBounds(385, 330, 350, 28)
  add(nameLabel)

  val nameField = new JTextField("Realm Walker")
  nameField.setFont(new Font("SansSerif", Font.PLAIN, 20))
  nameField.setHorizontalAlignment(SwingConstants.CENTER)
  nameField.setBounds(385, 365, 350, 44)
  add(nameField)

  val startButton = new JButton("BEGIN THE FINAL AWAKENING")
  startButton.setFont(new Font("SansSerif", Font.BOLD, 16))
  startButton.setForeground(Color.WHITE)
  startButton.setBackground(new Color(99, 74, 177))
  startButton.setFocusPainted(false)
  startButton.setBounds(365, 435, 390, 52)
  startButton.addActionListener(new ActionListener {
    def actionPerformed(e: ActionEvent): Unit = {
      var chosenName = nameField.getText.trim
      if (chosenName.length == 0) chosenName = "Realm Walker"
      onStart(chosenName)
    }
  })
  add(startButton)

  val controlsLabel = new JLabel("WASD / ARROWS: MOVE     SPACE: DASH     1-4: SELECT POWER     F: CAST     E: PORTAL", SwingConstants.CENTER)
  controlsLabel.setFont(new Font("SansSerif", Font.PLAIN, 12))
  controlsLabel.setForeground(new Color(174, 190, 220))
  controlsLabel.setBounds(100, 600, 920, 24)
  add(controlsLabel)

  val safetyLabel = new JLabel("Offline single-player finale  |  No Windows settings or personal files are changed", SwingConstants.CENTER)
  safetyLabel.setFont(new Font("SansSerif", Font.PLAIN, 12))
  safetyLabel.setForeground(new Color(135, 153, 185))
  safetyLabel.setBounds(180, 632, 760, 22)
  add(safetyLabel)

  override def paintComponent(g: Graphics): Unit = {
    super.paintComponent(g)
    val g2 = g.asInstanceOf[Graphics2D]
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
    g2.setPaint(new GradientPaint(0, 0, new Color(8, 13, 31), 0, getHeight, new Color(34, 22, 67)))
    g2.fillRect(0, 0, getWidth, getHeight)

    var i = 0
    while (i < 100) {
      val x = (i * 149 + 31) % getWidth
      val y = (i * 83 + 19) % getHeight
      val r = 2 + (i % 4)
      if (i % 3 == 0) g2.setColor(new Color(255, 211, 130, 150))
      else if (i % 3 == 1) g2.setColor(new Color(137, 164, 255, 145))
      else g2.setColor(new Color(202, 145, 255, 145))
      g2.fillOval(x, y, r, r)
      i += 1
    }

    g2.setColor(new Color(115, 89, 220, 55))
    g2.fillOval(370, 10, 380, 330)
    g2.setColor(new Color(13, 16, 39, 180))
    g2.fillOval(430, 25, 280, 300)
    g2.setStroke(new BasicStroke(5.0f))
    g2.setColor(new Color(255, 210, 135, 150))
    g2.drawOval(395, 15, 330, 320)
  }
}

class InfinityFinalRelic(var x: Double, var y: Double, var collected: Boolean, val sealName: String)
class InfinityFinalWisp(var x: Double, var y: Double, var stunTicks: Int)

class InfinityFinalGamePanel(val playerName: String, onBackToLogin: () => Unit) extends JPanel {
  setLayout(new BorderLayout())
  setPreferredSize(new Dimension(1120, 760))
  setBackground(new Color(9, 14, 29))

  val realmNames = Array("ETERNAL BLOOM GROVE", "PHANTOM LOST DIMENSION", "CRYSTAL CORE CITADEL", "ANCIENT DRAGON DOMINION", "PRIMAL POWER NEXUS")
  val realmTopColors = Array(
    new Color(16, 69, 62),
    new Color(35, 25, 66),
    new Color(17, 52, 83),
    new Color(86, 43, 31),
    new Color(44, 34, 83)
  )
  val realmBottomColors = Array(
    new Color(29, 111, 77),
    new Color(12, 12, 31),
    new Color(10, 30, 54),
    new Color(42, 22, 27),
    new Color(13, 15, 43)
  )
  val realmSealNames = Array("Bloom Seal", "Phantom Seal", "Crystal Seal", "Dragon Seal", "Primal Seal")
  val powerNames = Array("BLOOM HEAL", "PHANTOM VEIL", "CRYSTAL PULSE", "DRAGON NOVA")
  val powerColors = Array(
    new Color(112, 242, 164),
    new Color(185, 139, 255),
    new Color(99, 218, 255),
    new Color(255, 166, 95)
  )

  val relics = ArrayBuffer[InfinityFinalRelic]()
  val wisps = ArrayBuffer[InfinityFinalWisp]()
  val pressedKeys = scala.collection.mutable.Set[Int]()
  val random = new Random()

  var level = 1
  var realmIndex = 0
  var playerX = 85.0
  var playerY = 340.0
  var playerHealth = 6
  var energy = 70
  var coins = 0
  var score = 0
  var totalRelics = 0
  var selectedPower = 0
  var shieldTicks = 0
  var dashTicks = 0
  var dashCooldown = 0
  var castCooldown = 0
  var invulnerableTicks = 0
  var tickCount = 0
  var paused = false
  var gameOver = false
  var victory = false
  var bossActive = false
  var bossHealth = 12
  var bossX = 870.0
  var bossY = 340.0
  var bossStunTicks = 0
  var mouseTargetX = -1.0
  var mouseTargetY = -1.0
  var statusMessage = "Collect 3 realm relics, then approach the glowing gate and press E."
  var gameTimer: Timer = null

  val arenaCanvas = new JPanel() {
    setFocusable(true)
    setBackground(new Color(12, 20, 35))
    override def paintComponent(g: Graphics): Unit = {
      super.paintComponent(g)
      val g2 = g.asInstanceOf[Graphics2D]
      g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
      InfinityFinalGamePanel.this.drawWorld(g2)
    }
  }
  arenaCanvas.setPreferredSize(new Dimension(1120, 690))
  add(arenaCanvas, BorderLayout.CENTER)

  val buttonPanel = new JPanel(new FlowLayout(FlowLayout.CENTER, 6, 5))
  buttonPanel.setBackground(new Color(12, 15, 31))
  buttonPanel.setBorder(BorderFactory.createEmptyBorder(2, 4, 2, 4))

  def addGameButton(label: String, action: () => Unit): Unit = {
    val button = new JButton(label)
    button.setFont(new Font("SansSerif", Font.BOLD, 11))
    button.setForeground(Color.WHITE)
    button.setBackground(new Color(53, 56, 105))
    button.setFocusPainted(false)
    button.addActionListener(new ActionListener {
      def actionPerformed(e: ActionEvent): Unit = {
        action()
        arenaCanvas.requestFocusInWindow()
        arenaCanvas.repaint()
      }
    })
    buttonPanel.add(button)
  }

  addGameButton("1 BLOOM", () => { selectedPower = 0; castSelectedPower() })
  addGameButton("2 PHANTOM", () => { selectedPower = 1; castSelectedPower() })
  addGameButton("3 CRYSTAL", () => { selectedPower = 2; castSelectedPower() })
  addGameButton("4 DRAGON", () => { selectedPower = 3; castSelectedPower() })
  addGameButton("DASH", () => activateDash())
  addGameButton("SHIELD", () => useShield())
  addGameButton("PORTAL", () => interactWithGate())
  addGameButton("PAUSE", () => { paused = !paused })
  addGameButton("LOBBY", () => onBackToLogin())
  add(buttonPanel, BorderLayout.SOUTH)

  loadLevel()

  def startGame(): Unit = {
    if (gameTimer == null) {
      gameTimer = new Timer(25, new ActionListener {
        def actionPerformed(e: ActionEvent): Unit = updateGame()
      })
      gameTimer.start()
    }
    arenaCanvas.requestFocusInWindow()
  }

  def stopGame(): Unit = {
    if (gameTimer != null) gameTimer.stop()
  }

  def clamp(value: Double, low: Double, high: Double): Double = Math.max(low, Math.min(high, value))

  def distance(ax: Double, ay: Double, bx: Double, by: Double): Double = {
    val dx = ax - bx
    val dy = ay - by
    Math.sqrt(dx * dx + dy * dy)
  }

  def currentRelics(): Int = relics.count(r => r.collected)

  def loadLevel(): Unit = {
    realmIndex = (level - 1) / 2
    if (realmIndex > 4) realmIndex = 4
    playerX = 78.0
    playerY = 340.0
    mouseTargetX = -1.0
    mouseTargetY = -1.0
    relics.clear()
    relics += new InfinityFinalRelic(230.0, 190.0, false, realmSealNames(realmIndex))
    relics += new InfinityFinalRelic(420.0, 500.0, false, realmSealNames(realmIndex))
    relics += new InfinityFinalRelic(650.0, 190.0, false, realmSealNames(realmIndex))
    wisps.clear()
    wisps += new InfinityFinalWisp(370.0, 340.0, 0)
    wisps += new InfinityFinalWisp(700.0, 440.0, 0)
    if (level >= 5) wisps += new InfinityFinalWisp(560.0, 290.0, 0)
    bossActive = level == 10
    bossHealth = 12
    bossX = 900.0
    bossY = 340.0
    bossStunTicks = 0
    if (bossActive) statusMessage = "FINAL BOSS: collect all 3 Primal Seals, then use CRYSTAL or DRAGON power!"
    else statusMessage = "Realm " + level + "/10: collect 3 relics and reach the portal."
  }

  def activateDash(): Unit = {
    if (!paused && !gameOver && !victory && dashCooldown == 0) {
      dashTicks = 13
      dashCooldown = 55
      statusMessage = "REALM DASH ACTIVATED!"
    }
  }

  def useShield(): Unit = {
    if (paused || gameOver || victory) return
    if (energy >= 18) {
      energy -= 18
      shieldTicks = 150
      statusMessage = "ETERNAL AURA SHIELD ACTIVE!"
    } else statusMessage = "Not enough energy for the shield. Collect relics!"
  }

  def castSelectedPower(): Unit = {
    if (paused || gameOver || victory) return
    if (castCooldown > 0) {
      statusMessage = "Power is recharging."
      return
    }
    if (energy < 22) {
      statusMessage = "Not enough energy. Collect more relics!"
      return
    }
    energy -= 22
    castCooldown = 35
    if (selectedPower == 0) {
      playerHealth = Math.min(6, playerHealth + 1)
      statusMessage = "BLOOM HEAL restored your life."
    } else if (selectedPower == 1) {
      shieldTicks = 180
      var i = 0
      while (i < wisps.length) {
        wisps(i).stunTicks = 100
        i += 1
      }
      statusMessage = "PHANTOM VEIL concealed you from the Wisps."
    } else if (selectedPower == 2) {
      var j = 0
      while (j < wisps.length) {
        if (distance(playerX, playerY, wisps(j).x, wisps(j).y) < 260.0) wisps(j).stunTicks = 130
        j += 1
      }
      if (bossActive && bossHealth > 0 && distance(playerX, playerY, bossX, bossY) < 310.0) {
        bossHealth = Math.max(0, bossHealth - 1)
        bossStunTicks = 75
      }
      statusMessage = "CRYSTAL PULSE stunned nearby shadows and damaged the boss if close."
    } else {
      var k = 0
      while (k < wisps.length) {
        if (distance(playerX, playerY, wisps(k).x, wisps(k).y) < 330.0) wisps(k).stunTicks = 160
        k += 1
      }
      if (bossActive && bossHealth > 0 && distance(playerX, playerY, bossX, bossY) < 350.0) {
        bossHealth = Math.max(0, bossHealth - 2)
        bossStunTicks = 100
      }
      statusMessage = "DRAGON NOVA released a burst of ancient power!"
    }
  }

  def interactWithGate(): Unit = {
    if (paused || gameOver || victory) return
    val gateX = arenaCanvas.getWidth - 62.0
    val gateY = arenaCanvas.getHeight / 2.0
    if (distance(playerX, playerY, gateX, gateY) > 95.0) {
      statusMessage = "Move close to the glowing portal, then press E."
    } else if (currentRelics() < 3) {
      statusMessage = "The portal needs all 3 realm relics. Keep exploring!"
    } else if (bossActive && bossHealth > 0) {
      statusMessage = "The Infinity Guardian still protects the final portal!"
    } else if (level >= 10) {
      victory = true
      coins += 500
      score += 1000
      statusMessage = "THE INFINITY CORE IS AWAKENED! YOU SAVED EVERY REALM!"
    } else {
      coins += 100
      score += 150
      level += 1
      loadLevel()
    }
    arenaCanvas.repaint()
  }

  def returnToBase(): Unit = {
    playerX = 78.0
    playerY = arenaCanvas.getHeight / 2.0
    mouseTargetX = -1.0
    mouseTargetY = -1.0
    statusMessage = "Returned to the safe Realm Base. Your collected seals remain."
    arenaCanvas.repaint()
  }

  def restartGame(): Unit = {
    level = 1
    playerHealth = 6
    energy = 70
    coins = 0
    score = 0
    totalRelics = 0
    selectedPower = 0
    shieldTicks = 0
    dashTicks = 0
    dashCooldown = 0
    castCooldown = 0
    invulnerableTicks = 0
    paused = false
    gameOver = false
    victory = false
    loadLevel()
    statusMessage = "A new journey begins. Unite all five realms!"
    arenaCanvas.requestFocusInWindow()
    arenaCanvas.repaint()
  }

  def updateGame(): Unit = {
    if (paused || gameOver || victory) {
      arenaCanvas.repaint()
      return
    }

    tickCount += 1
    if (dashTicks > 0) dashTicks -= 1
    if (dashCooldown > 0) dashCooldown -= 1
    if (castCooldown > 0) castCooldown -= 1
    if (shieldTicks > 0) shieldTicks -= 1
    if (invulnerableTicks > 0) invulnerableTicks -= 1
    if (bossStunTicks > 0) bossStunTicks -= 1

    val baseSpeed = 2.65 + Math.min(1.25, totalRelics * 0.035)
    val moveSpeed = if (dashTicks > 0) baseSpeed * 2.65 else baseSpeed
    var dx = 0.0
    var dy = 0.0

    if (pressedKeys.contains(KeyEvent.VK_A) || pressedKeys.contains(KeyEvent.VK_LEFT)) dx -= 1.0
    if (pressedKeys.contains(KeyEvent.VK_D) || pressedKeys.contains(KeyEvent.VK_RIGHT)) dx += 1.0
    if (pressedKeys.contains(KeyEvent.VK_W) || pressedKeys.contains(KeyEvent.VK_UP)) dy -= 1.0
    if (pressedKeys.contains(KeyEvent.VK_S) || pressedKeys.contains(KeyEvent.VK_DOWN)) dy += 1.0

    if (dx != 0.0 || dy != 0.0) {
      val magnitude = Math.sqrt(dx * dx + dy * dy)
      playerX += (dx / magnitude) * moveSpeed
      playerY += (dy / magnitude) * moveSpeed
      mouseTargetX = -1.0
      mouseTargetY = -1.0
    } else if (mouseTargetX >= 0.0 && mouseTargetY >= 0.0) {
      val md = distance(playerX, playerY, mouseTargetX, mouseTargetY)
      if (md < 7.0) {
        mouseTargetX = -1.0
        mouseTargetY = -1.0
      } else {
        playerX += ((mouseTargetX - playerX) / md) * moveSpeed
        playerY += ((mouseTargetY - playerY) / md) * moveSpeed
      }
    }

    playerX = clamp(playerX, 34.0, Math.max(36.0, arenaCanvas.getWidth - 35.0))
    playerY = clamp(playerY, 112.0, Math.max(114.0, arenaCanvas.getHeight - 48.0))

    var r = 0
    while (r < relics.length) {
      val relic = relics(r)
      if (!relic.collected && distance(playerX, playerY, relic.x, relic.y) < 30.0) {
        relic.collected = true
        totalRelics += 1
        score += 60
        coins += 25
        energy = Math.min(100, energy + 22)
        statusMessage = realmSealNames(realmIndex).toUpperCase + " COLLECTED! +25 CREDITS"
      }
      r += 1
    }

    var w = 0
    while (w < wisps.length) {
      val enemy = wisps(w)
      if (enemy.stunTicks > 0) enemy.stunTicks -= 1
      else {
        val wd = distance(playerX, playerY, enemy.x, enemy.y)
        if (wd > 1.0) {
          val enemySpeed = 0.72 + (level.toDouble * 0.055)
          enemy.x += ((playerX - enemy.x) / wd) * enemySpeed
          enemy.y += ((playerY - enemy.y) / wd) * enemySpeed
        }
        if (wd < 27.0 && shieldTicks == 0 && invulnerableTicks == 0) {
          playerHealth -= 1
          invulnerableTicks = 90
          enemy.x = 120.0 + random.nextInt(760)
          enemy.y = 130.0 + random.nextInt(470)
          statusMessage = "A SHADOW WISP DRAINED YOUR LIFE! USE A POWER OR DASH."
        }
      }
      w += 1
    }

    if (bossActive && bossHealth > 0 && bossStunTicks == 0) {
      val bd = distance(playerX, playerY, bossX, bossY)
      if (bd > 1.0) {
        bossX += ((playerX - bossX) / bd) * 0.62
        bossY += ((playerY - bossY) / bd) * 0.62
      }
      if (bd < 46.0 && shieldTicks == 0 && invulnerableTicks == 0) {
        playerHealth -= 1
        invulnerableTicks = 105
        statusMessage = "THE INFINITY GUARDIAN STRUCK! DASH AWAY OR USE A SHIELD."
      }
    }

    if (playerHealth <= 0) {
      playerHealth = 0
      gameOver = true
      statusMessage = "YOUR LIGHT HAS FADED. PRESS R TO RESTART."
    }
    arenaCanvas.repaint()
  }

  arenaCanvas.addKeyListener(new KeyAdapter {
    override def keyPressed(e: KeyEvent): Unit = {
      val code = e.getKeyCode
      pressedKeys += code
      if (code == KeyEvent.VK_SPACE) activateDash()
      if (code == KeyEvent.VK_F) castSelectedPower()
      if (code == KeyEvent.VK_Q) useShield()
      if (code == KeyEvent.VK_E) interactWithGate()
      if (code == KeyEvent.VK_1) selectedPower = 0
      if (code == KeyEvent.VK_2) selectedPower = 1
      if (code == KeyEvent.VK_3) selectedPower = 2
      if (code == KeyEvent.VK_4) selectedPower = 3
      if (code == KeyEvent.VK_P || code == KeyEvent.VK_ESCAPE) paused = !paused
      if (code == KeyEvent.VK_B) returnToBase()
      if (code == KeyEvent.VK_R && (gameOver || victory)) restartGame()
      arenaCanvas.repaint()
    }
    override def keyReleased(e: KeyEvent): Unit = {
      pressedKeys -= e.getKeyCode
    }
  })

  arenaCanvas.addMouseListener(new MouseAdapter {
    override def mousePressed(e: MouseEvent): Unit = {
      if (e.getButton == MouseEvent.BUTTON1 && !paused && !gameOver && !victory) {
        mouseTargetX = e.getX.toDouble
        mouseTargetY = e.getY.toDouble
        arenaCanvas.requestFocusInWindow()
      }
    }
  })

  def drawWorld(g2: Graphics2D): Unit = {
    val width = getCanvasWidth()
    val height = getCanvasHeight()
    g2.setPaint(new GradientPaint(0, 0, realmTopColors(realmIndex), 0, height, realmBottomColors(realmIndex)))
    g2.fillRect(0, 0, width, height)

    var i = 0
    while (i < 95) {
      val sx = (i * 157 + 43) % Math.max(1, width)
      val sy = (i * 89 + 23) % Math.max(1, height)
      val radius = 1 + (i % 3)
      if (i % 4 == 0) g2.setColor(new Color(255, 220, 150, 155))
      else if (i % 4 == 1) g2.setColor(new Color(153, 191, 255, 145))
      else if (i % 4 == 2) g2.setColor(new Color(199, 151, 255, 135))
      else g2.setColor(new Color(127, 245, 205, 135))
      g2.fillOval(sx, sy, radius, radius)
      i += 1
    }

    g2.setColor(new Color(8, 12, 25, 65))
    g2.fillOval(100, 110, width - 200, height - 165)
    g2.setColor(new Color(235, 225, 255, 24))
    g2.setStroke(new BasicStroke(2.0f))
    g2.drawOval(120, 128, width - 240, height - 205)
    g2.drawOval(165, 165, width - 330, height - 280)

    drawRealmLandmarks(g2, width, height)
    drawRelics(g2)
    drawWisps(g2)
    if (bossActive && bossHealth > 0) drawFinalBoss(g2)
    drawPlayer(g2)
    drawPortal(g2, width, height)
    drawHud(g2, width, height)

    if (paused) drawOverlay(g2, "REALM PAUSED", "Press P or ESC to continue")
    if (gameOver) drawOverlay(g2, "REALM LOST", "Press R to restart the final journey")
    if (victory) drawOverlay(g2, "FINAL AWAKENING!", "The Infinity Core shines again. Press R to play again.")
  }

  def getCanvasWidth(): Int = Math.max(1120, arenaCanvas.getWidth)
  def getCanvasHeight(): Int = Math.max(610, arenaCanvas.getHeight)

  def drawRealmLandmarks(g2: Graphics2D, width: Int, height: Int): Unit = {
    if (realmIndex == 0) {
      g2.setColor(new Color(36, 130, 91, 120))
      g2.fillOval(120, height - 190, 230, 130)
      g2.fillOval(690, height - 190, 260, 130)
      g2.setColor(new Color(120, 245, 170, 130))
      var t = 0
      while (t < 7) {
        g2.fillOval(145 + t * 26, height - 165 - (t % 3) * 18, 22, 30)
        t += 1
      }
    } else if (realmIndex == 1) {
      g2.setColor(new Color(89, 65, 130, 105))
      g2.fillRect(130, height - 230, 95, 160)
      g2.fillRect(270, height - 190, 80, 120)
      g2.setColor(new Color(190, 150, 255, 120))
      g2.drawLine(130, height - 230, 178, height - 290)
      g2.drawLine(225, height - 230, 178, height - 290)
      g2.drawLine(270, height - 190, 310, height - 245)
      g2.drawLine(350, height - 190, 310, height - 245)
    } else if (realmIndex == 2) {
      g2.setColor(new Color(71, 165, 220, 95))
      g2.fillOval(130, height - 200, 180, 70)
      g2.fillOval(700, height - 185, 250, 78)
      g2.setColor(new Color(130, 225, 255, 120))
      g2.drawLine(180, height - 250, 270, height - 140)
      g2.drawLine(760, height - 250, 840, height - 140)
    } else if (realmIndex == 3) {
      g2.setColor(new Color(135, 80, 55, 110))
      g2.fillPolygon(Array[Int](180, 260, 220), Array[Int](height - 85, height - 285, height - 350), 3)
      g2.fillPolygon(Array[Int](730, 840, 790), Array[Int](height - 80, height - 310, height - 390), 3)
      g2.setColor(new Color(255, 143, 77, 115))
      g2.fillOval(205, height - 240, 28, 45)
      g2.fillOval(778, height - 300, 25, 44)
    } else {
      g2.setColor(new Color(106, 91, 190, 90))
      g2.fillOval(120, height - 210, 300, 150)
      g2.fillOval(650, height - 225, 320, 165)
      g2.setColor(new Color(255, 215, 143, 135))
      g2.drawOval(370, 145, 380, 330)
      g2.drawOval(405, 175, 310, 270)
    }
  }

  def drawRelics(g2: Graphics2D): Unit = {
    var i = 0
    while (i < relics.length) {
      val relic = relics(i)
      if (!relic.collected) {
        val pulse = (tickCount % 18).toInt
        g2.setColor(new Color(255, 219, 135, 65))
        g2.fillOval(relic.x.toInt - 20 - pulse / 3, relic.y.toInt - 20 - pulse / 3, 40 + pulse / 2, 40 + pulse / 2)
        g2.setColor(new Color(255, 219, 136))
        val px = relic.x.toInt
        val py = relic.y.toInt
        val shape = new Polygon(Array[Int](px, px + 12, px, px - 12), Array[Int](py - 17, py, py + 17, py), 4)
        g2.fillPolygon(shape)
        g2.setColor(new Color(255, 249, 216))
        g2.drawPolygon(shape)
      }
      i += 1
    }
  }

  def drawWisps(g2: Graphics2D): Unit = {
    var i = 0
    while (i < wisps.length) {
      val enemy = wisps(i)
      if (enemy.stunTicks > 0) g2.setColor(new Color(145, 212, 255, 170))
      else g2.setColor(new Color(192, 122, 255, 185))
      g2.fillOval(enemy.x.toInt - 17, enemy.y.toInt - 19, 34, 38)
      g2.setColor(new Color(24, 20, 48))
      g2.fillOval(enemy.x.toInt - 8, enemy.y.toInt - 5, 5, 6)
      g2.fillOval(enemy.x.toInt + 3, enemy.y.toInt - 5, 5, 6)
      g2.setColor(new Color(229, 211, 255, 180))
      g2.drawArc(enemy.x.toInt - 13, enemy.y.toInt + 5, 26, 22, 180, 180)
      i += 1
    }
  }

  def drawPlayer(g2: Graphics2D): Unit = {
    if (shieldTicks > 0) {
      g2.setColor(new Color(125, 205, 255, 65))
      g2.fillOval(playerX.toInt - 29, playerY.toInt - 31, 58, 62)
      g2.setColor(new Color(145, 224, 255, 190))
      g2.setStroke(new BasicStroke(2.0f))
      g2.drawOval(playerX.toInt - 29, playerY.toInt - 31, 58, 62)
    }
    if (invulnerableTicks == 0 || tickCount % 8 < 4) {
      g2.setColor(new Color(27, 31, 59))
      g2.fillRoundRect(playerX.toInt - 12, playerY.toInt - 2, 24, 28, 9, 9)
      g2.setColor(new Color(255, 218, 177))
      g2.fillOval(playerX.toInt - 10, playerY.toInt - 21, 20, 20)
      g2.setColor(new Color(255, 210, 128))
      g2.setStroke(new BasicStroke(3.0f))
      g2.drawLine(playerX.toInt - 8, playerY.toInt + 22, playerX.toInt - 12, playerY.toInt + 31)
      g2.drawLine(playerX.toInt + 8, playerY.toInt + 22, playerX.toInt + 12, playerY.toInt + 31)
    }
  }

  def drawPortal(g2: Graphics2D, width: Int, height: Int): Unit = {
    val px = width - 66
    val py = height / 2
    val ready = currentRelics() >= 3 && (!bossActive || bossHealth <= 0)
    g2.setColor(if (ready) new Color(255, 214, 125, 95) else new Color(119, 126, 196, 65))
    g2.fillOval(px - 38, py - 72, 76, 144)
    g2.setStroke(new BasicStroke(6.0f))
    g2.setColor(if (ready) new Color(255, 220, 143) else new Color(146, 151, 220))
    g2.drawOval(px - 29, py - 63, 58, 126)
    g2.setColor(new Color(14, 20, 47, 190))
    g2.fillOval(px - 20, py - 53, 40, 106)
    g2.setColor(new Color(245, 237, 210))
    g2.setFont(new Font("SansSerif", Font.BOLD, 11))
    g2.drawString("PORTAL", px - 22, py + 88)
  }

  def drawFinalBoss(g2: Graphics2D): Unit = {
    g2.setColor(new Color(255, 108, 135, 55))
    g2.fillOval(bossX.toInt - 48, bossY.toInt - 50, 96, 100)
    g2.setColor(new Color(34, 23, 59))
    g2.fillOval(bossX.toInt - 31, bossY.toInt - 37, 62, 75)
    g2.setColor(new Color(255, 93, 119))
    g2.fillOval(bossX.toInt - 14, bossY.toInt - 10, 8, 8)
    g2.fillOval(bossX.toInt + 6, bossY.toInt - 10, 8, 8)
    g2.setColor(new Color(255, 220, 165))
    g2.setFont(new Font("SansSerif", Font.BOLD, 13))
    g2.drawString("INFINITY GUARDIAN", bossX.toInt - 67, bossY.toInt - 50)
    g2.setColor(new Color(47, 20, 39))
    g2.fillRoundRect(760, 112, 230, 16, 8, 8)
    g2.setColor(new Color(255, 91, 126))
    g2.fillRoundRect(760, 112, 230 * bossHealth / 12, 16, 8, 8)
  }

  def drawHud(g2: Graphics2D, width: Int, height: Int): Unit = {
    g2.setColor(new Color(5, 9, 24, 210))
    g2.fillRoundRect(15, 12, width - 30, 80, 16, 16)
    g2.setColor(new Color(248, 240, 222))
    g2.setFont(new Font("SansSerif", Font.BOLD, 18))
    g2.drawString("INFINITY REALM: FINAL AWAKENING", 31, 39)
    g2.setFont(new Font("SansSerif", Font.BOLD, 12))
    g2.setColor(new Color(255, 218, 148))
    g2.drawString("Hero: " + playerName + "   |   " + realmNames(realmIndex) + "   |   LEVEL " + level + "/10", 31, 67)
    g2.setColor(new Color(223, 235, 255))
    g2.drawString("Relics: " + currentRelics() + "/3   Total: " + totalRelics, 510, 38)
    g2.drawString("HP: " + playerHealth + "/6   Energy: " + energy + "/100", 510, 66)
    g2.setColor(new Color(255, 224, 155))
    g2.drawString("Credits: " + coins + "   Score: " + score, 790, 38)
    g2.setColor(powerColors(selectedPower))
    g2.drawString("POWER: " + powerNames(selectedPower) + " [1-4]", 790, 66)

    g2.setColor(new Color(4, 8, 20, 205))
    g2.fillRoundRect(18, height - 43, width - 36, 29, 9, 9)
    g2.setColor(new Color(238, 241, 255))
    g2.setFont(new Font("SansSerif", Font.PLAIN, 12))
    g2.drawString(statusMessage, 30, height - 24)
    g2.setColor(new Color(209, 218, 240))
    g2.setFont(new Font("SansSerif", Font.PLAIN, 11))
    g2.drawString("WASD MOVE  |  CLICK WALK  |  SPACE DASH  |  F POWER  |  Q SHIELD  |  E PORTAL  |  B BASE  |  P PAUSE", 240, height - 58)
  }

  def drawOverlay(g2: Graphics2D, heading: String, subheading: String): Unit = {
    g2.setColor(new Color(3, 5, 17, 205))
    g2.fillRect(0, 0, arenaCanvas.getWidth, arenaCanvas.getHeight)
    g2.setColor(new Color(255, 225, 165))
    g2.setFont(new Font("SansSerif", Font.BOLD, 38))
    val headingWidth = g2.getFontMetrics.stringWidth(heading)
    g2.drawString(heading, (arenaCanvas.getWidth - headingWidth) / 2, 300)
    g2.setColor(Color.WHITE)
    g2.setFont(new Font("SansSerif", Font.PLAIN, 17))
    val subWidth = g2.getFontMetrics.stringWidth(subheading)
    g2.drawString(subheading, (arenaCanvas.getWidth - subWidth) / 2, 345)
  }
}

// Run the complete Kojo script to open the game window.
InfinityRealmFinalAwakeningEvent10.main(Array[String]())