parent
53322cbeb5
commit
e7b70956e9
@ -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 + "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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in new issue