diff --git a/src/DualGame.java b/src/DualGame.java deleted file mode 100644 index 3b611d6..0000000 --- a/src/DualGame.java +++ /dev/null @@ -1,376 +0,0 @@ -package cn.edu.caztc.sokobangame; - -import javax.swing.*; -import java.awt.*; -import java.awt.event.*; -import java.io.*; - -public class DualGame extends JFrame implements MapConfig { - private int[][][] map1; - private int player1x = -1, player1y = -1; - private int player2x = -1, player2y = -1; - private int level = 1; - private boolean diy = false; - - private JPanel panel; - private static DualGame instance; - private ImageIcon[] currentIcons; - private UpdateThread updateThread; - - public static DualGame getInstance() { - return instance; - } - - public DualGame() { - instance = this; - currentIcons = ThemeSwitcher.getCurrentThemeIcons().clone(); - initUI(); - loadInitialMap(); - setVisible(true); - } - - public void updateTheme(ImageIcon[] newIcons) { - currentIcons = newIcons.clone(); - panel.repaint(); - } - - private void initUI() { - setTitle("推箱子-双人模式"); - setSize(900, 950); - setLayout(new FlowLayout()); - setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); - setLocationRelativeTo(null); - setResizable(false); - - initMenu(); - initGamePanel(); - - addWindowListener(new WindowAdapter() { - @Override - public void windowClosing(WindowEvent e) { - cleanupResources(); - System.out.println("双人模式程序终止"); // 添加终止信息 - } - }); - } - - private void initMenu() { - JMenuBar menuBar = new JMenuBar(); - JMenu menu = new JMenu("菜单"); - - JMenuItem levelItem = new JMenuItem("选关"); - levelItem.addActionListener(e -> selectLevel()); - menu.add(levelItem); - - JMenuItem restartItem = new JMenuItem("重新开始"); - restartItem.addActionListener(e -> GetMAP(level, diy)); - menu.add(restartItem); - - JMenuItem singleModeItem = new JMenuItem("切换到单人模式"); - singleModeItem.addActionListener(e -> switchToSingleMode()); - menu.add(singleModeItem); - - menuBar.add(menu); - setJMenuBar(menuBar); - } - - private void initGamePanel() { - panel = new DualPanel(); - panel.setPreferredSize(new Dimension(MAP_WIDTH, MAP_HEIGHT)); - panel.setBackground(Color.BLACK); - add(panel); - - panel.setFocusable(true); - panel.requestFocusInWindow(); - panel.addKeyListener(new DualKeyListener()); - } - - private void loadInitialMap() { - GetMAP(1, false); - updateThread = new UpdateThread(panel); - updateThread.start(); - } - - private void cleanupResources() { - MusicPlayer.getInstance().stopMusic(); - if (updateThread != null) { - updateThread.stopRunning(); - } - } - - void GetMAP(int level, boolean diy) { - String prefix = diy ? "双人diy" : "双人"; - String filePath = PATH + "\\" + prefix + level + ".map"; - - try { - File mapFile = new File(filePath); - loadMapData(filePath); - validateSpawnPoints(); - } catch (Exception e) { - JOptionPane.showMessageDialog(null, - "地图加载失败: " + e.getMessage() + "\n文件路径: " + filePath, - "错误", JOptionPane.ERROR_MESSAGE); - } - - refreshGameDisplay(); - } - - private void loadMapData(String filePath) throws IOException { - try (DataInputStream in = new DataInputStream( - new BufferedInputStream(new FileInputStream(filePath)))) { - - resetPlayerPositions(); - int rows = in.readInt(); - int cols = in.readInt(); - map1 = new int[rows][cols][1]; - - for (int i = 0; i < rows; i++) { - for (int j = 0; j < cols; j++) { - int cellValue = in.readInt(); - map1[i][j][0] = cellValue; - - if (cellValue == 5) { // 玩家一出生点 - player1x = i; - player1y = j; - map1[i][j][0] = 1; // 出生点变为空地 - } else if (cellValue == 6) { // 玩家二出生点 - player2x = i; - player2y = j; - map1[i][j][0] = 1; // 出生点变为空地 - } - } - } - } - } - - private void validateSpawnPoints() { - if (player1x == -1 || player2x == -1) { - JOptionPane.showMessageDialog(null, - "地图必须包含两个出生点(5-玩家一,6-玩家二)", "错误", JOptionPane.ERROR_MESSAGE); - } - } - - class DualPanel extends JPanel { - @Override - protected void paintComponent(Graphics g) { - super.paintComponent(g); - - g.setColor(Color.BLACK); - g.fillRect(0, 0, getWidth(), getHeight()); - - if (map1 != null) { - for (int i = 0; i < map1.length; i++) { - for (int j = 0; j < map1[0].length; j++) { - int cellValue = map1[i][j][0]; - if (cellValue >= 0 && cellValue < currentIcons.length) { // 使用currentIcons - Image img = currentIcons[cellValue].getImage(); - if (img != null) { - g.drawImage(img, j*SOUREC_WIDTH, i*SOUREC_HEIGHT, - SOUREC_WIDTH, SOUREC_HEIGHT, this); - } - } - } - } - } - - // 绘制玩家(同样使用currentIcons) - if (player1x >= 0 && player1y >= 0) { - g.drawImage(currentIcons[5].getImage(), player1y*SOUREC_WIDTH, player1x*SOUREC_HEIGHT, - SOUREC_WIDTH, SOUREC_HEIGHT, this); - } - if (player2x >= 0 && player2y >= 0) { - g.drawImage(currentIcons[6].getImage(), player2y*SOUREC_WIDTH, player2x*SOUREC_HEIGHT, - SOUREC_WIDTH, SOUREC_HEIGHT, this); - } - } - } - - class DualKeyListener extends KeyAdapter { - @Override - public void keyPressed(KeyEvent e) { - switch (e.getKeyCode()) { - case KeyEvent.VK_UP: tryMove(1, 1); break; - case KeyEvent.VK_DOWN: tryMove(1, 3); break; - case KeyEvent.VK_LEFT: tryMove(1, 2); break; - case KeyEvent.VK_RIGHT: tryMove(1, 4); break; - case KeyEvent.VK_W: tryMove(2, 1); break; - case KeyEvent.VK_S: tryMove(2, 3); break; - case KeyEvent.VK_A: tryMove(2, 2); break; - case KeyEvent.VK_D: tryMove(2, 4); break; - } - panel.repaint(); - } - - private void tryMove(int playerNum, int direction) { - if (canMove(playerNum, direction)) { - if (isPushingBox(playerNum, direction)) { - if (canPushBox(playerNum, direction)) { - movePlayer(playerNum, direction); - } - } else { - movePlayer(playerNum, direction); - } - - if (IsSuccess()) { - Success(); - } - } - } - } - - // 其他辅助方法... - private void movePlayer(int playerNum, int direction) { - int x = playerNum == 1 ? player1x : player2x; - int y = playerNum == 1 ? player1y : player2y; - - int newX = x, newY = y; - int frontX = x, frontY = y; - int beyondX = x, beyondY = y; - - switch (direction) { - case 1: newX--; frontX--; beyondX -= 2; break; - case 2: newY--; frontY--; beyondY -= 2; break; - case 3: newX++; frontX++; beyondX += 2; break; - case 4: newY++; frontY++; beyondY += 2; break; - } - - if ((playerNum == 1 && newX == player2x && newY == player2y) || - (playerNum == 2 && newX == player1x && newY == player1y)) { - return; - } - - if (map1[frontX][frontY][0] == 2 || map1[frontX][frontY][0] == 3) { - if ((beyondX == player1x && beyondY == player1y) || - (beyondX == player2x && beyondY == player2y)) { - return; - } - - map1[beyondX][beyondY][0] = (map1[beyondX][beyondY][0] == 4) ? 3 : 2; - map1[frontX][frontY][0] = (map1[frontX][frontY][0] == 3) ? 4 : 1; - } - - if (playerNum == 1) { - player1x = newX; - player1y = newY; - } else { - player2x = newX; - player2y = newY; - } - } - - boolean IsSuccess() { - for (int i = 0; i < map1.length; i++) { - for (int j = 0; j < map1[0].length; j++) { - if (map1[i][j][0] == 2) { - return false; - } - } - } - return true; - } - - void Success() { - String prefix = diy ? "双人diy" : "双人"; - // 先检查是否是最后一关 - if (!new File(PATH + "\\" + prefix + (level+1) + ".map").exists()) { - // 是最后一关 - JOptionPane.showMessageDialog(null, - "恭喜您已通关所有关卡!", - "全部通关", JOptionPane.INFORMATION_MESSAGE); - level = 1; - GetMAP(level, diy); - } else { - // 不是最后一关 - JOptionPane.showMessageDialog(null, - "恭喜通关!即将进入下一关", - "成功", JOptionPane.INFORMATION_MESSAGE); - GetNextMap(); - } - } - - void GetNextMap() { - String prefix = diy ? "双人diy" : "双人"; - level++; - GetMAP(level, diy); - } - - private void refreshGameDisplay() { - panel.repaint(); - panel.requestFocusInWindow(); - } - - private void selectLevel() { - GetLevelDialog dialog = new GetLevelDialog(true); - if (dialog.getValue() != 0) { - diy = dialog.isdiy(); - level = dialog.getValue(); - GetMAP(level, diy); - } - } - - private void switchToSingleMode() { - new MainGame().setVisible(true); - dispose(); - } - - private void resetPlayerPositions() { - player1x = player1y = player2x = player2y = -1; - } - - private boolean canMove(int playerNum, int direction) { - int x = playerNum == 1 ? player1x : player2x; - int y = playerNum == 1 ? player1y : player2y; - - switch (direction) { - case 1: return x > 0 && map1[x-1][y][0] != 0; - case 2: return y > 0 && map1[x][y-1][0] != 0; - case 3: return x < map1.length-1 && map1[x+1][y][0] != 0; - case 4: return y < map1[0].length-1 && map1[x][y+1][0] != 0; - } - return false; - } - - private boolean isPushingBox(int playerNum, int direction) { - int x = playerNum == 1 ? player1x : player2x; - int y = playerNum == 1 ? player1y : player2y; - - switch (direction) { - case 1: return x > 0 && (map1[x-1][y][0] == 2 || map1[x-1][y][0] == 3); - case 2: return y > 0 && (map1[x][y-1][0] == 2 || map1[x][y-1][0] == 3); - case 3: return x < map1.length-1 && (map1[x+1][y][0] == 2 || map1[x+1][y][0] == 3); - case 4: return y < map1[0].length-1 && (map1[x][y+1][0] == 2 || map1[x][y+1][0] == 3); - } - return false; - } - - private boolean canPushBox(int playerNum, int direction) { - int x = playerNum == 1 ? player1x : player2x; - int y = playerNum == 1 ? player1y : player2y; - - int frontX = x, frontY = y; - int beyondX = x, beyondY = y; - - switch (direction) { - case 1: frontX--; beyondX -= 2; break; - case 2: frontY--; beyondY -= 2; break; - case 3: frontX++; beyondX += 2; break; - case 4: frontY++; beyondY += 2; break; - } - - if (frontX < 0 || frontY < 0 || - frontX >= map1.length || frontY >= map1[0].length || - (map1[frontX][frontY][0] != 2 && map1[frontX][frontY][0] != 3)) { - return false; - } - - if (beyondX < 0 || beyondY < 0 || - beyondX >= map1.length || beyondY >= map1[0].length || - map1[beyondX][beyondY][0] == 0 || - map1[beyondX][beyondY][0] == 2 || - map1[beyondX][beyondY][0] == 3) { - return false; - } - - return true; - } -}