Java 2D数组冒险游戏:完善方向判断if语句与钥匙系统求助
Hey Sam, let's fix up your haunted house game step by step. I noticed a couple of immediate issues (like an array out-of-bounds error) plus your two requested features—we'll cover all of them clearly, no fancy jargon since you mentioned you're still building your programming foundation.
1. 完善方向输入有效性判断
First off, your code has a critical array out-of-bounds bug: you declared a 2x2 array with String room[][] = new String[2][2];, but then tried to assign values to indexes like room[2][0]—Java arrays start counting from 0, so a 2x2 array only uses 0 and 1 for row/column indexes. Let's fix that first by changing the array to 3x3:
String room[][] = new String[3][3];
Now for the blank if statement in the direction loop: we need to read the user's input, check if it's a valid direction (W/A/S/D), and either accept it or prompt for a retry. We'll also make it case-insensitive so lowercase inputs work too:
while (true) { System.out.println("Enter your direction (W/A/S/D):"); di = c.nextLine().trim().toUpperCase(); // Trim spaces and convert to uppercase // Check if input is one of the valid directions if (di.equals("W") || di.equals("A") || di.equals("S") || di.equals("D")) { break; // Exit loop if input is valid } else { System.out.println("Invalid direction! Please enter W, A, S, or D."); } }
2. 添加钥匙解锁系统
We'll implement a simple key system that tracks which keys the player has, checks for locked rooms when moving, and unlocks them if the player has the right key.
Step 1: Add key tracking variables
At the top of your main method, right after declaring the room array, add these boolean variables to track key ownership:
// Track if player has keys: false = no, true = yes boolean hasStorageKey = false; boolean hasGarageKey = false;
Step 2: Give keys to the player (or let them find them)
You can either give keys upfront (like your initial message suggests) or let players find them in specific rooms. Let's make it more fun by having keys spawn in rooms:
// Inside the do-while loop, right after printing the current room if (room[x][y].equals("Entry Hall") && !hasStorageKey) { hasStorageKey = true; System.out.println("You found a rusted key on the entry table—this must unlock the Storage!"); } if (room[x][y].equals("Grand Hall") && !hasGarageKey) { hasGarageKey = true; System.out.println("You spotted a shiny key on the grand piano—this opens the Garage!"); }
Step 3: Lock check logic when moving
Instead of directly updating x and y, we'll calculate the target coordinates first, check if the target room is locked, and only move if the player has the key (or the room is unlocked):
// Calculate target coordinates (don't update x/y yet) int targetX = x; int targetY = y; switch(di) { case "W": targetY += 1; break; case "A": targetX -= 1; break; case "S": targetY -= 1; break; case "D": targetX += 1; break; } // First check if target is outside the map (wall collision) if (targetX < 0 || targetX >= 3 || targetY < 0 || targetY >= 3) { System.out.println("Oops, you hit a wall! Try another direction."); continue; // Skip to next loop iteration } // Check if target room is locked String targetRoom = room[targetX][targetY]; if (targetRoom.contains("[locked]")) { if (targetRoom.equals("Storage [locked]") && hasStorageKey) { // Unlock the room and move room[targetX][targetY] = "Storage"; System.out.println("Click! You unlocked the Storage room."); x = targetX; y = targetY; } else if (targetRoom.equals("Garage [locked]") && hasGarageKey) { room[targetX][targetY] = "Garage"; System.out.println("Click! You unlocked the Garage room."); x = targetX; y = targetY; } else { System.out.println("This room is locked—you need the right key to enter!"); } } else { // Room is unlocked, move freely x = targetX; y = targetY; }
Step 4: Fix the loop end condition
Your original do-while condition (while (x>=2);) will exit as soon as the player reaches x=2, which is too abrupt. Let's make it end when the player reaches the Back Door:
do { // All game logic here } while (!room[x][y].equals("Back Door")); // Exit message System.out.println("\nYou reached the Back Door and escaped! You uncovered the haunted house's secret—congratulations!"); c.close();
Full Modified Code
Here's the complete working code with all fixes and features:
package hauntedhouse; import java.util.Scanner; public class HauntedHouse { public static void main(String[] args) { Scanner c = new Scanner(System.in); // Fixed array size to 3x3 to avoid out-of-bounds errors String room[][] = new String[3][3]; // Fill room names room[0][0] = "Entry Hall"; room[1][0] = "Dining Room"; room[2][0] = "Master Bedroom"; room[0][1] = "Storage [locked]"; room[1][1] = "Grand Hall"; room[2][1] = "Bedroom"; room[0][2] = "Garage [locked]"; room[1][2] = "Back Door"; room[2][2] = "Attic"; // Added name for empty room int x = 0; int y = 0; String di = ""; // Key tracking variables boolean hasStorageKey = false; boolean hasGarageKey = false; System.out.println("Theres a secret in this house,"); System.out.println("go into the locked rooms to find"); System.out.println("out what it is. Let's start!"); do { System.out.println("\nYou are now in the " + room[x][y]); // Give keys when entering specific rooms if (room[x][y].equals("Entry Hall") && !hasStorageKey) { hasStorageKey = true; System.out.println("You found a rusted key on the entry table—this must unlock the Storage!"); } if (room[x][y].equals("Grand Hall") && !hasGarageKey) { hasGarageKey = true; System.out.println("You spotted a shiny key on the grand piano—this opens the Garage!"); } // Direction input loop while (true) { System.out.println("Enter your direction (W/A/S/D):"); di = c.nextLine().trim().toUpperCase(); if (di.equals("W") || di.equals("A") || di.equals("S") || di.equals("D")) { break; } else { System.out.println("Invalid direction! Please enter W, A, S, or D."); } } // Calculate target coordinates int targetX = x; int targetY = y; switch(di) { case "W": targetY += 1; break; case "A": targetX -= 1; break; case "S": targetY -= 1; break; case "D": targetX += 1; break; } // Check wall collision if (targetX < 0 || targetX >= 3 || targetY < 0 || targetY >= 3) { System.out.println("Oops, you hit a wall! Try another direction."); continue; } // Check locked rooms and keys String targetRoom = room[targetX][targetY]; if (targetRoom.contains("[locked]")) { if (targetRoom.equals("Storage [locked]") && hasStorageKey) { room[targetX][targetY] = "Storage"; System.out.println("Click! You unlocked the Storage room."); x = targetX; y = targetY; } else if (targetRoom.equals("Garage [locked]") && hasGarageKey) { room[targetX][targetY] = "Garage"; System.out.println("Click! You unlocked the Garage room."); x = targetX; y = targetY; } else { System.out.println("This room is locked—you need the right key to enter!"); } } else { x = targetX; y = targetY; } } while (!room[x][y].equals("Back Door")); System.out.println("\nYou reached the Back Door and escaped! You uncovered the haunted house's secret—congratulations!"); c.close(); } }
内容的提问来源于stack exchange,提问作者Sam

