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 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); } } }