用JAVA制作小游戏——推箱子(三)

本篇博客主要是对推箱子地图编辑器功能的代码讲解。
首先给出这段代码的部分运行截图
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

重难点:

地图编辑器主要有三个重难点
需要有一个绘制地图的界面
能够实现地图绘制的功能
地图绘制完成后需要将地图内容保存下来
下面就是每块内容的代码片段:

界面显示

界面显示分成绘图区与功能区
绘图区为label数组(大小为20*20)
功能区为8个按钮,对应各自的功能

public void init() {
    
    //界面显示
		for(i=0;i<20;i++) {
    
    
			for(j=0;j<20;j++) {
    
    
				mymap[i][j]=0;
				jl[i][j]=new JLabel(new ImageIcon());//实例化label
				this.add(jl[i][j]);
				jl[i][j].addMouseListener(new mouse());//label添加监听器
				jl[i][j].setBounds(i*30+90, j*30+20, 30, 30);//设置label位置和大小
				jl[i][j].setOpaque(true);//true表示不透明,false表示透明
			}
		}
		//窗体添加控件
		this.add(jb1);this.add(jb2);
		this.add(jb3);this.add(jb4);
		this.add(jb5);this.add(jb6);
		this.add(jb7);this.add(jb8);
		//按钮设置位置和大小
		jb1.setBounds(35, 640, 80, 40);jb2.setBounds(125, 640, 80, 40);
		jb3.setBounds(215, 640, 80, 40);jb4.setBounds(305, 640, 80, 40);
		jb8.setBounds(395, 640, 80, 40);jb5.setBounds(485, 640, 80, 40);
		jb6.setBounds(575, 640, 80, 40);jb7.setBounds(665, 640, 80, 40);
		//给按钮添加鼠标事件
		jb1.addMouseListener(new mouse());jb2.addMouseListener(new mouse());
		jb3.addMouseListener(new mouse());jb4.addMouseListener(new mouse());
		jb5.addMouseListener(new mouse());jb6.addMouseListener(new mouse());
		jb7.addMouseListener(new mouse());jb8.addMouseListener(new mouse());
		//设置按钮背景
		jb1.setBackground(new Color(140,199,181));jb2.setBackground(new Color(140,199,181));
		jb3.setBackground(new Color(140,199,181));jb4.setBackground(new Color(140,199,181));
		jb5.setBackground(new Color(140,199,181));jb6.setBackground(new Color(140,199,181));
		jb7.setBackground(new Color(140,199,181));jb8.setBackground(new Color(140,199,181));
	}

主要功能实现

地图的绘制功能需要鼠标先点击想要绘制的图片相对应的按钮,然后再点击label后就可以在点击的label上面显示相对应的图片。但对于墙块,空白块一个个点击太过繁琐,所以可以使用持续按压进行绘制,但由于java中没有专门对鼠标持续按压进行监听的监听器,所以只能通过对鼠标按压与释放,进入的监听器进行组合实现上述功能。
当鼠标按压时,标识符为1,当鼠标释放时,标识符为0,只有当标识符为1且进入label就改变label的图片。

class mouse extends MouseAdapter{
    
    
		@Override
		public void mousePressed(MouseEvent e) {
    
    //鼠标按压事件
			// TODO Auto-generated method stub
			if(e.getSource()==jb1) {
    
    pd=1;}//点击“墙块”按钮
			else if(e.getSource()==jb2) {
    
    pd=2;}//点击“玩家”按钮
			else if(e.getSource()==jb3) {
    
    pd=3;}//点击“箱子”按钮
			else if(e.getSource()==jb4) {
    
    pd=4;}//点击“目的地”按钮
			else if(e.getSource()==jb5) {
    
    //点击“清空”按钮
				for(i=0;i<20;i++) {
    
    
					for(j=0;j<20;j++) {
    
    
						jl[i][j].setIcon(new ImageIcon());//改变label图片
						mymap[i][j]=0;//改变label对应数据
					}
				}
			}
			else if(e.getSource()==jb6) {
    
    save();}//点击“保存”按钮
			else if(e.getSource()==jb7) {
    
    new game_tui_1();dispose();}//点击“返回”按钮
			else if(e.getSource()==jb8) {
    
    pd=5;}//点击“空白块”按钮
			else {
    
    //点击label
				for(i=0;i<20;i++) {
    
    
					for(j=0;j<20;j++) {
    
    
						if(e.getSource()==jl[i][j]) {
    
    //获取点击了哪个label
							pd_press=1;//用于标识判断按压
							if(pd==0) {
    
    }//pd=0表示没有点击任何按钮,点击label不做任何操作
							else if(pd==1) {
    
    jl[i][j].setIcon(new ImageIcon("shiyan4_image/wall.png"));mymap[i][j]=1;}//将label显示图片墙块
							else if(pd==2) {
    
    jl[i][j].setIcon(new ImageIcon("shiyan4_image/player.png"));mymap[i][j]=5;}//将label显示图片玩家
							else if(pd==3) {
    
    jl[i][j].setIcon(new ImageIcon("shiyan4_image/box1.png"));mymap[i][j]=3;}//将label显示图片箱子
							else if(pd==4) {
    
    jl[i][j].setIcon(new ImageIcon("shiyan4_image/destination.png"));mymap[i][j]=4;}//将label显示图片目的地
							else if(pd==5) {
    
    jl[i][j].setIcon(new ImageIcon());mymap[i][j]=0;}//将label显示空白块
						} 
					}
				}
			}
		}
		@Override
		public void mouseReleased(MouseEvent e) {
    
    //鼠标释放事件
			// TODO Auto-generated method stub
			for(int i=0;i<20;i++) {
    
    
				for(int j=0;j<20;j++) {
    
    
					if(e.getSource()==jl[i][j]) {
    
    
						pd_press=0;//释放将按压标识改回0
					}
				}
			}
		}
		@Override
		public void mouseEntered(MouseEvent e) {
    
    //鼠标进入事件
			// TODO Auto-generated method stub
			//长按绘图
			for(int i=0;i<20;i++) {
    
    
				for(int j=0;j<20;j++) {
    
    
					if(e.getSource()==jl[i][j]&&pd_press==1) {
    
    //鼠标进入label且处在按压
						if(pd==0) {
    
    }//pd=0表示没有点击任何按钮,点击label不做任何操作
						else if(pd==1) {
    
    jl[i][j].setIcon(new ImageIcon("shiyan4_image/wall.png"));mymap[i][j]=1;}//绘图墙块
						else if(pd==5) {
    
    jl[i][j].setIcon(new ImageIcon());mymap[i][j]=0;}//绘图空白块
					} 
				}
			}
		}
	}

地图写入

地图写入是在点击保存按钮后需要实现的,且地图不是任何时候都能保存的,需要一个简单的判断,需要满足以下条件:
存在玩家控制的方块,且只有一个
存在箱子 和 目的地
箱子和目的地的数量相等
这些判断条件可以使玩家绘制出的地图更具有可玩性。

public void save() {
    
    //保存数据到文件
		// TODO Auto-generated method stub
          String content="";FileOutputStream fout;byte[] b;
		try {
    
    
			File file=new File("shiyan4_maps\\11.map");//文件路径,根据实际自行修改
			if(!file.exists())  file.createNewFile();//判断11.map文件是否存在,不存在新建一个
			fout=new FileOutputStream(file,false); //创建文件输出流,false代表覆盖修改,ture代表添加修改
												//覆盖修改:覆盖之前的内容   添加修改:保留之前的内容,在原来基础上添加内容
			for(int i=0;i<20;i++) {
    
    
				for(int j=0;j<20;j++) {
    
    
					content=content+mymap[j][i];
				}
				if(i!=19)
				content=content+"\r\n";//“\r\n” 是回车
			}
			b=content.getBytes();
			if(pd_save()==1) {
    
    //判断是否要保存
            fout.write(b);//文件写入
            JOptionPane.showMessageDialog(null, "                       文件写入成功!!", "消息",JOptionPane.PLAIN_MESSAGE);
			}
			else {
    
    JOptionPane.showMessageDialog(null, "        文件写入失败!!", "消息",JOptionPane.ERROR_MESSAGE);
			}
			}
		catch (IOException e) {
    
    
			// TODO Auto-generated catch block
			e.getMessage();
		}
	}
	public int pd_save() {
    
    //判断是否要保存
		//保存要满足的条件:存在玩家控制,箱子数要等于目的地数
		int num_player=0,num_end=0,num_box=0;
		for(int i=0;i<20;i++) {
    
    
			for(int j=0;j<20;j++) {
    
    
				if(mymap[i][j]==5) num_player++;
				else if(mymap[i][j]==4) num_end++;
				else if(mymap[i][j]==3) num_box++;
			}
		}
		if(num_player!=1||num_end!=num_box||num_end==0)return 0;
		else return 1;
	}

最后附上 推箱子 地图编辑器功能 完整的代码

地图编辑器完整代码

import java.awt.Color;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import javax.swing.ImageIcon;
import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
public class game_tui_3 extends JFrame{
    
    
	JButton jb1 =new JButton("墙块");
	JButton jb2 =new JButton("玩家");
	JButton jb3 =new JButton("箱子");
	JButton jb4 =new JButton("目的地");
	JButton jb8 =new JButton("空白块");
	JButton jb5 =new JButton("清空");
	JButton jb6 =new JButton("保存");
	JButton jb7 =new JButton("返回");
	JLabel[][] jl=new JLabel[20][20];
	int[][] mymap=new int[20][20];int pd=0;
	int i=0,j=0;int pd_press=0;
	public game_tui_3() {
    
    
		//自定义方法
		init();//初始化
		//窗口属性
		this.setTitle("地图编辑器");//窗体名称
		this.setSize(800, 730);//窗体大小
		this.setDefaultCloseOperation(3);//窗体关闭按钮功能
		this.setLocationRelativeTo(null);//窗体居中
		this.setResizable(false);//窗体不可拉伸
		this.setLayout(null);
		this.getContentPane().setBackground(new Color(214,213,183));//设置背景颜色
		this.setVisible(true);//窗体可视
	}
	public static void main(String[] args) {
    
    
		// TODO Auto-generated method stub
		new game_tui_3();
	}
	public void save() {
    
    //保存地图数据到文件
		// TODO Auto-generated method stub
          String content="";FileOutputStream fout;byte[] b;
		try {
    
    
			File file=new File("shiyan4_maps\\11.map");//文件路径,根据实际自行修改
			if(!file.exists())  file.createNewFile();//判断11.map文件是否存在,不存在新建一个
			fout=new FileOutputStream(file,false); //创建文件输出流,false代表覆盖修改,ture代表添加修改
												//覆盖修改:覆盖之前的内容   添加修改:保留之前的内容,在原来基础上添加内容
			for(int i=0;i<20;i++) {
    
    
				for(int j=0;j<20;j++) {
    
    
					content=content+mymap[j][i];
				}
				if(i!=19)
				content=content+"\r\n";//“\r\n” 是回车
			}
				
			b=content.getBytes();
			if(pd_save()==1) {
    
    //判断是否要保存
            fout.write(b);
            JOptionPane.showMessageDialog(null, "                       文件写入成功!!", "消息",JOptionPane.PLAIN_MESSAGE);
			}
			else {
    
    JOptionPane.showMessageDialog(null, "        文件写入失败!!", "消息",JOptionPane.ERROR_MESSAGE);
			}
			}
		catch (IOException e) {
    
    
			// TODO Auto-generated catch block
			e.getMessage();
		}
	}
	public int pd_save() {
    
    //判断是否要保存
		//保存要满足的条件:存在玩家控制,箱子数要等于目的地数
		int num_player=0,num_end=0,num_box=0;
		for(int i=0;i<20;i++) {
    
    
			for(int j=0;j<20;j++) {
    
    
				if(mymap[i][j]==5) num_player++;
				else if(mymap[i][j]==4) num_end++;
				else if(mymap[i][j]==3) num_box++;
			}
		}
		if(num_player!=1||num_end!=num_box||num_end==0)return 0;
		else return 1;
	}
	public void init() {
    
    //界面显示
		for(i=0;i<20;i++) {
    
    
			for(j=0;j<20;j++) {
    
    
				mymap[i][j]=0;
				jl[i][j]=new JLabel(new ImageIcon());//实例化label
				this.add(jl[i][j]);
				jl[i][j].addMouseListener(new mouse());//label添加监听器
				jl[i][j].setBounds(i*30+90, j*30+20, 30, 30);//设置label位置和大小
				jl[i][j].setOpaque(true);//true表示不透明,false表示透明
			}
		}
		//窗体添加控件
		this.add(jb1);this.add(jb2);
		this.add(jb3);this.add(jb4);
		this.add(jb5);this.add(jb6);
		this.add(jb7);this.add(jb8);
		//按钮设置位置和大小
		jb1.setBounds(35, 640, 80, 40);jb2.setBounds(125, 640, 80, 40);
		jb3.setBounds(215, 640, 80, 40);jb4.setBounds(305, 640, 80, 40);
		jb8.setBounds(395, 640, 80, 40);jb5.setBounds(485, 640, 80, 40);
		jb6.setBounds(575, 640, 80, 40);jb7.setBounds(665, 640, 80, 40);
		//给按钮添加鼠标事件
		jb1.addMouseListener(new mouse());jb2.addMouseListener(new mouse());
		jb3.addMouseListener(new mouse());jb4.addMouseListener(new mouse());
		jb5.addMouseListener(new mouse());jb6.addMouseListener(new mouse());
		jb7.addMouseListener(new mouse());jb8.addMouseListener(new mouse());
		//设置按钮背景
		jb1.setBackground(new Color(140,199,181));jb2.setBackground(new Color(140,199,181));
		jb3.setBackground(new Color(140,199,181));jb4.setBackground(new Color(140,199,181));
		jb5.setBackground(new Color(140,199,181));jb6.setBackground(new Color(140,199,181));
		jb7.setBackground(new Color(140,199,181));jb8.setBackground(new Color(140,199,181));
	}
	class mouse extends MouseAdapter{
    
    
		@Override
		public void mousePressed(MouseEvent e) {
    
    //鼠标按压事件
			// TODO Auto-generated method stub
			if(e.getSource()==jb1) {
    
    pd=1;}//点击“墙块”按钮
			else if(e.getSource()==jb2) {
    
    pd=2;}//点击“玩家”按钮
			else if(e.getSource()==jb3) {
    
    pd=3;}//点击“箱子”按钮
			else if(e.getSource()==jb4) {
    
    pd=4;}//点击“目的地”按钮
			else if(e.getSource()==jb5) {
    
    //点击“清空”按钮
				for(i=0;i<20;i++) {
    
    
					for(j=0;j<20;j++) {
    
    
						jl[i][j].setIcon(new ImageIcon());//改变label图片
						mymap[i][j]=0;//改变label对应数据
					}
				}
			}
			else if(e.getSource()==jb6) {
    
    save();}//点击“保存”按钮
			else if(e.getSource()==jb7) {
    
    /*new game_tui_1();dispose();*/}//点击“返回”按钮,由于单独代码,所以页面跳转代码注释了
			else if(e.getSource()==jb8) {
    
    pd=5;}//点击“空白块”按钮
			else {
    
    //点击label
				for(i=0;i<20;i++) {
    
    
					for(j=0;j<20;j++) {
    
    
						if(e.getSource()==jl[i][j]) {
    
    //获取点击了哪个label,图片路径根据实际自行修改
							pd_press=1;//用于标识判断按压
							if(pd==0) {
    
    }//pd=0表示没有点击任何按钮,点击label不做任何操作
							else if(pd==1) {
    
    jl[i][j].setIcon(new ImageIcon("shiyan4_image/wall.png"));mymap[i][j]=1;}//将label显示图片墙块
							else if(pd==2) {
    
    jl[i][j].setIcon(new ImageIcon("shiyan4_image/player.png"));mymap[i][j]=5;}//将label显示图片玩家
							else if(pd==3) {
    
    jl[i][j].setIcon(new ImageIcon("shiyan4_image/box1.png"));mymap[i][j]=3;}//将label显示图片箱子
							else if(pd==4) {
    
    jl[i][j].setIcon(new ImageIcon("shiyan4_image/destination.png"));mymap[i][j]=4;}//将label显示图片目的地
							else if(pd==5) {
    
    jl[i][j].setIcon(new ImageIcon());mymap[i][j]=0;}//将label显示空白块
						} 
					}
				}
			}
		}
		@Override
		public void mouseReleased(MouseEvent e) {
    
    //鼠标释放事件
			// TODO Auto-generated method stub
			for(int i=0;i<20;i++) {
    
    
				for(int j=0;j<20;j++) {
    
    
					if(e.getSource()==jl[i][j]) {
    
    
						pd_press=0;//释放将按压标识改回0
					}
				}
			}
		}
		@Override
		public void mouseEntered(MouseEvent e) {
    
    //鼠标进入事件
			// TODO Auto-generated method stub
			//长按绘图
			for(int i=0;i<20;i++) {
    
    
				for(int j=0;j<20;j++) {
    
    
					if(e.getSource()==jl[i][j]&&pd_press==1) {
    
    //鼠标进入label且处在按压,图片路径根据实际自行修改
						if(pd==0) {
    
    }//pd=0表示没有点击任何按钮,点击label不做任何操作
						else if(pd==1) {
    
    jl[i][j].setIcon(new ImageIcon("shiyan4_image/wall.png"));mymap[i][j]=1;}//绘图墙块
						else if(pd==5) {
    
    jl[i][j].setIcon(new ImageIcon());mymap[i][j]=0;}//绘图空白块
					} 
				}
			}
		}
	}
}
如有错误
欢迎指出

下一篇:用JAVA制作小游戏——推箱子(四)

猜你喜欢

转载自blog.csdn.net/zjl0409/article/details/112084840