192 lines
8.5 KiB
Java
192 lines
8.5 KiB
Java
import javax.swing.*;
|
||
import java.awt.*;
|
||
|
||
/**
|
||
* LvlManager
|
||
*
|
||
* Builds each level as its own GameFields panel and registers them
|
||
* with the root CardLayout container. The level-select screen lives
|
||
* here; clicking a level button in MainMenu calls
|
||
* gm.levelStart(name1, name2, "LEVEL1") which tells CardLayout to
|
||
* flip to that card.
|
||
*/
|
||
public class LvlManager extends JPanel {
|
||
|
||
public JPanel container;
|
||
private CardLayout cardLayout;
|
||
|
||
public LvlManager(GameFields gm) {
|
||
|
||
setLayout(null);
|
||
setPreferredSize(new Dimension(640, 360));
|
||
setBackground(new Color(20, 20, 40));
|
||
|
||
// ── "Go Back" button ─────────────────────────────────────────────
|
||
JButton back = new JButton("Go Back");
|
||
back.setFont(new Font("Arial", Font.BOLD, 12));
|
||
back.setForeground(Color.WHITE);
|
||
back.setBackground(new Color(60, 60, 100));
|
||
back.setBorder(BorderFactory.createLineBorder(new Color(120, 120, 200), 1));
|
||
back.setFocusPainted(false);
|
||
back.setBounds(275, 318, 90, 28);
|
||
add(back);
|
||
back.addActionListener(e -> cardLayout.show(container, "MENU"));
|
||
|
||
// ── Build individual level panels ─────────────────────────────────
|
||
// Each level is a fresh GameFields; we configure its elements here,
|
||
// add it to the shared container under its card name, and wire up
|
||
// the setContainer call so the in-game "back" path works too.
|
||
|
||
buildLevel1(gm);
|
||
buildLevel2(gm);
|
||
buildLevel3(gm);
|
||
}
|
||
|
||
// =========================================================================
|
||
// LEVEL 1 — "The Crossing" (Easy)
|
||
// =========================================================================
|
||
private void buildLevel1(GameFields gm) {
|
||
GameFields level1 = new GameFields();
|
||
|
||
// Players
|
||
level1.placePlayer(level1.bear, 50, 270);
|
||
level1.placePlayer(level1.seal, 560, 270);
|
||
|
||
// Walls (x, y — default 120×20 size assigned in GameFields constructor)
|
||
level1.placeWall(level1.walls.get(0), 0, 318); // left ground
|
||
level1.placeWall(level1.walls.get(1), 340, 318); // right ground (gap at 260-340)
|
||
level1.placeWall(level1.walls.get(2), 270, 250); // center ledge
|
||
level1.placeWall(level1.walls.get(3), 80, 220); // left raised platform
|
||
level1.placeWall(level1.walls.get(4), 490, 220); // right raised platform
|
||
|
||
// Rocks
|
||
level1.placeRock(level1.rocks.get(0), 258, 288); // bridges the ground gap
|
||
|
||
// Fluids (index 0-2 = bear-fluid / dangerous to bear;
|
||
// index 3-5 = seal-fluid / dangerous to seal)
|
||
level1.placeFluid(level1.fluids.get(0), 430, 298); // bear-fluid on right path
|
||
level1.placeFluid(level1.fluids.get(3), 140, 298); // seal-fluid on left path
|
||
|
||
// Gust
|
||
level1.placeGust(level1.windBoxes.get(0), 60, 130);
|
||
|
||
// Win doors (bear door on right side, seal door on left side — they must cross)
|
||
level1.placeDoors(580, 240, 20, 240);
|
||
|
||
// Wire up navigation so level1 can also switch cards
|
||
level1.addKeyListener(new java.awt.event.KeyAdapter() {
|
||
@Override public void keyPressed(java.awt.event.KeyEvent e) {
|
||
if (e.getKeyCode() == java.awt.event.KeyEvent.VK_ESCAPE)
|
||
level1.cardLayout.show(level1.container, "MENU");
|
||
if (e.getKeyCode() == java.awt.event.KeyEvent.VK_R)
|
||
buildLevel1Restart(level1);
|
||
}
|
||
});
|
||
|
||
// Will be registered with the container in setContainer()
|
||
// Store reference so setContainer can wire it up
|
||
storeLevel(level1, "LEVEL1");
|
||
}
|
||
|
||
// =========================================================================
|
||
// LEVEL 2 — "Double Danger" (Medium)
|
||
// =========================================================================
|
||
private void buildLevel2(GameFields gm) {
|
||
GameFields level2 = new GameFields();
|
||
|
||
level2.placePlayer(level2.bear, 100, 290);
|
||
level2.placePlayer(level2.seal, 520, 290);
|
||
|
||
level2.placeWall(level2.walls.get(0), 0, 330); // bottom floor
|
||
level2.placeWall(level2.walls.get(1), 30, 240); // left mid platform
|
||
level2.placeWall(level2.walls.get(2), 490, 240); // right mid platform
|
||
level2.placeWall(level2.walls.get(3), 240, 150); // center upper platform
|
||
level2.placeWall(level2.walls.get(4), 308, 260); // center divider
|
||
|
||
level2.placeRock(level2.rocks.get(0), 70, 300);
|
||
level2.placeRock(level2.rocks.get(1), 500, 300);
|
||
level2.placeRock(level2.rocks.get(2), 290, 122);
|
||
|
||
level2.placeFluid(level2.fluids.get(0), 400, 315); // bear-fluid lower right
|
||
level2.placeFluid(level2.fluids.get(1), 460, 222); // bear-fluid mid-right ledge edge
|
||
level2.placeFluid(level2.fluids.get(2), 255, 132); // bear-fluid on finish ledge
|
||
level2.placeFluid(level2.fluids.get(3), 160, 315); // seal-fluid lower left
|
||
level2.placeFluid(level2.fluids.get(4), 100, 222); // seal-fluid mid-left ledge edge
|
||
|
||
level2.placeGust(level2.windBoxes.get(0), 50, 60);
|
||
level2.placeGust(level2.windBoxes.get(1), 560, 60);
|
||
|
||
level2.placeDoors(570, 130, 20, 130);
|
||
|
||
storeLevel(level2, "LEVEL2");
|
||
}
|
||
|
||
// =========================================================================
|
||
// LEVEL 3 — "The Gauntlet" (Hard)
|
||
// =========================================================================
|
||
private void buildLevel3(GameFields gm) {
|
||
GameFields level3 = new GameFields();
|
||
|
||
level3.placePlayer(level3.bear, 20, 290);
|
||
level3.placePlayer(level3.seal, 590, 290);
|
||
|
||
level3.placeWall(level3.walls.get(0), 0, 330); // left floor strip
|
||
level3.placeWall(level3.walls.get(1), 530, 330); // right floor strip
|
||
level3.placeWall(level3.walls.get(2), 150, 230); // wide center platform
|
||
level3.placeWall(level3.walls.get(3), 30, 140); // upper-left ledge
|
||
level3.placeWall(level3.walls.get(4), 540, 140); // upper-right ledge
|
||
|
||
level3.placeRock(level3.rocks.get(0), 300, 202);
|
||
level3.placeRock(level3.rocks.get(1), 80, 300);
|
||
level3.placeRock(level3.rocks.get(2), 520, 300);
|
||
|
||
// Bear-fluid (index 0-2)
|
||
level3.placeFluid(level3.fluids.get(0), 120, 310);
|
||
level3.placeFluid(level3.fluids.get(1), 340, 212);
|
||
level3.placeFluid(level3.fluids.get(2), 560, 122);
|
||
// Seal-fluid (index 3-5)
|
||
level3.placeFluid(level3.fluids.get(3), 460, 310);
|
||
level3.placeFluid(level3.fluids.get(4), 240, 212);
|
||
level3.placeFluid(level3.fluids.get(5), 50, 122);
|
||
|
||
level3.placeGust(level3.windBoxes.get(0), 30, 50);
|
||
level3.placeGust(level3.windBoxes.get(1), 570, 50);
|
||
|
||
level3.placeDoors(560, 100, 10, 100);
|
||
|
||
storeLevel(level3, "LEVEL3");
|
||
}
|
||
|
||
// ── Small helpers ─────────────────────────────────────────────────────
|
||
|
||
/** Holds level panels until setContainer() is called and we can register them. */
|
||
private final java.util.LinkedHashMap<String, GameFields> pendingLevels = new java.util.LinkedHashMap<>();
|
||
|
||
private void storeLevel(GameFields lv, String key) {
|
||
pendingLevels.put(key, lv);
|
||
}
|
||
|
||
/** Resets level1 positions in-place (called on 'R' key). */
|
||
private void buildLevel1Restart(GameFields lv) {
|
||
lv.placePlayer(lv.bear, 50, 270);
|
||
lv.placePlayer(lv.seal, 560, 270);
|
||
lv.placeRock(lv.rocks.get(0), 258, 288);
|
||
}
|
||
|
||
// ── setContainer ──────────────────────────────────────────────────────
|
||
|
||
public void setContainer(JPanel container, CardLayout layout) {
|
||
this.container = container;
|
||
this.cardLayout = layout;
|
||
|
||
// Register every pending level built in the constructor
|
||
for (String key : pendingLevels.keySet()) {
|
||
GameFields lv = pendingLevels.get(key);
|
||
lv.setContainer(container, layout);
|
||
container.add(lv, key);
|
||
}
|
||
}
|
||
}
|
||
|
||
|