Taught you do Sokoban game --JAVA GUI (a)

Disclaimer: This article is a blogger original article, follow the CC 4.0 BY-SA copyright agreement, reproduced, please attach the original source link and this statement.
This link: https://blog.csdn.net/qq_40176716/article/details/96454589

Read this blog needs a bit of programming basics, a little can. About this project see the blogger blog. This tutorial is written using JAVA + Eclipse, Eclipse do not understand, please click → Portal

 

Create a project and import resources
Create a project and import resources

 

​​​​

This blog directory

​​​​

Map Editor interface MapConfig.java

 Map Editor interface CreatMap.java

1. Create a screen

2. The drop-down list box displays pictures

 3. The display interface map

4. Save Map

 The code optimization

Tools Utils.java

Test class test.java

final effect


  • Map Editor interface MapConfig.java

We must first set the size of the map editor, the size of each resource on the map editor, that the size of each grid through a simple six pictures, constitute a complete map

I set the default map for 800 * 800, 50 * 50 each asset. That is, each row is a column every 18 material

Map array, digital band edge material. Wall floor 0 1 2 3 boxes 4 boxes empty boxes spawn point 5 points

package cn.edu.caztc.sokobangame;

import javax.swing.ImageIcon;

public interface MapConfig {
	/**素材宽度*/
    int SOUREC_WIDTH = 50;
    /**素材高度*/
    int SOUREC_HEIGHT = 50;  
    /**地图宽度*/
    int MAP_WIDTH = 800;  
    /**地图高度*/
    int MAP_HEIGHT= 800;  
    /**地图保存的位置 */
    String PATH = "D:\\推箱子";  
   
    ImageIcon icon101 = new ImageIcon("images/墙.png"); 
    ImageIcon icon102 = new ImageIcon("images/地板.png"); 
    ImageIcon icon103 = new ImageIcon("images/空箱子.png"); 
    ImageIcon icon104 = new ImageIcon("images/箱子.png"); 
    ImageIcon icon105 = new ImageIcon("images/箱子点.png"); 
    ImageIcon icon106 = new ImageIcon("images/player.png");  
    
    //将所有的图片素材对象放入一个数组中,便于窗体上的下拉列表添加所有的图片素材  
    ImageIcon[] allicons = {icon101,icon102,icon103,icon104,icon105,icon106};
}
  •  Map Editor interface CreatMap.java

CreatMap () constructor, used to create the interface and controls

void setBox (JComboBox <ImageIcon> box) side of the interface will add allicons creative to 6 in the box, box drop-down list

class PanelListenner class panel monitor, a mouse click on a location corresponding to the array assignment location

class MySetPanel temporary map panel category, Show Map

class Buttonlistenner key listener class, then click the Save button to save the map file map

1. Create a screen

Generally envisaged interface is such that the left display screen, a map display, JPanel achieved. The right configuration, the + button for configuration edit box confirmation. Save for the Save button. There is a drop-down box to select the picture material.

 Code:

package cn.edu.caztc.sokobangame;

import java.awt.Dimension;

import javax.swing.ImageIcon;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class CreatMap extends JFrame implements MapConfig {

	private JPanel contentPane;
	private JTextField tf_level;
	private JPanel panel;

	// 关卡变量
	int level = 1;

	// 用来选择素材的下拉表
	private JComboBox<ImageIcon> box;

	/**
	 * 创建界面
	 */
	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);

		// 滚动面板
		JScrollPane scrollPane = new JScrollPane();
		scrollPane.setBounds(14, 13, 800, 653);
		contentPane.add(scrollPane);

		// 地图面板
		panel = new JPanel();
		panel.setPreferredSize(new Dimension(800, 800));
		scrollPane.setViewportView(panel);
		scrollPane.setHorizontalScrollBarPolicy(JScrollPane.HORIZONTAL_SCROLLBAR_ALWAYS);

		// 标签
		JLabel lb_1 = new JLabel("关卡");
		lb_1.setBounds(874, 160, 111, 36);
		contentPane.add(lb_1);

		// 编辑框
		tf_level = new JTextField();
		// 设置默认关卡
		tf_level.setText(String.valueOf(level));
		tf_level.setColumns(10);
		tf_level.setBounds(1003, 158, 117, 40);
		contentPane.add(tf_level);

		// 下拉菜单
		box = new JComboBox<ImageIcon>();
		box.setBounds(939, 312, 123, 99);
		contentPane.add(box);

		// 界面居中
		setLocationRelativeTo(null);
		// 显示界面
		setVisible(true);
	}

}
Creating interface effects

2. The drop-down list box displays pictures

 As the name suggests, the picture is displayed good choice ah. Here you can modify the contents of the red box.

 Code:

//省略***********************************
//下拉菜单
		box = new JComboBox<ImageIcon>();
		setBox(box);
		box.setSelectedIndex(0);
		box.setBounds(939, 312, 123, 99);
		contentPane.add(box);
//省略
//省略*****************************************
//省略
// 设置地图中的素材下拉表
	public void setBox(JComboBox<ImageIcon> box) {
		for (int i = 0; i < allicons.length; i++) {
			box.addItem(allicons[i]);
		}
	}

 

Drop-down list box displays the picture effect

 3. The display interface map

We did before preparation of course we want to display the map ah. Thinking, that is, the JPanel paint drawn. We define a 3-dimensional array of type int, used to hold the map. Wherein the map coordinates representative of the first two, the third bit represents a number corresponding to the map image. My default is 0 1 wall floor empty box 2 box 3 box 4 point 5 point of birth. A map must and only then define a ImageIcon2 a 5-dimensional array, used to hold the corresponding picture.

package cn.edu.caztc.sokobangame;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class CreatMap extends JFrame implements MapConfig {

	private JPanel contentPane;
	private JTextField tf_level;
	private JPanel panel;

	// 关卡变量
	int level = 1;

	// 用来选择素材的下拉表
	private JComboBox<ImageIcon> box;
	// 地图数组
	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);

		// 滚动面板
		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);

		// 标签
		JLabel lb_1 = new JLabel("关卡");
		lb_1.setBounds(874, 160, 111, 36);
		contentPane.add(lb_1);

		// 编辑框
		tf_level = new JTextField();
		// 设置默认关卡
		tf_level.setText(String.valueOf(level));
		tf_level.setColumns(10);
		tf_level.setBounds(1003, 158, 117, 40);
		contentPane.add(tf_level);

		// 下拉菜单
		box = new JComboBox<ImageIcon>();
		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);

		// 给面板安装鼠标监听器
		PanelListenner plis = new PanelListenner();
		panel.addMouseListener(plis);

		// 界面居中
		setLocationRelativeTo(null);
		// 显示界面
		setVisible(true);
	}

	// 设置地图中的素材下拉表
	public void setBox(JComboBox<ImageIcon> box) {
		for (int i = 0; i < allicons.length; i++) {
			box.addItem(allicons[i]);
		}
	}

	/**
	 * 面板监听类
	 * 
	 * @author 莫言情难忘
	 */
	class PanelListenner extends MouseAdapter {
		public void mouseClicked(MouseEvent e) {
			int num = 0;
			// 得到该位置对应的数组下标
			int j = e.getX() / SOUREC_WIDTH;
			int i = e.getY() / SOUREC_HEIGHT;
			System.out.println(i + "<>" + j);
			// 得到选择框中的图片
			ImageIcon icon = (ImageIcon) box.getSelectedItem();
			// 0墙 1地板 2空箱子 3 箱子 4箱子点 5出生点
			int index = box.getSelectedIndex();
			if (index > 5) {
				index = 0;
				icons[i][j] = icon101;
			} else {
				map1[i][j][0] = index;
				icons[i][j] = icon;
			}
			panel.repaint();
		}
	}

	/**
	 * 临时地图面板类
	 * 
	 * @author 莫言情难忘
	 * 
	 */
	class MySetPanel extends JPanel {

		@Override
		public void paint(Graphics g) {
			super.paint(g);
			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);
					}
				}
			}
		}

		// 将数组下标转化成对应的图片左上角坐标
		public int getDrawX(int j) {
			int x = j * 50;
			return x;
		}

		// 将数组下标转化成对应的图片左上角坐标
		public int getDrawY(int i) {
			int y = i * 50;
			return y;
		}
	}

}

 

Display interface effects

4. Save Map

The final step, save the map ah. Because we have a 3-dimensional array of type int, so we put the array in turn save. A little attention, we put all the material one point out of a waste of time, so we set to 0 the role of Wall manifested. The default is do not do wall wall. Some of these methods, below the tool comprising class.

package cn.edu.caztc.sokobangame;

import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.DataOutputStream;
import java.io.FileOutputStream;

import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JComboBox;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextField;
import javax.swing.border.EmptyBorder;

public class CreatMap extends JFrame implements MapConfig {

	private JPanel contentPane;
	private JTextField tf_level;
	private JPanel panel;

	// 关卡变量
	int level = 1;

	// 用来选择素材的下拉表
	private JComboBox<ImageIcon> box;
	// 地图数组
	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);

		// 滚动面板
		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);

		// 标签
		JLabel lb_1 = new JLabel("关卡");
		lb_1.setBounds(874, 160, 111, 36);
		contentPane.add(lb_1);

		// 编辑框
		tf_level = new JTextField();
		// 设置默认关卡
		tf_level.setText(String.valueOf(level));
		tf_level.setColumns(10);
		tf_level.setBounds(1003, 158, 117, 40);
		contentPane.add(tf_level);

		// 下拉菜单
		box = new JComboBox<ImageIcon>();
		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);

		// 给面板安装鼠标监听器
		PanelListenner plis = new PanelListenner();
		panel.addMouseListener(plis);

		// 给按钮安装事件监听器
		Buttonlistenner blis = new Buttonlistenner();
		btn_save.addActionListener(blis);
		// 界面居中
		setLocationRelativeTo(null);
		// 显示界面
		setVisible(true);
	}

	// 设置地图中的素材下拉表
	public void setBox(JComboBox<ImageIcon> box) {
		for (int i = 0; i < allicons.length; i++) {
			box.addItem(allicons[i]);
		}
	}

	/**
	 * 面板监听类
	 * 
	 * @author 莫言情难忘
	 */
	class PanelListenner extends MouseAdapter {
		public void mouseClicked(MouseEvent e) {
			int num = 0;
			// 得到该位置对应的数组下标
			int j = e.getX() / SOUREC_WIDTH;
			int i = e.getY() / SOUREC_HEIGHT;
			System.out.println(i + "<>" + j);
			// 得到选择框中的图片
			ImageIcon icon = (ImageIcon) box.getSelectedItem();
			// 0墙 1地板 2空箱子 3 箱子 4箱子点 5出生点
			int index = box.getSelectedIndex();
			if (index > 5) {
				index = 0;
				icons[i][j] = icon101;
			} else {
				map1[i][j][0] = index;
				icons[i][j] = icon;
			}
			panel.repaint();
		}
	}

	/**
	 * 临时地图面板类
	 * 
	 * @author 莫言情难忘
	 * 
	 */
	class MySetPanel extends JPanel {

		@Override
		public void paint(Graphics g) {
			super.paint(g);
			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);
					}
				}
			}
		}

		// 将数组下标转化成对应的图片左上角坐标
		public int getDrawX(int j) {
			int x = j * 50;
			return x;
		}

		// 将数组下标转化成对应的图片左上角坐标
		public int getDrawY(int i) {
			int y = i * 50;
			return y;
		}
	}

	/**
	 * 按键监听类
	 * 
	 * @author 莫言情难忘
	 * 
	 */
	class Buttonlistenner implements ActionListener {

		@Override
		public void actionPerformed(ActionEvent e) {
			// 如果按下了创建按钮,就保存地图
			if (e.getActionCommand().equals("保存地图")) {
				level = Integer.parseInt(tf_level.getText());
				if (Utils.IsExistence(PATH + "\\diy" + level + ".map")) {
					int n = JOptionPane.showConfirmDialog(null, "地图已存在,是否覆盖?", "警告", JOptionPane.YES_NO_OPTION);// 0确定
																												// 1取消
					if (n == 0) {
						// 确定即保存
						CreatMapTxt();
					}
				} else {
					// 不存在文件则创建文件
					CreatMapTxt();
				}
			}
		}
	}

	/**
	 * 创建地图文件
	 */
	void CreatMapTxt() {
		try {
			// 得到文件输出流
			FileOutputStream fos = new FileOutputStream(PATH + "\\diy" + level + ".map");
			// 将文件输出流包装成基本数据输出流
			DataOutputStream dos = new DataOutputStream(fos);
			// 从配置的接口中得到二维数组的大小(由于本类已经实现了上面的Mapconfig接口,所以可以直接用里面的数据)
			int i = MAP_HEIGHT / SOUREC_HEIGHT;
			int j = MAP_WIDTH / SOUREC_WIDTH;
			// 先数组的大小写入文件
			dos.writeInt(i);
			dos.writeInt(j);
			// 按顺序将三维数组写入文件,后面游戏读取地图的时候也要按这种顺序读回来
			for (int ii = 0; ii < i; ii++) {
				for (int jj = 0; jj < j; jj++) {
					dos.writeInt(map1[ii][jj][0]);
				}
			}
			// 强制流中的数据完全输出完
			dos.flush();
			// 关闭输出流
			dos.close();
		} catch (Exception ef) {
			ef.printStackTrace();
		}
		System.out.println("保存成功");
	}

}

 The code optimization

In fact, there are many places in the code can be optimized, I have not optimized. Because it may involve things behind. For example, we can not require imageicon array to hold the coordinates of each picture, can use digital pictures substitution, to coordinate when the paint, remove the number from the int array, and then through a getimage Hu Olympic channel its corresponding picture. Another example, not necessary to provide a key listener class. Because he was a key. . .

  • Tools Utils.java

Of course, the tools essential ah, tools used

package cn.edu.caztc.sokobangame;

import java.io.File;

public class Utils{
	
	/**
	 * 判断是否存在文件file
	 * 
	 * @param file 如:D:\\推箱子\\1.map
	 * @return 存在即为true
	 */
	static boolean IsExistence(String file) {
		File fileuser = new File(file);
		if (!fileuser.exists()) {
			return false;
		}
		return true;
	}

}
  • Test class test.java

Such a map editor to do the work, we simply create a test class test

final effect

 

If you have questions, contact QQ1179307527. Gangster If there is an error, please correct me.

Taught you do Sokoban game --JAVA GUI (a)

Taught you do Sokoban game --JAVA GUI (ii)

Taught you do Sokoban game --JAVA GUI (c)

Taught you do Sokoban game --JAVA GUI (d)

Taught you do Sokoban game --JAVA GUI (V)

Guess you like

Origin blog.csdn.net/qq_40176716/article/details/96454589