ADD file via upload

main
p6xlcrq3f 4 months ago
parent 8797f99c36
commit b8fdcdc06e

@ -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<ImageIcon> 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<ImageIcon> 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 + 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;
}
}
}
Loading…
Cancel
Save