Code Sketch
Bixuu event PhantomsLostDimensionEvent2
Category: Programming
import java.awt.BasicStroke
import java.awt.BorderLayout
import java.awt.Color
import java.awt.Dimension
import java.awt.Font
import java.awt.GradientPaint
import java.awt.Graphics
import java.awt.Graphics2D
import java.awt.RenderingHints
import java.awt.event.ActionEvent
import java.awt.event.ActionListener
import java.awt.event.KeyAdapter
import java.awt.event.KeyEvent
import java.awt.event.MouseAdapter
import java.awt.event.MouseEvent
import javax.swing.BorderFactory
import javax.swing.Box
import javax.swing.BoxLayout
import javax.swing.JButton
import javax.swing.JFrame
import javax.swing.JLabel
import javax.swing.JPanel
import javax.swing.JTextField
import javax.swing.SwingConstants
import javax.swing.SwingUtilities
import javax.swing.Timer
import javax.swing.WindowConstants
import java.util.Random
object PhantomsLostDimensionEvent2 {
private val WINDOW_WIDTH = 960
private val WINDOW_HEIGHT = 700
private val FIELD_WIDTH = 920
private val FIELD_HEIGHT = 570
def main(args: Array[String]): Unit = {
SwingUtilities.invokeLater(new Runnable {
override def run(): Unit = createWindow()
})
}
private def createWindow(): Unit = {
val frame = new JFrame("INFINITY REALMS - PHANTOM'S LOST DIMENSION")
frame.setDefaultCloseOperation(WindowConstants.DISPOSE_ON_CLOSE)
frame.setSize(WINDOW_WIDTH, WINDOW_HEIGHT)
frame.setMinimumSize(new Dimension(820, 620))
frame.setLocationRelativeTo(null)
val cardLayout = new java.awt.CardLayout()
val root = new JPanel(cardLayout)
root.setPreferredSize(new Dimension(WINDOW_WIDTH, WINDOW_HEIGHT))
val loginPanel = new JPanel()
loginPanel.setLayout(new BoxLayout(loginPanel, BoxLayout.Y_AXIS))
loginPanel.setBackground(new Color(12, 10, 31))
loginPanel.setBorder(BorderFactory.createEmptyBorder(70, 50, 55, 50))
val title = new JLabel("PHANTOM'S LOST DIMENSION")
title.setFont(new Font("SansSerif", Font.BOLD, 34))
title.setForeground(new Color(221, 202, 255))
title.setAlignmentX(0.5f)
val season = new JLabel("INFINITY REALMS SEASON 2 | HAUNTED REALM")
season.setFont(new Font("SansSerif", Font.BOLD, 16))
season.setForeground(new Color(155, 132, 220))
season.setAlignmentX(0.5f)
val story = new JLabel("Find the lost memories, escape the Phantom Wisps, and open the Moon Gate.")
story.setFont(new Font("SansSerif", Font.PLAIN, 14))
story.setForeground(new Color(220, 216, 238))
story.setAlignmentX(0.5f)
val nameLabel = new JLabel("ENTER YOUR EXPLORER NAME")
nameLabel.setFont(new Font("SansSerif", Font.BOLD, 14))
nameLabel.setForeground(new Color(190, 175, 232))
nameLabel.setAlignmentX(0.5f)
val nameField = new JTextField("Explorer", 20)
nameField.setFont(new Font("SansSerif", Font.PLAIN, 18))
nameField.setHorizontalAlignment(SwingConstants.CENTER)
nameField.setMaximumSize(new Dimension(330, 42))
nameField.setAlignmentX(0.5f)
val startButton = makeButton("ENTER THE DIMENSION", new Color(103, 72, 174))
startButton.setAlignmentX(0.5f)
startButton.setMaximumSize(new Dimension(330, 46))
val hint = new JLabel("Offline adventure | No account or internet required")
hint.setFont(new Font("SansSerif", Font.PLAIN, 12))
hint.setForeground(new Color(133, 125, 163))
hint.setAlignmentX(0.5f)
loginPanel.add(Box.createVerticalGlue())
loginPanel.add(title)
loginPanel.add(Box.createVerticalStrut(12))
loginPanel.add(season)
loginPanel.add(Box.createVerticalStrut(26))
loginPanel.add(story)
loginPanel.add(Box.createVerticalStrut(48))
loginPanel.add(nameLabel)
loginPanel.add(Box.createVerticalStrut(10))
loginPanel.add(nameField)
loginPanel.add(Box.createVerticalStrut(18))
loginPanel.add(startButton)
loginPanel.add(Box.createVerticalStrut(24))
loginPanel.add(hint)
loginPanel.add(Box.createVerticalGlue())
root.add(loginPanel, "login")
var activeGame: GamePanel = null
val beginGame = new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = {
val entered = nameField.getText.trim
val playerName = if (entered.length == 0) "Explorer" else entered.take(18)
if (activeGame != null) {
activeGame.stopGame()
root.remove(activeGame)
}
activeGame = new GamePanel(playerName, new Runnable {
override def run(): Unit = {
if (activeGame != null) activeGame.stopGame()
cardLayout.show(root, "login")
nameField.requestFocusInWindow()
}
})
root.add(activeGame, "game")
cardLayout.show(root, "game")
activeGame.startGame()
}
}
startButton.addActionListener(beginGame)
nameField.addActionListener(beginGame)
frame.setContentPane(root)
frame.setVisible(true)
}
private def makeButton(text: String, color: Color): JButton = {
val button = new JButton(text)
button.setFont(new Font("SansSerif", Font.BOLD, 13))
button.setForeground(Color.WHITE)
button.setBackground(color)
button.setFocusPainted(false)
button.setBorder(BorderFactory.createEmptyBorder(10, 18, 10, 18))
button.setOpaque(true)
button
}
private class GamePanel(playerName: String, onBack: Runnable) extends JPanel(new BorderLayout()) {
private val field = new PlayField(playerName, onBack)
private val status = new JLabel("Collect 6 Lost Memories to unlock the Moon Gate.")
private val pauseButton = makeButton("PAUSE", new Color(76, 65, 112))
private val restartButton = makeButton("RESTART", new Color(80, 105, 135))
private val backButton = makeButton("BACK TO LOGIN", new Color(112, 65, 91))
private val bottom = new JPanel(new BorderLayout())
private val buttonRow = new JPanel()
private val timer = new Timer(30, new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = {
field.updateWorld()
status.setText(field.statusText)
field.repaint()
}
})
setBackground(new Color(13, 11, 32))
status.setForeground(new Color(225, 218, 245))
status.setFont(new Font("SansSerif", Font.BOLD, 13))
status.setBorder(BorderFactory.createEmptyBorder(8, 12, 8, 12))
status.setBackground(new Color(25, 21, 48))
status.setOpaque(true)
buttonRow.setBackground(new Color(20, 17, 40))
buttonRow.add(pauseButton)
buttonRow.add(restartButton)
buttonRow.add(backButton)
bottom.setBackground(new Color(20, 17, 40))
bottom.add(status, BorderLayout.CENTER)
bottom.add(buttonRow, BorderLayout.SOUTH)
add(field, BorderLayout.CENTER)
add(bottom, BorderLayout.SOUTH)
pauseButton.addActionListener(new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = {
field.togglePause()
if (field.isPaused) pauseButton.setText("RESUME")
else pauseButton.setText("PAUSE")
field.requestFocusInWindow()
}
})
restartButton.addActionListener(new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = {
field.resetWorld()
if (!timer.isRunning) timer.start()
pauseButton.setText("PAUSE")
field.requestFocusInWindow()
}
})
backButton.addActionListener(new ActionListener {
override def actionPerformed(e: ActionEvent): Unit = {
stopGame()
onBack.run()
}
})
def startGame(): Unit = {
timer.start()
field.requestFocusInWindow()
}
def stopGame(): Unit = {
timer.stop()
field.stopGame()
}
}
private class Shard(val x: Double, val y: Double, var found: Boolean)
private class PlayField(playerName: String, onBack: Runnable) extends JPanel {
private val random = new Random()
private val fieldW = FIELD_WIDTH
private val fieldH = FIELD_HEIGHT
private val layouts: Array[Array[(Int, Int)]] = Array(
Array((145, 135), (310, 110), (470, 190), (690, 135), (780, 330), (370, 420)),
Array((125, 310), (270, 150), (450, 100), (650, 220), (790, 420), (430, 450)),
Array((160, 160), (320, 360), (500, 130), (690, 390), (790, 170), (470, 470))
)
private var realm = 0
private var playerX = 75.0
private var playerY = 500.0
private var facing = 1
private var lives = 3
private var totalMemories = 0
private var realmMemories = 0
private var dashFrames = 0
private var dashCooldown = 0
private var lanternCooldown = 0
private var hitCooldown = 0
private var paused = false
private var lost = false
private var completed = false
private var message = "Find the glowing memories."
private var up = false
private var down = false
private var left = false
private var right = false
private var targetX = -1.0
private var targetY = -1.0
private var mouseWalking = false
private var interactRequested = false
private var shards: Array[Shard] = makeShards()
private var ghostX: Array[Double] = Array(760.0, 620.0, 825.0)
private var ghostY: Array[Double] = Array(120.0, 440.0, 300.0)
private var ghostStun: Array[Int] = Array(0, 0, 0)
private var frameCount = 0
setPreferredSize(new Dimension(fieldW, fieldH))
setBackground(new Color(12, 9, 29))
setFocusable(true)
setDoubleBuffered(true)
private def makeShards(): Array[Shard] = {
layouts(realm).map(p => new Shard(p._1.toDouble, p._2.toDouble, false))
}
def statusText: String = {
if (completed) "Dimension restored! You awakened the Moon Gate."
else if (lost) "The dimension has trapped you. Press RESTART to try again."
else "Realm " + (realm + 1) + "/3 | Memories " + realmMemories + "/6 | Total " + totalMemories + " | Hearts " + lives
}
def isPaused: Boolean = paused
def togglePause(): Unit = {
paused = !paused
message = if (paused) "Paused - press RESUME to continue." else "Keep moving, " + playerName + "!"
repaint()
}
def resetWorld(): Unit = {
realm = 0
playerX = 75.0
playerY = 500.0
lives = 3
totalMemories = 0
realmMemories = 0
dashFrames = 0
dashCooldown = 0
lanternCooldown = 0
hitCooldown = 0
paused = false
lost = false
completed = false
message = "Find 6 Lost Memories and reach the Moon Gate."
up = false
down = false
left = false
right = false
mouseWalking = false
shards = makeShards()
resetGhosts()
requestFocusInWindow()
repaint()
}
def stopGame(): Unit = {
paused = true
}
private def resetGhosts(): Unit = {
ghostX = Array(760.0, 620.0, 825.0)
ghostY = Array(120.0, 440.0, 300.0)
ghostStun = Array(0, 0, 0)
}
addKeyListener(new KeyAdapter {
override def keyPressed(e: KeyEvent): Unit = {
e.getKeyCode match {
case KeyEvent.VK_W | KeyEvent.VK_UP => up = true
case KeyEvent.VK_S | KeyEvent.VK_DOWN => down = true
case KeyEvent.VK_A | KeyEvent.VK_LEFT => left = true
case KeyEvent.VK_D | KeyEvent.VK_RIGHT => right = true
case KeyEvent.VK_SPACE =>
if (dashCooldown <= 0 && !paused && !lost && !completed) {
dashFrames = 12
dashCooldown = 70
message = "Moon Dash!"
}
case KeyEvent.VK_F =>
if (lanternCooldown <= 0 && !paused && !lost && !completed) {
var i = 0
while (i < ghostStun.length) {
ghostStun(i) = 90
i += 1
}
lanternCooldown = 150
message = "Lantern pulse! The Phantom Wisps are stunned."
}
case KeyEvent.VK_E => interactRequested = true
case KeyEvent.VK_P => togglePause()
case KeyEvent.VK_R => resetWorld()
case KeyEvent.VK_ESCAPE => onBack.run()
case _ =>
}
}
override def keyReleased(e: KeyEvent): Unit = {
e.getKeyCode match {
case KeyEvent.VK_W | KeyEvent.VK_UP => up = false
case KeyEvent.VK_S | KeyEvent.VK_DOWN => down = false
case KeyEvent.VK_A | KeyEvent.VK_LEFT => left = false
case KeyEvent.VK_D | KeyEvent.VK_RIGHT => right = false
case _ =>
}
}
})
addMouseListener(new MouseAdapter {
override def mousePressed(e: MouseEvent): Unit = {
targetX = e.getX.toDouble
targetY = e.getY.toDouble
mouseWalking = true
requestFocusInWindow()
}
})
def updateWorld(): Unit = {
if (paused || lost || completed) return
frameCount += 1
if (dashCooldown > 0) dashCooldown -= 1
if (lanternCooldown > 0) lanternCooldown -= 1
if (hitCooldown > 0) hitCooldown -= 1
if (dashFrames > 0) dashFrames -= 1
var dx = 0.0
var dy = 0.0
if (left) dx -= 1.0
if (right) dx += 1.0
if (up) dy -= 1.0
if (down) dy += 1.0
if (mouseWalking && dx == 0.0 && dy == 0.0) {
val mx = targetX - playerX
val my = targetY - playerY
val distance = math.sqrt(mx * mx + my * my)
if (distance < 8.0) mouseWalking = false
else {
dx = mx / distance
dy = my / distance
}
}
val length = math.sqrt(dx * dx + dy * dy)
if (length > 0.0) {
val candyBoost = math.min(totalMemories.toDouble * 0.035, 1.0)
val baseSpeed = 3.1 + candyBoost
val moveSpeed = if (dashFrames > 0) baseSpeed * 2.7 else baseSpeed
playerX += (dx / length) * moveSpeed
playerY += (dy / length) * moveSpeed
if (dx > 0) facing = 1
if (dx < 0) facing = -1
}
playerX = math.max(28.0, math.min(fieldW - 28.0, playerX))
playerY = math.max(92.0, math.min(fieldH - 28.0, playerY))
var s = 0
while (s < shards.length) {
if (!shards(s).found && distanceBetween(playerX, playerY, shards(s).x, shards(s).y) < 25.0) {
shards(s).found = true
realmMemories += 1
totalMemories += 1
message = "Lost Memory collected! Your movement is getting faster."
}
s += 1
}
var i = 0
while (i < ghostX.length) {
if (ghostStun(i) > 0) ghostStun(i) -= 1
else {
val gx = playerX - ghostX(i)
val gy = playerY - ghostY(i)
val distance = math.sqrt(gx * gx + gy * gy)
if (distance > 1.0) {
val ghostSpeed = 0.65 + realm.toDouble * 0.18 + (if (i == 0) 0.16 else 0.0)
ghostX(i) += (gx / distance) * ghostSpeed
ghostY(i) += (gy / distance) * ghostSpeed
}
if (distance < 25.0 && hitCooldown <= 0) {
lives -= 1
hitCooldown = 85
playerX = 75.0
playerY = 500.0
message = "A Phantom Wisp caught you! You lost one heart."
if (lives <= 0) {
lost = true
message = "Lost in the Dimension! Press RESTART to try again."
}
}
}
i += 1
}
if (interactRequested) {
interactRequested = false
if (realmMemories >= 6 && distanceBetween(playerX, playerY, fieldW - 90.0, 118.0) < 68.0) {
advanceRealm()
} else if (realmMemories < 6) {
message = "The Moon Gate is sealed. Find all 6 Lost Memories first."
} else {
message = "The Moon Gate is open! Move close and press E."
}
}
if (realmMemories >= 6 && distanceBetween(playerX, playerY, fieldW - 90.0, 118.0) < 48.0) {
advanceRealm()
}
}
private def distanceBetween(x1: Double, y1: Double, x2: Double, y2: Double): Double = {
val dx = x1 - x2
val dy = y1 - y2
math.sqrt(dx * dx + dy * dy)
}
private def advanceRealm(): Unit = {
if (realm < 2) {
realm += 1
realmMemories = 0
playerX = 75.0
playerY = 500.0
shards = makeShards()
resetGhosts()
message = "Welcome to " + realmName + ". Find 6 more memories."
} else {
completed = true
message = "You restored the Phantom Dimension! The Moon Gate is healed."
}
}
private def realmName: String = {
realm match {
case 0 => "The Forgotten Village"
case 1 => "The Whispering Forest"
case _ => "The Phantom Citadel"
}
}
override def paintComponent(graphics: Graphics): Unit = {
super.paintComponent(graphics)
val g = graphics.create().asInstanceOf[Graphics2D]
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON)
val w = getWidth
val h = getHeight
drawBackground(g, w, h)
drawRuins(g, w, h)
drawPortal(g, w, h)
drawShards(g)
drawGhosts(g)
drawPlayer(g)
drawHud(g, w)
if (paused) drawOverlay(g, w, h, "PAUSED", "Press P or RESUME to continue")
if (lost) drawOverlay(g, w, h, "LOST IN THE DIMENSION", "Press RESTART to begin again")
if (completed) drawOverlay(g, w, h, "PHANTOM DIMENSION RESTORED!", "You awakened the Moon Gate. Congratulations, " + playerName + "!")
g.dispose()
}
private def drawBackground(g: Graphics2D, w: Int, h: Int): Unit = {
val top = realm match {
case 0 => new Color(17, 14, 43)
case 1 => new Color(10, 31, 42)
case _ => new Color(34, 15, 45)
}
val bottom = realm match {
case 0 => new Color(48, 25, 66)
case 1 => new Color(18, 63, 65)
case _ => new Color(75, 27, 62)
}
g.setPaint(new GradientPaint(0, 0, top, 0, h, bottom))
g.fillRect(0, 0, w, h)
var i = 0
while (i < 85) {
val sx = (i * 97 + 31) % math.max(1, w)
val sy = (i * 53 + 17) % math.max(1, h)
val radius = if (i % 7 == 0) 3 else 2
g.setColor(new Color(220, 213, 255, 100 + (i % 5) * 25))
g.fillOval(sx, sy, radius, radius)
i += 1
}
g.setColor(new Color(215, 211, 244, 190))
g.fillOval(w - 175, 45, 76, 76)
g.setColor(new Color(top.getRed, top.getGreen, top.getBlue, 90))
g.fillOval(w - 155, 35, 76, 76)
g.setColor(new Color(18, 17, 38, 180))
val hill1 = new java.awt.Polygon()
hill1.addPoint(0, h - 145)
hill1.addPoint(w / 4, h - 230)
hill1.addPoint(w / 2, h - 150)
hill1.addPoint(w * 3 / 4, h - 235)
hill1.addPoint(w, h - 145)
hill1.addPoint(w, h)
hill1.addPoint(0, h)
g.fillPolygon(hill1)
g.setColor(new Color(14, 13, 31, 220))
g.fillRect(0, h - 58, w, 58)
}
private def drawRuins(g: Graphics2D, w: Int, h: Int): Unit = {
var i = 0
while (i < 6) {
val x = 45 + i * 155
val y = h - 112 - (i % 2) * 12
g.setColor(new Color(39, 35, 62))
g.fillRoundRect(x, y, 42, 75, 12, 12)
g.setColor(new Color(93, 76, 118))
g.drawRoundRect(x, y, 42, 75, 12, 12)
g.setColor(new Color(148, 130, 178, 150))
g.drawArc(x + 10, y + 12, 22, 27, 0, 180)
i += 1
}
g.setColor(new Color(22, 28, 40, 210))
g.fillRect(0, h - 90, w, 32)
}
private def drawPortal(g: Graphics2D, w: Int, h: Int): Unit = {
val x = w - 90
val y = 118
val open = realmMemories >= 6
val glow = if (open) new Color(109, 244, 215, 85) else new Color(119, 91, 160, 70)
g.setColor(glow)
g.fillOval(x - 47, y - 48, 94, 96)
g.setColor(if (open) new Color(133, 255, 221) else new Color(130, 112, 162))
g.setStroke(new BasicStroke(5.0f))
g.drawOval(x - 37, y - 40, 74, 82)
g.setStroke(new BasicStroke(2.0f))
g.drawOval(x - 26, y - 29, 52, 60)
g.setColor(new Color(14, 9, 31, 225))
g.fillOval(x - 19, y - 24, 38, 52)
g.setColor(if (open) Color.WHITE else new Color(173, 158, 197))
g.setFont(new Font("SansSerif", Font.BOLD, 11))
g.drawString(if (open) "MOON GATE" else "SEALED", x - 31, y + 58)
}
private def drawShards(g: Graphics2D): Unit = {
var i = 0
while (i < shards.length) {
if (!shards(i).found) {
val x = shards(i).x.toInt
val y = shards(i).y.toInt
val bob = (math.sin((frameCount + i * 13).toDouble * 0.08) * 5.0).toInt
g.setColor(new Color(170, 115, 255, 70))
g.fillOval(x - 17, y - 17 + bob, 34, 34)
val crystal = new java.awt.Polygon()
crystal.addPoint(x, y - 15 + bob)
crystal.addPoint(x + 10, y + bob)
crystal.addPoint(x, y + 15 + bob)
crystal.addPoint(x - 10, y + bob)
g.setColor(new Color(182, 143, 255))
g.fillPolygon(crystal)
g.setColor(Color.WHITE)
g.drawLine(x, y - 11 + bob, x, y + 10 + bob)
}
i += 1
}
}
private def drawGhosts(g: Graphics2D): Unit = {
var i = 0
while (i < ghostX.length) {
val x = ghostX(i).toInt
val y = ghostY(i).toInt
val bob = (math.sin((frameCount + i * 20).toDouble * 0.06) * 5.0).toInt
val stunned = ghostStun(i) > 0
val bodyColor = if (stunned) new Color(119, 236, 255, 220) else new Color(205, 186, 244, 225)
g.setColor(new Color(bodyColor.getRed, bodyColor.getGreen, bodyColor.getBlue, 55))
g.fillOval(x - 25, y - 25 + bob, 50, 50)
g.setColor(bodyColor)
g.fillOval(x - 16, y - 19 + bob, 32, 34)
val tail = new java.awt.Polygon()
tail.addPoint(x - 15, y + 3 + bob)
tail.addPoint(x - 8, y + 19 + bob)
tail.addPoint(x, y + 10 + bob)
tail.addPoint(x + 8, y + 19 + bob)
tail.addPoint(x + 16, y + 3 + bob)
g.fillPolygon(tail)
g.setColor(new Color(53, 40, 84))
g.fillOval(x - 8, y - 5 + bob, 5, 7)
g.fillOval(x + 3, y - 5 + bob, 5, 7)
i += 1
}
}
private def drawPlayer(g: Graphics2D): Unit = {
val x = playerX.toInt
val y = playerY.toInt
if (hitCooldown <= 0 || (hitCooldown / 5) % 2 == 0) {
g.setColor(new Color(80, 210, 255, 75))
g.fillOval(x - 22, y - 22, 44, 44)
}
g.setColor(new Color(38, 105, 154))
g.fillOval(x - 12, y - 17, 24, 24)
g.setColor(new Color(45, 55, 96))
val cloak = new java.awt.Polygon()
cloak.addPoint(x - 13, y - 4)
cloak.addPoint(x + 13, y - 4)
cloak.addPoint(x + 18, y + 18)
cloak.addPoint(x - 18, y + 18)
g.fillPolygon(cloak)
g.setColor(new Color(223, 240, 255))
g.fillOval(x - 7, y - 12, 4, 5)
g.fillOval(x + 3, y - 12, 4, 5)
g.setColor(new Color(135, 239, 255))
g.fillOval(x + facing * 10 - 4, y + 1, 9, 9)
if (dashFrames > 0) {
g.setColor(new Color(119, 228, 255, 120))
g.drawOval(x - 27, y - 27, 54, 54)
}
}
private def drawHud(g: Graphics2D, w: Int): Unit = {
g.setColor(new Color(8, 7, 22, 195))
g.fillRoundRect(12, 10, w - 24, 62, 18, 18)
g.setColor(new Color(232, 222, 255))
g.setFont(new Font("SansSerif", Font.BOLD, 17))
g.drawString("PHANTOM'S LOST DIMENSION", 28, 34)
g.setFont(new Font("SansSerif", Font.PLAIN, 12))
g.setColor(new Color(190, 178, 222))
g.drawString("Explorer: " + playerName + " | " + realmName, 28, 55)
g.setColor(new Color(255, 221, 151))
g.drawString("MEMORIES " + realmMemories + "/6", w - 245, 34)
g.setColor(new Color(255, 153, 186))
g.drawString("HEARTS " + lives, w - 245, 55)
g.setColor(new Color(202, 191, 230))
g.drawString(message, 28, 91)
}
private def drawOverlay(g: Graphics2D, w: Int, h: Int, heading: String, subheading: String): Unit = {
g.setColor(new Color(5, 4, 17, 190))
g.fillRect(0, 0, w, h)
g.setColor(new Color(228, 212, 255))
g.setFont(new Font("SansSerif", Font.BOLD, 29))
val fm = g.getFontMetrics
g.drawString(heading, (w - fm.stringWidth(heading)) / 2, h / 2 - 12)
g.setFont(new Font("SansSerif", Font.PLAIN, 15))
val fm2 = g.getFontMetrics
g.setColor(new Color(211, 199, 235))
g.drawString(subheading, (w - fm2.stringWidth(subheading)) / 2, h / 2 + 23)
}
}
}
PhantomsLostDimensionEvent2.main(Array[String]())