From 5dd43b6f9de90140a54080d2a8056966f29da1b8 Mon Sep 17 00:00:00 2001 From: Maurice Date: Fri, 12 Dec 2025 12:26:32 +0100 Subject: [PATCH] added game over screen --- assets/META-INF/MANIFEST.MF | 3 + src/de/miaurizius/jgame2d/core/GamePanel.java | 13 +++ src/de/miaurizius/jgame2d/core/UI.java | 85 ++++++++++++------- .../jgame2d/core/enums/GameState.java | 1 + .../jgame2d/core/handlers/KeyHandler.java | 59 +++++++------ .../jgame2d/core/handlers/Sound.java | 1 + src/de/miaurizius/jgame2d/entity/Player.java | 17 +++- 7 files changed, 123 insertions(+), 56 deletions(-) create mode 100644 assets/META-INF/MANIFEST.MF diff --git a/assets/META-INF/MANIFEST.MF b/assets/META-INF/MANIFEST.MF new file mode 100644 index 0000000..0f66352 --- /dev/null +++ b/assets/META-INF/MANIFEST.MF @@ -0,0 +1,3 @@ +Manifest-Version: 1.0 +Main-Class: de.miaurizius.jgame2d.core.Boot + diff --git a/src/de/miaurizius/jgame2d/core/GamePanel.java b/src/de/miaurizius/jgame2d/core/GamePanel.java index 28ed7b9..bd65f7b 100644 --- a/src/de/miaurizius/jgame2d/core/GamePanel.java +++ b/src/de/miaurizius/jgame2d/core/GamePanel.java @@ -241,5 +241,18 @@ public class GamePanel extends JPanel implements Runnable { fScreenWidth = Boot.window.getWidth(); fScreenHeight = Boot.window.getHeight(); } + public void retry() { + player.setDefaultPositions(); + player.restoreLife(); + assetSetter.setNPC(); + assetSetter.setMonster(); + } + public void restart() { + player.setDefaultValues(); + assetSetter.setObject(); + assetSetter.setNPC(); + assetSetter.setMonster(); + assetSetter.setITiles(); + } } diff --git a/src/de/miaurizius/jgame2d/core/UI.java b/src/de/miaurizius/jgame2d/core/UI.java index 0dd8191..a297a47 100644 --- a/src/de/miaurizius/jgame2d/core/UI.java +++ b/src/de/miaurizius/jgame2d/core/UI.java @@ -47,26 +47,17 @@ public class UI { if(panel.gameState == null) return; switch (panel.gameState) { - case GameState.PLAY: - drawPlayScreen(); - break; - case GameState.PAUSE: - drawPauseScreen(); - break; - case GameState.DIALOGUE: - drawDialogueScreen(); - break; - case TITLE: - drawTitleScreen(); - break; - case CHARACTER: - drawCharacterScreen(); - break; + case GameState.PLAY -> drawPlayScreen(); + case GameState.PAUSE -> drawPauseScreen(); + case GameState.DIALOGUE -> drawDialogueScreen(); + case TITLE -> drawTitleScreen(); + case CHARACTER -> drawCharacterScreen(); + case GAMEOVER -> drawGameOverScreen(); } } // HUD - public void drawPlayerLife() { + private void drawPlayerLife() { int x = panel.tileSize / 2; int y = panel.tileSize / 2; int i = 0; @@ -91,7 +82,7 @@ public class UI { x += panel.tileSize; } } - public void drawMessages() { + private void drawMessages() { int messageX = panel.tileSize; int messageY = panel.tileSize*4; graphics2d.setFont(graphics2d.getFont().deriveFont(Font.BOLD, 32F)); @@ -112,7 +103,7 @@ public class UI { } } } - public void drawCharStats() { + private void drawCharStats() { // DRAW FRAME final int frameX = panel.tileSize*2; final int frameY = panel.tileSize; @@ -159,7 +150,7 @@ public class UI { textY += panel.tileSize; graphics2d.drawImage(panel.player.currentShield.down1, tailX - panel.tileSize, textY-14, null); } - public void drawInventory() { + private void drawInventory() { // DRAW FRAME int frameX = panel.tileSize*12; int frameY = panel.tileSize; @@ -221,7 +212,7 @@ public class UI { } // GAME STATES - public void drawPauseScreen() { + private void drawPauseScreen() { graphics2d.setColor(Color.white); graphics2d.setFont(graphics2d.getFont().deriveFont(32F)); @@ -240,7 +231,7 @@ public class UI { } panel.keyH.spacePressed = false; } - public void drawDialogueScreen() { + private void drawDialogueScreen() { drawPlayerLife(); // WINDOW int x = panel.tileSize*2; @@ -258,7 +249,7 @@ public class UI { y += 40; } } - public void drawTitleScreen() { + private void drawTitleScreen() { graphics2d.setColor(new Color(0, 0, 0)); graphics2d.fillRect(0, 0, panel.screenWidth, panel.screenHeight); @@ -296,27 +287,59 @@ public class UI { graphics2d.drawString(text, x, y); if(commandNum == 2) graphics2d.drawString(">", x-panel.tileSize, y); } - public void drawCharacterScreen() { + private void drawCharacterScreen() { drawCharStats(); drawInventory(); } - public void drawPlayScreen() { + private void drawPlayScreen() { drawPlayerLife(); drawMessages(); } + private void drawGameOverScreen() { + graphics2d.setColor(new Color(0,0,0, 150)); + graphics2d.fillRect(0, 0, panel.screenWidth, panel.screenHeight); + + int x, y; + String text; + graphics2d.setFont(graphics2d.getFont().deriveFont(Font.BOLD, 110F)); + text = "GAME OVER"; + // SHADOW + graphics2d.setColor(Color.black); + x = getCenteredX(text); + y = panel.tileSize*3; + graphics2d.drawString(text, x, y); + + // MAIN TEXT + graphics2d.setColor(Color.white); + graphics2d.drawString(text, x-4, y-4); + + // OPTIONS + graphics2d.setFont(graphics2d.getFont().deriveFont(50F)); + text = "Retry"; + x = getCenteredX(text); + y += panel.tileSize*4; + graphics2d.drawString(text, x, y); + if(commandNum == 0) graphics2d.drawString(">", x-panel.tileSize, y); + + text = "Return to title"; + x = getCenteredX(text); + y += 55; + graphics2d.drawString(text, x, y); + if(commandNum == 1) graphics2d.drawString(">", x-panel.tileSize, y); + } // UTILITY - public void drawSubWindow(int x, int y, int width, int height) { + private void drawSubWindow(int x, int y, int width, int height) { graphics2d.setColor(new Color(0,0,0,210)); graphics2d.fillRoundRect(x, y, width, height, 35, 35); graphics2d.setColor(new Color(255,255,255)); graphics2d.setStroke(new BasicStroke(5)); graphics2d.drawRoundRect(x+5, y+5, width-10, height-10, 25, 25); } - public int getCenteredX(String text) { + private int getCenteredX(String text) { return panel.screenWidth / 2 - (int) graphics2d.getFontMetrics().getStringBounds(text, graphics2d).getWidth() / 2; } - public int getAlignedToRightX(String text, int tailX) { + private int getAlignedToRightX(String text, int tailX) { return tailX - (int) graphics2d.getFontMetrics().getStringBounds(text, graphics2d).getWidth(); } public int getItemIndex() { @@ -328,7 +351,7 @@ public class UI { } // OPTIONS UI - public void optionsTop(int frameX, int frameY) { + private void optionsTop(int frameX, int frameY) { int textX, textY; String title = "Options"; textX = getCenteredX(title); @@ -412,7 +435,7 @@ public class UI { panel.config.save(); } - public void optionsControls(int frameX, int frameY) { + private void optionsControls(int frameX, int frameY) { int textX; int textY; @@ -445,7 +468,7 @@ public class UI { graphics2d.drawString(">", textX-25, textY); if(panel.keyH.spacePressed) optionState = OptionState.OVERVIEW; } - public void optionsFSNotify(int frameX, int frameY) { + private void optionsFSNotify(int frameX, int frameY) { int textX = frameX + panel.tileSize; int textY = frameY + panel.tileSize*3; @@ -464,7 +487,7 @@ public class UI { } } - public void optionsQuitNotify(int frameX, int frameY) { + private void optionsQuitNotify(int frameX, int frameY) { int textX = frameX + panel.tileSize; int textY = frameY + panel.tileSize*3; diff --git a/src/de/miaurizius/jgame2d/core/enums/GameState.java b/src/de/miaurizius/jgame2d/core/enums/GameState.java index 287b686..844e900 100644 --- a/src/de/miaurizius/jgame2d/core/enums/GameState.java +++ b/src/de/miaurizius/jgame2d/core/enums/GameState.java @@ -7,5 +7,6 @@ public enum GameState { DIALOGUE, TITLE, CHARACTER, + GAMEOVER, } diff --git a/src/de/miaurizius/jgame2d/core/handlers/KeyHandler.java b/src/de/miaurizius/jgame2d/core/handlers/KeyHandler.java index 87bbd38..00848a2 100644 --- a/src/de/miaurizius/jgame2d/core/handlers/KeyHandler.java +++ b/src/de/miaurizius/jgame2d/core/handlers/KeyHandler.java @@ -18,7 +18,7 @@ public class KeyHandler implements KeyListener { } // STATE SPECIFIC KEYBIND CONFIGURATION - public void handleTitle(int code) { + private void handleTitle(int code) { switch (code) { case KeyEvent.VK_UP -> { if(panel.ui.commandNum != 0) panel.ui.commandNum--; @@ -42,7 +42,7 @@ public class KeyHandler implements KeyListener { } } } - public void handlePlay(int code) { + private void handlePlay(int code) { switch (code) { // CONTROLS case KeyEvent.VK_W, KeyEvent.VK_UP -> upPressed = true; @@ -65,7 +65,7 @@ public class KeyHandler implements KeyListener { case KeyEvent.VK_C -> panel.gameState = GameState.CHARACTER; } } - public void handlePause(int code) { + private void handlePause(int code) { if(code == KeyEvent.VK_SPACE) spacePressed = true; int maxCommandNum = 0; @@ -115,13 +115,13 @@ public class KeyHandler implements KeyListener { if(code == KeyEvent.VK_ESCAPE) if(panel.ui.optionState == UI.OptionState.OVERVIEW) panel.gameState = GameState.PLAY; else panel.ui.optionState = UI.OptionState.OVERVIEW; } - public void handleDialogue(int code) { + private void handleDialogue(int code) { // EXIT STATE if (code == KeyEvent.VK_SPACE) { panel.gameState = GameState.PLAY; } } - public void handleCharacter(int code) throws InterruptedException { + private void handleCharacter(int code) { switch (code) { case KeyEvent.VK_UP: if(panel.ui.slotRow == 0) break; @@ -157,6 +157,30 @@ public class KeyHandler implements KeyListener { break; } } + private void handleGameOver(int code) { + switch(code) { + case KeyEvent.VK_UP: + if (panel.ui.commandNum <= 0) break; + panel.ui.commandNum--; + panel.playSE(9); + break; + case KeyEvent.VK_DOWN: + if (panel.ui.commandNum >= 1) break; + panel.ui.commandNum++; + panel.playSE(9); + break; + case KeyEvent.VK_SPACE: + if(panel.ui.commandNum == 0) { + panel.gameState = GameState.PLAY; + panel.retry(); + } + if(panel.ui.commandNum == 1) { + panel.gameState = GameState.TITLE; + panel.restart(); + panel.stopMusic(); + } + } + } // KEY-LISTENER @Override @@ -165,25 +189,12 @@ public class KeyHandler implements KeyListener { public void keyPressed(KeyEvent e) { int code = e.getKeyCode(); switch(panel.gameState) { - case PLAY: - handlePlay(code); - break; - case DIALOGUE: - handleDialogue(code); - break; - case TITLE: - handleTitle(code); - break; - case PAUSE: - handlePause(code); - break; - case CHARACTER: - try { - handleCharacter(code); - } catch (InterruptedException ex) { - throw new RuntimeException(ex); - } - break; + case PLAY -> handlePlay(code); + case DIALOGUE -> handleDialogue(code); + case TITLE -> handleTitle(code); + case PAUSE -> handlePause(code); + case CHARACTER -> handleCharacter(code); + case GAMEOVER -> handleGameOver(code); } } @Override diff --git a/src/de/miaurizius/jgame2d/core/handlers/Sound.java b/src/de/miaurizius/jgame2d/core/handlers/Sound.java index 40feeed..18bdac6 100644 --- a/src/de/miaurizius/jgame2d/core/handlers/Sound.java +++ b/src/de/miaurizius/jgame2d/core/handlers/Sound.java @@ -32,6 +32,7 @@ public class Sound { load(9, "assets/sounds/cursor.wav"); load(10, "assets/sounds/burning.wav"); load(11, "assets/sounds/cuttree.wav"); + load(12, "assets/sounds/gameover.wav"); } @Deprecated diff --git a/src/de/miaurizius/jgame2d/entity/Player.java b/src/de/miaurizius/jgame2d/entity/Player.java index 5f7c1ed..fbcc9e8 100644 --- a/src/de/miaurizius/jgame2d/entity/Player.java +++ b/src/de/miaurizius/jgame2d/entity/Player.java @@ -125,6 +125,11 @@ public class Player extends Entity { invincible = false; invincibleCount = 0; } + + if(life <= 0) { + panel.gameState = GameState.GAMEOVER; + panel.playSE(12); + } } // INTERACTION @@ -241,7 +246,7 @@ public class Player extends Entity { super.speak(); } - // BACKGROUND CHECKS + // BACKGROUND JOBS public void checkLevelUp() { if(exp < nextLevelExp) return; level++; @@ -274,6 +279,15 @@ public class Player extends Entity { inventory.remove(itemIndex); } } + public void setDefaultPositions() { + worldX = panel.tileSize * 23; + worldY = panel.tileSize * 21; + direction = Direction.DOWN; + } + public void restoreLife() { + life = maxLife; + invincible = false; + } // SETTING THINGS UP public void setDefaultValues() { @@ -298,6 +312,7 @@ public class Player extends Entity { defense = getDefense(); // INVENTORY + inventory.clear(); inventory.add(currentWeapon); inventory.add(currentShield); }