From e7b70956e95849ff71a30cfb08a0bf12426be60e Mon Sep 17 00:00:00 2001 From: pmjakhf25 <3190866304@qq.com> Date: Sun, 13 Apr 2025 20:10:46 +0800 Subject: [PATCH] ADD file via upload --- src/CreatMap.java | 257 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 257 insertions(+) create mode 100644 src/CreatMap.java diff --git a/src/CreatMap.java b/src/CreatMap.java new file mode 100644 index 0000000..ef202cc --- /dev/null +++ b/src/CreatMap.java @@ -0,0 +1,257 @@ +package cn.edu.caztc.sokobangame; + +import javax.swing.*; +import javax.swing.border.EmptyBorder; +import java.awt.*; +import java.awt.event.*; +import java.io.*; + +public class CreatMap extends JFrame implements MapConfig { + private JPanel contentPane; + private JTextField tf_level; + private JPanel panel; + private JCheckBox dualModeCheck; + private JComboBox box; + + // 关卡变量 + int level = 1; + + // 地图数据 + static int[][][] map1 = new int[MAP_WIDTH / SOUREC_WIDTH][MAP_HEIGHT / SOUREC_HEIGHT][1]; + static ImageIcon[][] icons = new ImageIcon[MAP_WIDTH / SOUREC_WIDTH][MAP_HEIGHT / SOUREC_HEIGHT]; + + public CreatMap() { + setTitle("推箱子地图编辑器"); + setDefaultCloseOperation(JFrame.DISPOSE_ON_CLOSE); + setBounds(100, 100, 1180, 735); + + contentPane = new JPanel(); + contentPane.setBorder(new EmptyBorder(5, 5, 5, 5)); + setContentPane(contentPane); + contentPane.setLayout(null); + + // 初始化地图 - 初始为空白 + initMap(); + + // 滚动面板 + JScrollPane scrollPane = new JScrollPane(); + scrollPane.setBounds(14, 13, 800, 653); + contentPane.add(scrollPane); + + // 地图面板 + panel = new MySetPanel(); + panel.setPreferredSize(new Dimension(800, 800)); + scrollPane.setViewportView(panel); + scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS); + + // 双人模式复选框 + dualModeCheck = new JCheckBox("双人模式"); + dualModeCheck.setBounds(874, 100, 111, 36); + contentPane.add(dualModeCheck); + + // 关卡标签和输入框 + JLabel lb_1 = new JLabel("关卡"); + lb_1.setBounds(874, 160, 111, 36); + contentPane.add(lb_1); + + tf_level = new JTextField(String.valueOf(level)); + tf_level.setBounds(1003, 158, 117, 40); + contentPane.add(tf_level); + + // 素材选择下拉框 + box = new JComboBox<>(); + setBox(box); + box.setSelectedIndex(0); + box.setBounds(939, 312, 123, 99); + contentPane.add(box); + + // 保存地图按钮 + JButton btn_save = new JButton("保存地图"); + btn_save.setBounds(945, 578, 117, 40); + contentPane.add(btn_save); + + // 给面板安装鼠标监听器 + panel.addMouseListener(new PanelListenner()); + + // 保存按钮监听器 + btn_save.addActionListener(new Buttonlistenner()); + + setLocationRelativeTo(null); + setVisible(true); + } + + // 初始化地图数据 - 初始为空白 + private void initMap() { + for (int i = 0; i < map1.length; i++) { + for (int j = 0; j < map1[0].length; j++) { + map1[i][j][0] = -1; // 使用-1表示空白 + icons[i][j] = null; // 初始没有图标 + } + } + } + + // 设置素材下拉表 + public void setBox(JComboBox box) { + box.addItem(icon101); // 墙 + box.addItem(icon102); // 地板 + box.addItem(icon103); // 空箱子 + box.addItem(icon104); // 箱子 + box.addItem(icon105); // 箱子点 + box.addItem(icon106); // 玩家一 + box.addItem(icon107); // 玩家二 + } + + // 面板监听类 + class PanelListenner extends MouseAdapter { + public void mouseClicked(MouseEvent e) { + int j = e.getX() / SOUREC_WIDTH; + int i = e.getY() / SOUREC_HEIGHT; + + ImageIcon icon = (ImageIcon) box.getSelectedItem(); + int index = box.getSelectedIndex(); + + // 处理不同素材的放置 + switch (index) { + case 0: // 墙 + map1[i][j][0] = 0; + icons[i][j] = icon101; + break; + case 1: // 地板 + map1[i][j][0] = 1; + icons[i][j] = icon102; + break; + case 2: // 空箱子 + map1[i][j][0] = 2; + icons[i][j] = icon103; + break; + case 3: // 箱子 + map1[i][j][0] = 3; + icons[i][j] = icon104; + break; + case 4: // 箱子点 + map1[i][j][0] = 4; + icons[i][j] = icon105; + break; + case 5: // 玩家一 + map1[i][j][0] = 5; // 玩家一出生点 + icons[i][j] = icon106; + break; + case 6: // 玩家二 + map1[i][j][0] = 6; // 玩家二出生点 + icons[i][j] = icon107; + break; + } + + panel.repaint(); + } + } + + // 按钮监听类 + class Buttonlistenner implements ActionListener { + @Override + public void actionPerformed(ActionEvent e) { + if (e.getActionCommand().equals("保存地图")) { + try { + level = Integer.parseInt(tf_level.getText()); + } catch (NumberFormatException ex) { + JOptionPane.showMessageDialog(null, "请输入有效的关卡数字", "错误", JOptionPane.ERROR_MESSAGE); + return; + } + + // 验证双人模式地图是否包含两个出生点 + if (dualModeCheck.isSelected()) { + int player1Count = 0, player2Count = 0; + for (int i = 0; i < map1.length; i++) { + for (int j = 0; j < map1[0].length; j++) { + if (map1[i][j][0] == 5) player1Count++; + if (map1[i][j][0] == 6) player2Count++; + } + } + + if (player1Count != 1 || player2Count != 1) { + JOptionPane.showMessageDialog(null, + "双人模式地图必须包含一个玩家一出生点(5)和一个玩家二出生点(6)", + "错误", JOptionPane.ERROR_MESSAGE); + return; + } + } + + // 检查地图是否已存在 + String prefix = dualModeCheck.isSelected() ? "双人" : ""; + String filePath = PATH + "\\" + prefix + level + ".map"; + + if (new File(filePath).exists()) { + int n = JOptionPane.showConfirmDialog(null, + "地图已存在,是否覆盖?", "警告", JOptionPane.YES_NO_OPTION); + if (n != JOptionPane.YES_OPTION) { + return; + } + } + + CreatMapTxt(); + } + } + } + + // 创建地图文件 + void CreatMapTxt() { + String prefix = dualModeCheck.isSelected() ? "双人" : ""; + String filePath = PATH + "\\" + prefix + "diy" + level + ".map"; + + try (DataOutputStream dos = new DataOutputStream(new FileOutputStream(filePath))) { + dos.writeInt(map1.length); // 行数 + dos.writeInt(map1[0].length); // 列数 + + for (int i = 0; i < map1.length; i++) { + for (int j = 0; j < map1[0].length; j++) { + // 保存时,空白位置(-1)自动转为墙(0) + dos.writeInt(map1[i][j][0] == -1 ? 0 : map1[i][j][0]); + } + } + + JOptionPane.showMessageDialog(null, "地图保存成功: " + filePath); + } catch (Exception e) { + JOptionPane.showMessageDialog(null, "保存地图失败: " + e.getMessage(), + "错误", JOptionPane.ERROR_MESSAGE); + e.printStackTrace(); + } + } + + // 地图面板类 + class MySetPanel extends JPanel { + @Override + public void paint(Graphics g) { + super.paint(g); + // 绘制背景 + g.setColor(Color.LIGHT_GRAY); + g.fillRect(0, 0, getWidth(), getHeight()); + + // 绘制网格线 + g.setColor(Color.GRAY); + for (int i = 0; i <= MAP_HEIGHT / SOUREC_HEIGHT; i++) { + g.drawLine(0, i * SOUREC_HEIGHT, MAP_WIDTH, i * SOUREC_HEIGHT); + } + for (int j = 0; j <= MAP_WIDTH / SOUREC_WIDTH; j++) { + g.drawLine(j * SOUREC_WIDTH, 0, j * SOUREC_WIDTH, MAP_HEIGHT); + } + + // 绘制已放置的素材 + for (int i = 0; i < MAP_HEIGHT / SOUREC_HEIGHT; i++) { + for (int j = 0; j < MAP_WIDTH / SOUREC_WIDTH; j++) { + if (icons[i][j] != null) { + g.drawImage(icons[i][j].getImage(), getDrawX(j), getDrawY(i), + SOUREC_WIDTH, SOUREC_HEIGHT, null); + } + } + } + } + + private int getDrawX(int j) { + return j * SOUREC_WIDTH; + } + + private int getDrawY(int i) { + return i * SOUREC_HEIGHT; + } + } +}