Java实战推箱子——菜鸟之路

【经典项目】Java小游戏 —— 推箱子 用Java实现推箱子的小游戏,推箱子是一种益智解谜类的小游戏,玩家需要通过推动箱子将它们放置到指定的位置,以完成关卡的任务。 阅读详情

    当时找了很久也没找到几个实战的教程视频,最后还是花了半天看了网络上的一些源码和思路然后来写了这个。总体感觉自己写的还是很烂,写这个的时候自己并没有写地图,而是引用了网络上的地图(用0~9来标记不同的图真的是给绘制地图较低了很大一部分难度)。

    先来说一下要来做什么,我们想要实现的就是传统的推箱子小游戏。那传统的推箱子小游戏有什么,他的背景很大,并且你需要不同的地方来标志你的地图,以下列我所写的程序为例。传统的推箱子游戏(恩。。我记得当年小时候的直板手机上就是有这些功能),可以根据用户的要求,跳到第一关,上一关,下一关,最后一关,也可以重新开始,悔棋,选关等操作。这里想问一个问题为什么按钮只要写四个字就会只显示两个字其他都隐藏呢。。我改了按钮大小当时也是这种情况比较迷。

  说了这么多废话还是总结一下,我们需要实现的需求吧。

  1.用户界面上的一些东西

  (1)存在一个选项菜单栏,我们需要给出如下子菜单功能的实现。重新开始、上一关、下一关、选择关卡、悔一步、退出。当然还包括一个分割线。

  (2)存在一个设置音乐菜单栏,存在你所写的歌的名称,我的就很low的一下这几个了。当然他们是互斥的,所以当点下一歌菜单栏按钮时,你需要从视觉上反馈给用户当前正在播放的音乐是什么。

  (3)存在一个帮助菜单栏,下面有个名叫关于此游戏的选项,恩。。。这个就胡乱蹦出一个信息就好,比如一个消息对话框。

  (4)就是对应操作的一些按钮了。在这里添加了,重玩,悔一步,第一关,上一关,下一关,选关,最终关,音乐关 恩点一下它可以变为音乐开(意思就是关闭音乐,打开音乐 我这里因为我的low 写不出四个以上的字就用了三个字代替)。

  (5)还有一个就是更换音乐的一个下拉菜单了。这个也没什么好讲的。至于这个黄色的“更换音乐”,直接显示文字就好。

  (6)每次通关后要蹦出一个消息对话框问你是否进入下一关

  2.就是地图也就是画板了 我这里定义了一个20*20这么多的小图片拼成的地图。emmm。。。个人没什么审美 丑的一p。

  这里不做过多的赘述,要讲的基本上我都在代码的注释里讲了。就多说几句关于这个游戏判断的东西吧,这里使用的方法是用不同的数字来代表不同的图片,也就是不同的方块,这样更加方便我们去进行移动和生成地图,还有判断输赢。个人感觉这个游戏只要看一看JFrame基本上就不会有太大的难度。代码中唯一麻烦的就是移动的一些判断了,其实只需要写出一个来然后复制改下标就可以了。复述一句,注意我的下标,当时建立的窗口坐标和自己二维数组坐标不一样,然后自己也懒得增加修改量了,望谅解,哈哈哈。

  我的虫子是四个方向不同的图片。所以说你要考虑走不动时按不同的键位,图片要进行刷新。恩,先给出代码吧,后续我会添加详细的关于JFrame方面的应用和理解,还有该代码的详细解释还有几个游戏的详解。恩,要下课了,准备溜了溜了。。

先给出客户端的类代码实现:

package xyz.lzw.box;
/**
 * 游戏实现 客户端
 */
import java.awt.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.ItemEvent;
import java.awt.event.ItemListener;

import javax.swing.*;


public class mainFrame extends JFrame implements ActionListener,ItemListener {
	JLabel lb;
	JLabel lb2;
	JButton renew1,last1,choose1,first1,over1,muc1,back1,next1;
	MainPanel panel;
	Sound sound;
	//菜单栏
	JComboBox jc = new JComboBox();
	MenuItem renew = new MenuItem("重新开始");
	MenuItem back = new MenuItem("悔一步");
	MenuItem last = new MenuItem("上一关");
	MenuItem next = new MenuItem("下一关");
	MenuItem choose = new MenuItem("选择关卡");
	MenuItem exit = new MenuItem("退出");
	MenuItem qin = new MenuItem("琴箫合奏");
	MenuItem guang = new MenuItem("BGM");
	MenuItem mid1 = new MenuItem("mid1");
	MenuItem mid2 = new MenuItem("mid2");
	MenuItem nor = new MenuItem("默认");
	MenuItem about = new MenuItem("关于此游戏");
	//构造函数,实现图形用户界面
	mainFrame(){
		super("Puppet制作 恶搞小游戏");
		setSize(720,720);
		setVisible(true);
		setResizable(false);  //设置窗体的大小不可随意改变
		setLocation(320,20);
		setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		//创建一个容器 并将JFrame窗体转换为容器
		Container conter = getContentPane();
		conter.setLayout(null);
		conter.setBackground(Color.BLACK);
		lb = new JLabel("推箱子~",SwingConstants.CENTER);
		lb2 = new JLabel("更换音乐",SwingConstants.CENTER);
		add(lb);
		add(lb2);
		lb.setBounds(100,20,400,20);
		lb.setForeground(Color.YELLOW);
		lb2.setBounds(625, 500, 55, 20);
		lb2.setForeground(Color.YELLOW);
		//按钮
		renew1 = new JButton("重玩");
		add(renew1);
		back1 = new JButton("悔一步");
		add(back1);
		last1 = new JButton("上一关");
		add(last1);
		next1 = new JButton("下一关");
		add(next1);
		choose1 = new JButton("选关");
		add(choose1);
		first1 = new JButton("第1关");
		add(first1);
		over1 = new JButton("最终关");
		add(over1);
		muc1 = new JButton("音乐关");
		add(muc1);
		renew1.setBounds(625, 100, 80, 40);
		renew1.addActionListener(this);
		
		back1.setBounds(625, 150, 80, 40);
		back1.addActionListener(this);
		
		first1.setBounds(625, 200, 80, 40);
		first1.addActionListener(this);

		last1.setBounds(625, 250, 80, 40);
		last1.addActionListener(this);

		next1.setBounds(625, 300, 80, 40);
		next1.addActionListener(this);
		
		choose1.setBounds(625, 350, 80, 40);
		choose1.addActionListener(this);
	
		over1.setBounds(625, 400, 80, 40);
		over1.addActionListener(this);

		muc1.setBounds(625, 450, 80, 40);
		muc1.addActionListener(this);
		//更换音乐里的下拉菜单标题
		jc.setBounds(625, 530, 80, 25);
		jc.addItem("默认");
		jc.addItem("琴箫合奏");
		jc.addItem("BGM");
		jc.addItem("经典");
		jc.addItem("流行");
		jc.addItemListener(this);
		conter.add(jc);
		//子菜单栏
		Menu choices = new Menu("选项");
		choices.add(renew);
		choices.add(last);
		choices.add(next);
		choices.add(choose);
		choices.add(back);
		choices.addSeparator();
		choices.add(exit);
		renew.addActionListener(this);
		last.addActionListener(this);
		next.addActionListener(this);
		choose.addActionListener(this);
		back.addActionListener(this);
		exit.addActionListener(this);
		//子菜单栏
		Menu setmusic = new Menu("设置音乐");
		setmusic.add(nor);
		setmusic.add(qin);
		setmusic.add(guang);
		setmusic.add(mid1);
		setmusic.add(mid2);
		nor.addActionListener(this);
		qin.addActionListener(this);
		guang.addActionListener(this);
		mid1.addActionListener(this);
		mid2.addActionListener(this);
		Menu help = new Menu("帮助");
		help.add(about);
		about.addActionListener(this);
		//菜单
		MenuBar bar = new MenuBar();
		bar.add(choices);
		bar.add(setmusic);
		bar.add(help);
		setMenuBar(bar);
		nor.setEnabled(false);
		
		sound = new Sound();
		sound.loadSound();
		panel = new MainPanel();
		add(panel);
		panel.PutBox(panel.level);
		panel.requestFocus();
		validate();
	}
	//返回画板上按钮的监听,来看用户点下了什么按钮,同时进行不同操作
	@Override
	public void actionPerformed(ActionEvent e) {
		//重玩
		if(e.getSource()==renew1||e.getSource()==renew) {
			panel.PutBox(panel.level);
			panel.requestFocus();
			panel.remove();
		}
		//上一关
		else if(e.getSource()==last||e.getSource()==last1) {
			panel.level--;
			//判断是否为第一关 从而执行不同操作
			if(panel.level<1) {
				panel.level++;
			JOptionPane.showMessageDialog(this, "本关是是第一关,无法继续返回上一关卡");
			panel.requestFocus();
			}
			else {
				panel.PutBox(panel.level);
				panel.requestFocus();
			}
			panel.remove();
		}
		//下一关
		else if(e.getSource()==next||e.getSource()==next1) {
			panel.level++;
			//判断是否是最后一关 从而进行不同操作
			if(panel.level>panel.maxlevel()) {
				panel.level--;
				JOptionPane.showMessageDialog(this, "本关已经是最后一关 无法进入下一关");
				panel.requestFocus();
			}
			else {
				panel.PutBox(panel.level);
				panel.requestFocus();
			}
			panel.remove();
		}
		//最终关
		else if(e.getSource()==over1) {
			panel.level=panel.maxlevel();
			panel.PutBox(panel.level);
			panel.requestFocus();
			panel.remove();
		}
		//退出 结束游戏
		else if(e.getSource()==exit) {
			System.exit(0);
		}
		//帮助
		else if(e.getSource()==about) {
			JOptionPane.showMessageDialog(this, "PUPPET制作 非完善版");
		}
		//选关
		else if(e.getSource()==choose||e.getSource()==choose1) {
			String tmpp = JOptionPane.showInputDialog(this,"请输入您要跳转到的关卡号:(1~50)");
			panel.level=Integer.parseInt(tmpp);
			panel.remove();
			if(panel.level>panel.maxlevel()||panel.level<1) {
				JOptionPane.showMessageDialog(this, "不存在该关卡!!!!");
				panel.requestFocus();
			}
			else {
				panel.PutBox(panel.level);
				panel.requestFocus();
			}
		}
		//第一关
		else if(e.getSource()==first1) {
			panel.level=1;
			panel.PutBox(panel.level);
			panel.requestFocus();
			panel.remove();
		}
		//音乐开/关
		else if(e.getSource()==muc1) {
			if(sound.isplay()) {
				sound.mystop();
				muc1.setLabel("音乐开");
			}
			else {
				sound.loadSound();
				muc1.setLabel("音乐关");
			}
			panel.requestFocus();
		}
		//上一步
		else if(e.getSource()==back1||e.getSource()==back) {
			if(panel.isMystackEmpty()) {
				JOptionPane.showMessageDialog(this, "你还未进行移动,无法返回上一步~~~");
			}
			else {
				switch(panel.back()) {
				case 10:panel.backup(10);break;
				case 11:panel.backup(11);break;
				case 20:panel.backdown(20);break;
				case 21:panel.backdown(21);break;
				case 30:panel.backleft(30);break;
				case 31:panel.backleft(31);break;
				case 40:panel.backright(40);break;
				case 41:panel.backright(41);break;
				}
			}
			panel.requestFocus();
		}
		//音乐下拉菜单里的默认音乐
		else if(e.getSource()==nor) {
			jc.setSelectedIndex(0);
		}
		//音乐下拉菜单里的琴箫合奏音乐
		else if(e.getSource()==qin) {
			jc.setSelectedIndex(1);
		}
		//音乐下拉菜单里的灌篮高手音乐
		else if(e.getSource()==guang) {
			jc.setSelectedIndex(2);
		}
		//音乐下拉菜单里的经典音乐
		else if(e.getSource()==mid1) {
			jc.setSelectedIndex(3);
		}
		//音乐下拉菜单里的流行音乐
		else if(e.getSource()==mid2) {
			jc.setSelectedIndex(4);
		}
	}
	//更换音乐
	@Override
	public void itemStateChanged(ItemEvent ie) {
		int numm = jc.getSelectedIndex();
		switch(numm) {
			case 0:
				sound.setMusic("nor.mid");
				if(sound.isplay()) {
					sound.mystop();
				}
				sound.loadSound();
				muc1.setLabel("音乐关");
				nor.setEnabled(false);
				qin.setEnabled(true);
				guang.setEnabled(true);
				mid1.setEnabled(true);
				mid2.setEnabled(true);
				panel.requestFocus();
				break;
			case 1: 
				sound.setMusic("qin.mid");
				if(sound.isplay()) {
					sound.mystop();
				}
				sound.loadSound();
				muc1.setLabel("音乐关");
				nor.setEnabled(true);
				qin.setEnabled(false);
				guang.setEnabled(true);
				mid1.setEnabled(true);
				mid2.setEnabled(true);
				panel.requestFocus();
				break;
			case 2: 
				sound.setMusic("guang.mid");
				if(sound.isplay()) {
					sound.mystop();
				}
				sound.loadSound();
				muc1.setLabel("音乐关");
				nor.setEnabled(true);
				qin.setEnabled(true);
				guang.setEnabled(false);
				mid1.setEnabled(true);
				mid2.setEnabled(true);
				panel.requestFocus();
				break;
			case 3: 
				sound.setMusic("mid1.mid");
				if(sound.isplay()) {
					sound.mystop();
				}
				sound.loadSound();
				muc1.setLabel("音乐关");
				nor.setEnabled(true);
				qin.setEnabled(true);
				guang.setEnabled(true);
				mid1.setEnabled(false);
				mid2.setEnabled(true);
				panel.requestFocus();
				break;
			case 4: 
				sound.setMusic("mid2.mid");
				if(sound.isplay()) {
					sound.mystop();
				}
				sound.loadSound();
				muc1.setLabel("音乐关");
				nor.setEnabled(true);
				qin.setEnabled(true);
				guang.setEnabled(true);
				mid1.setEnabled(true);
				mid2.setEnabled(false);
				panel.requestFocus();
				break;
		}
	}
}

之后是画板类的代码(也就是俗称的画地图的东西):

package xyz.lzw.box;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Toolkit;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Stack;

import javax.swing.JOptionPane;
import javax.swing.JPanel;

/**
 * 画板 界面
 */
public class MainPanel extends JPanel implements KeyListener {
	int max = 50;
	int[][] map,maptmp;
	int X,Y,boxnum;
	Image[] myImage;
	Map Levelmap;
	Map Levelmaptmp;
	int len = 30;
	public int level = 1;
	Stack mystack = new Stack();
	//构造函数 将图片导入
	MainPanel(){
		setBounds(15,50,600,600);
		setBackground(Color.WHITE);
		addKeyListener(this);
		myImage = new Image[10];
		for(int i = 0;i < 10;i++) {
			myImage[i] = Toolkit.getDefaultToolkit().getImage("pic\\"+i+".gif");
		}
		setVisible(true);
	}
	//加载地图
	void PutBox(int i) {
		Levelmap = new Map(i);
		Levelmaptmp = new Map(i);
		map = Levelmap.getmap();
		X = Levelmap.getX();
		Y = Levelmap.getY();
		maptmp = Levelmaptmp.getmap();
		repaint(); //重画
	}
	//返回最高的关卡
	int maxlevel() {
		return max;
	}
	//画地图
	public void paint(Graphics g) {
		for(int i = 0;i < 20;i++)
			for(int j = 0;j < 20;j++) {
				g.drawImage(myImage[map[j][i]], i*len, j*len, this);
			}
		g.setColor(new Color(0,0,0));
		g.setFont(new Font("楷体_2312",Font.BOLD,30));
		g.drawString("第", 240, 40);
		g.drawString(String.valueOf(level), 310, 40);
		g.drawString("层", 360, 40);
	}
	@Override
	public void keyPressed(KeyEvent e) {
		//由键盘返回上下左右四个方向上的移动
		if(e.getKeyCode()==KeyEvent.VK_UP){
			moveup();
		}
		else if(e.getKeyCode()==KeyEvent.VK_DOWN) {
			movedown();
		}
		else if(e.getKeyCode()==KeyEvent.VK_LEFT) {
			moveleft();
		}
		else if(e.getKeyCode()==KeyEvent.VK_RIGHT) {
			moveright();
		}
		//判断过关后进行的不同操作
		if(win()) {
			//通关了则提示打通全关
			if(level == max) {
				JOptionPane.showMessageDialog(this, "恭喜您打通全关!!!");
			}
			//弹出一个对话框提示是否进行下一关
			else {
				String message = "恭喜您通过了第" + level +"关!\n是否要进入下一关?";
				int type = JOptionPane.YES_NO_OPTION;
				String title = "恭喜过关!!!";
				int option = JOptionPane.showConfirmDialog(null, message,title,type);
				if(option == 1)
					System.exit(0);
				else if(option == 0) {
					level++;
					PutBox(level);
				}	
			}
			mystack.removeAllElements();
		}
	}
	@Override
	public void keyReleased(KeyEvent e) {
	}
	@Override
	public void keyTyped(KeyEvent e) {
	}
	//判空
	boolean isMystackEmpty() {
		return mystack.isEmpty();
	}
	int back() {
		return (Integer)mystack.pop();
	}
	//清空
	void remove() {
		mystack.removeAllElements();
	}
	//四个方向的移动和悔步 这里要考虑走这一步时能不能走 走过去是什么情况
	void moveup() {
		if(map[Y-1][X]==2||map[Y-1][X]==4) {
			if(maptmp[Y][X]==4||maptmp[Y][X]==9)
				map[Y][X]=4;
			else
				map[Y][X]=2;
			map[Y-1][X]=8;
			repaint();
			Y--;
			mystack.push(10);
		}
		else if(map[Y-1][X]==3) {
			if(map[Y-2][X]==4) {
				if(maptmp[Y][X]==4||maptmp[Y][X]==9)
					map[Y][X]=4;
				else 
					map[Y][X]=2;
				map[Y-1][X]=8;
				map[Y-2][X]=9;
				repaint();
				Y--;
				mystack.push(11);
			}
			else if(map[Y-2][X]==2) {
				if(maptmp[Y][X]==4||maptmp[Y][X]==9)
					map[Y][X]=4;
				else 
					map[Y][X]=2;
				map[Y-1][X]=8;
				map[Y-2][X]=3;
				repaint();
				Y--;
				mystack.push(11);
			}
			else {
				map[Y][X]=8;
				repaint();
			}
		}
		else if(map[Y-1][X]==9) {
			if(map[Y-2][X]==4) {
				if(maptmp[Y][X]==4||maptmp[Y][X]==9)
					map[Y][X]=4;
				else
					map[Y][X]=2;
				map[Y-1][X]=8;
				map[Y-2][X]=9;
				repaint();
				Y--;
				mystack.push(11);
			}
			else if(map[Y-2][X]==2) {
				if(maptmp[Y][X]==4||maptmp[Y][X]==9)
					map[Y][X]=4;
				else
					map[Y][X]=2;
				map[Y-1][X]=8;
				map[Y-2][X]=3;
				repaint();
				Y--;
				mystack.push(11);
			}
			else {
				map[Y][X]=8;
				repaint();
			}
		}
		if(map[Y-1][X]==1) {
			map[Y][X]=8;
			repaint();
		}
	}
	void backup(int t) {
		int cnt = t;
		if(cnt == 10) {
			if(maptmp[Y][X]==4||maptmp[Y][X]==9) {
				map[Y][X]=4;
			}
			else
				map[Y][X]=2;
		}
		else if(cnt == 11) {
			if(maptmp[Y][X]==4||maptmp[Y][X]==9)
			{
				map[Y][X]=9;
			}
			else
				map[Y][X]=3;
			if(maptmp[Y-1][X]==4||maptmp[Y-1][X]==9) {
				map[Y-1][X]=4;
			}
			else 
				map[Y-1][X]=2;
		}
		map[Y+1][X]=8;
		repaint();
		Y++;
	}
	void movedown() {
		if(map[Y+1][X]==2||map[Y+1][X]==4) {
			if(maptmp[Y][X]==4||maptmp[Y][X]==9)
				map[Y][X]=4;
			else
				map[Y][X]=2;
			map[Y+1][X]=5;
			repaint();
			Y++;
			mystack.push(20);
		}
		else if(map[Y+1][X]==3) {
			if(map[Y+2][X]==4) {
				if(maptmp[Y][X]==4||maptmp[Y][X]==9)
					map[Y][X]=4;
				else 
					map[Y][X]=2;
				map[Y+1][X]=5;
				map[Y+2][X]=9;
				repaint();
				Y++;
				mystack.push(21);
			}
			else if(map[Y+2][X]==2) {
				if(maptmp[Y][X]==4||maptmp[Y][X]==9)
					map[Y][X]=4;
				else 
					map[Y][X]=2;
				map[Y+1][X]=5;
				map[Y+2][X]=3;
				repaint();
				Y++;
				mystack.push(21);
			}
			else {
				map[Y][X]=5;
				repaint();
			}
		}
		else if(map[Y+1][X]==9) {
			if(map[Y+2][X]==4) {
				if(maptmp[Y][X]==4||maptmp[Y][X]==9)
					map[Y][X]=4;
				else
					map[Y][X]=2;
				map[Y+1][X]=5;
				map[Y+2][X]=9;
				repaint();
				Y++;
				mystack.push(21);
			}
			else if(map[Y+2][X]==2) {
				if(maptmp[Y][X]==4||maptmp[Y][X]==9)
					map[Y][X]=4;
				else
					map[Y][X]=2;
				map[Y+1][X]=5;
				map[Y+2][X]=3;
				repaint();
				Y++;
				mystack.push(21);
			}
			else {
				map[Y][X]=5;
				repaint();
			}
		}
		if(map[Y+1][X]==1) {
			map[Y][X]=5;
			repaint();
		}
	}
	void backdown(int t) {
		int cnt = t;
		if(cnt == 20) {
			if(maptmp[Y][X]==4||maptmp[Y][X]==9) {
				map[Y][X]=4;
			}
			else
				map[Y][X]=2;
		}
		else if(cnt == 21) {
			if(maptmp[Y][X]==4||maptmp[Y][X]==9)
			{
				map[Y][X]=9;
			}
			else
				map[Y][X]=3;
			if(maptmp[Y+1][X]==4||maptmp[Y+1][X]==9) {
				map[Y+1][X]=4;
			}
			else 
				map[Y+1][X]=2;
		}
		map[Y-1][X]=5;
		repaint();
		Y--;
	}
	void moveleft() {
		if(map[Y][X-1]==2||map[Y][X-1]==4) {
			if(maptmp[Y][X]==4||maptmp[Y][X]==9)
				map[Y][X]=4;
			else
				map[Y][X]=2;
			map[Y][X-1]=6;
			repaint();
			X--;
			mystack.push(30);
		}
		else if(map[Y][X-1]==3) {
			if(map[Y][X-2]==4) {
				if(maptmp[Y][X]==4||maptmp[Y][X]==9)
					map[Y][X]=4;
				else 
					map[Y][X]=2;
				map[Y][X-1]=6;
				map[Y][X-2]=9;
				repaint();
				X--;
				mystack.push(31);
			}
			else if(map[Y][X-2]==2) {
				if(maptmp[Y][X]==4||maptmp[Y][X]==9)
					map[Y][X]=4;
				else 
					map[Y][X]=2;
				map[Y][X-1]=6;
				map[Y][X-2]=3;
				repaint();
				X--;
				mystack.push(31);
			}
			else {
				map[Y][X]=6;
				repaint();
			}
		}
		else if(map[Y][X-1]==9) {
			if(map[Y][X-2]==4) {
				if(maptmp[Y][X]==4||maptmp[Y][X]==9)
					map[Y][X]=4;
				else
					map[Y][X]=2;
				map[Y][X-1]=6;
				map[Y][X-2]=9;
				repaint();
				X--;
				mystack.push(31);
			}
			else if(map[Y][X-2]==2) {
				if(maptmp[Y][X]==4||maptmp[Y][X]==9)
					map[Y][X]=4;
				else
					map[Y][X]=2;
				map[Y][X-1]=6;
				map[Y][X-2]=3;
				repaint();
				X--;
				mystack.push(31);
			}
			else {
				map[Y][X]=6;
				repaint();
			}
		}
		if(map[Y][X-1]==1) {
			map[Y][X]=6;
			repaint();
		}
	}
	void backleft(int t)
	{
		int cnt=t;
		if(cnt == 30){
			if(maptmp[Y][X]==4||maptmp[Y][X]==9){
				map[Y][X]=4;
			}
			else 
				map[Y][X]=2;
		}
		else if(cnt==31){
			if(maptmp[Y][X]==4||maptmp[Y][X]==9){
				map[Y][X]=9;
			}
			else 
				map[Y][X]=3;
			if(maptmp[Y][X-1]==4||maptmp[Y][X-1]==9){
				map[Y][X-1]=4;
			}
			else 
				map[Y][X-1]=2;
		}
		map[Y][X+1]=6;
		repaint();
		X++;
	}
	void moveright() {
		if(map[Y][X+1]==2||map[Y][X+1]==4) {
			if(maptmp[Y][X]==4||maptmp[Y][X]==9)
				map[Y][X]=4;
			else
				map[Y][X]=2;
			map[Y][X+1]=7;
			repaint();
			X++;
			mystack.push(40);
		}
		else if(map[Y][X+1]==3) {
			if(map[Y][X+2]==4) {
				if(maptmp[Y][X]==4)
					map[Y][X]=4;
				else 
					map[Y][X]=2;
				map[Y][X+1]=7;
				map[Y][X+2]=9;
				repaint();
				X++;
				mystack.push(41);
			}
			else if(map[Y][X+2]==2) {
				if(maptmp[Y][X]==4)
					map[Y][X]=4;
				else 
					map[Y][X]=2;
				map[Y][X+1]=7;
				map[Y][X+2]=3;
				repaint();
				X++;
				mystack.push(41);
			}
			else {
				map[Y][X]=7;
				repaint();
			}
		}
		else if(map[Y][X+1]==9) {
			if(map[Y][X+2]==4) {
				if(maptmp[Y][X]==4||maptmp[Y][X]==9)
					map[Y][X]=4;
				else
					map[Y][X]=2;
				map[Y][X+1]=7;
				map[Y][X+2]=9;
				repaint();
				X++;
				mystack.push(41);
			}
			else if(map[Y][X+2]==2) {
				if(maptmp[Y][X]==4||maptmp[Y][X]==9)
					map[Y][X]=4;
				else
					map[Y][X]=2;
				map[Y][X+1]=7;
				map[Y][X+2]=3;
				repaint();
				X++;
				mystack.push(41);
			}
			else {
				map[Y][X]=7;
				repaint();
			}
		}
		else if(map[Y][X+1]==1) {
			map[Y][X]=7;
			repaint();
		}
	}
	void backright(int t)
	{
		int cnt=t;
		if(cnt == 40){
			if(maptmp[Y][X]==4||maptmp[Y][X]==9){
				map[Y][X]=4;
			}
			else 
				map[Y][X]=2;
		}
		else if(cnt == 41){
			if(maptmp[Y][X]==4||maptmp[Y][X]==9){
				map[Y][X]=9;
			}
			else 
				map[Y][X]=3;
			if(maptmp[Y][X+1]==4||maptmp[Y][X+1]==9){
				map[Y][X+1]=4;
			}
			else 
				map[Y][X+1]=2;
		}
		map[Y][X-1]=7;
		repaint();
		X--;
	}
	//判断是否通关 遍历以便看是否要求位置的标号是否存在即可
	boolean win() {
		boolean flag =false;
		out:for(int i = 0;i < 20;i++)
			  for(int j = 0;j< 20; j++) {
				  if(maptmp[i][j]==4||maptmp[i][j]==9)
					  if(map[i][j] == 9)
						  flag = true;
					  else {
						  flag = false;
						  break out;
					  }
			  }
		return flag;
	}
}

地图类的代码:

package xyz.lzw.box;
/**
 * 地图类
 */
import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;

public class Map {
	private int level,x,y;
	private int[][] mymap = new int[20][20];
	FileReader r;
	BufferedReader br;
	String b="";
	int t = 0;
	//主要是将地图文件导入到String中 然后改为int型存入到mymap中 存成一个表
	Map(int k){
		level = k;
		String s;
		try {
			File f =new File("maps\\" + level + ".map");
			r = new FileReader(f);
			br = new BufferedReader(r);
		}	catch(IOException e) {
			System.out.println(e);
		}
		
		try {
			while((s=br.readLine())!=null) {
				b = b + s;
			}
		}	catch(IOException g) {
			System.out.println(g);
		}
		byte[] db =b.getBytes();
		int len = b.length();
		int[] x1 = new int[len];
		for(int i = 0;i < b.length();i++)//转成int型
			x1[i] = db[i] -48;
		for(int i = 0;i < 20;i++) {
			for(int j = 0;j < 20 ;j++) {
				mymap[i][j] = x1[t];
				if(mymap[i][j]==5) {//记录虫子当前所在位置
					x = j;
					y = i;
				}
				t++;
			}
		}
	}
	//获得地图
	int[][] getmap(){
		return mymap;
	}
	//获得X
	int getX() {
		return x;
	}
	//获得Y
	int getY() {
		return y;
	}
}

声音类:

package xyz.lzw.box;
/**
 * 声音类
 */
import java.io.File;

import javax.sound.midi.*;

public class Sound {
	String path = new String("musics\\");
	String file = new String("nor.mid");
	Sequence sq;
	Sequencer mid;
	boolean sign;
	//加载音乐
	void loadSound() {
		try {
			sq = MidiSystem.getSequence(new File(path + file));
			mid = MidiSystem.getSequencer();
			mid.open();
			mid.setSequence(sq);
			mid.start();
			mid.setLoopCount(Sequencer.LOOP_CONTINUOUSLY);
		}
		catch(Exception exit) {
			exit.printStackTrace();
		}
		sign = true;
	}
	//关闭音乐
	void mystop() {
		mid.stop();
		mid.close();
		sign = false;
	}
	//查看是否开着音乐
	boolean isplay() {
		return sign;
	}
	//更改音乐
	void setMusic(String e) {
		file = e;
	}
}

测试类:

package xyz.lzw.box;
/**
 * 测试类
 * @author 栾兆威
 *
 */
public class TEXT {
		public static void main(String[] args) {
			new mainFrame();
		}
}

最后附上源代码 别太嫌弃。。链接: 复制这段内容后打开百度网盘手机App,操作更方便哦
链接:百度网盘 请输入提取码 提取码:okQ8

毕业设计:基于java的推箱子游戏系统设计与实现 基于Java的推箱子游戏系统设计与实现的性能评估是对系统在处理游戏逻辑和用户交互时的效率和稳定性进行评估和分析。通过对系统进行多方面的性能测试和分析,旨在确保系统能够满足用户在实际游戏过程中的性能需求。1、游戏逻辑处理性能评估:游戏逻辑处理是推箱子游戏系统的核心功能,包括玩家移动、箱子移动和碰撞检测等。通过对游戏逻辑处理进行性能评估,可以了解系统在处理这些操作时的效率和稳定性。可以测试不同场景下的游戏性能,如大型地图、多个玩家和多个箱子等。 阅读详情

相关推荐

基于java的推箱子游戏系统设计与实现

推箱子游戏是经典的计算机游戏之一,由于其简单的规则和易于上手的操作,深受广大玩家的喜爱。本文将介绍基于Java的推箱子游戏系统设计与实现的系统性能评估的总结和分析。首先,该系统由三部分组成:玩家控制部分、机器人控制和游戏控制部分。玩家控制部分负责控制玩家的移动和操作,机器人控制部分负责控制机器人的移动和操作,游戏控制部分负责控制游戏的全局控制和游戏状态的管理。其次,该系统采用基于事件驱动的开发方式,将游戏中的事件分为四个主要类型:玩家移动、机器人移动、箱子移动和游戏状态。

m0_62396648的博客 1536

Java课程设计之推箱子

推箱子游戏是一个比较古老的游戏,深受广大游戏爱好者的欢迎,它在带来乐趣的同时也能培养我们的反应力以及严谨的思维能力。 游戏规则是要求角色将地图中所有放置的箱子推到指定目标位置,只有合理安排移动次序和位置,才能顺利完成任务。 项目任务是用java语言设计并实现一个推箱子游戏,旨在培养学生面向对象编程思维方式,开发小型桌面应用程序的能力。 系统功能模块设计 其中系统可以分为初始化模块,绘制地图模块,移动箱子模块、移动小人模块,音乐播放模块,功能控制模块。 程序设计 主

m0_49684834的博客 4457

推箱子java源代码

推箱子java源代码,很适合入门者学习,提高自己的编程能力

Java小游戏-推箱子

推箱子是来自于日本的一个古老游戏,目的是在于训练逻辑思维能力,在一个狭小的空间里,要把木箱推到指定的位置,稍不小心箱子就会无法移动或者被通道堵住的情况,所以需要巧妙的利用有限的空间和通道,合理安排移动的次序和位置,才能顺利的完成任务。在此游戏本着娱乐为目的,游戏者不仅可以在玩游戏的同时享受乐趣,游戏界面简单,操作容易,在玩游戏的同时还可以锻炼大家的反应速度和灵敏程度,在游戏中设置关卡,级别由低到高,一关比一关难,提高大家的兴趣,通过对小人的移动是否到达指定位置进行判断决定是否通关并进入下一关。

m0_54570435的博客 2328

Java-Sokoban-Game:Java推箱子游戏源代码-java source code

Java-Sokoban-Game Java推箱子游戏源代码 根据2条款BSD许可证

日前日内多阶段多时间尺度源荷储协调调度(matlab代码)

多阶段多时间尺度的协调调度的优势是考虑新能源出力的波 动性与随机性,需求响应负荷的不确定性会对电网制定的日前调度计划准确性造成影响,也就是能够更加精准的进行调度和分析,优化结果的可用性更强。在这方面论文里面,金力的《考虑特性分布的储能电站接入的电网多时间尺度源储荷协调调度策略》就考虑了日前日内实时三个阶段调度,每个阶段考虑了不同负荷需求响应策略,同时考虑了负荷波动性的影响,具有很强的参考意义。 目录 一、模型 二、程序运行 三、程序链接 一、模型 负荷需求响应考虑电价型和激励型两种,电.

zhangxd212489的博客 7915

[java]按钮JButton问题(图形按钮、按钮不显示、鼠标滑过才显示、显示位置错误等)——form:菜鸟理解

问题目录问题起源按钮显示位置错误(按钮充满整个窗体)按钮的添加位置按钮只有在鼠标滑过才显示 问题起源 我呢,是一名目前还在纠结毕业设计的苦逼学生。之前壮志凌云,许下:“自己的毕设要自己写”的豪情壮志。还为了防止重题,直接避开了“连连看”、“推箱子”这种网上有对照的题目,选了个“四顶棋”这个小时候玩的游戏,而且网上丝毫没有相关资料。连这个“四顶棋”的名字,都不知道是不是这个游戏的本名! 以上均是废话...

谔码者 9197

Qt+PCL实战:如何用QVTKOpenGLNativeWidget高效渲染3D点云(附完整代码)

本文深入解析了Qt与PCL结合使用QVTKOpenGLNativeWidget进行高效3D点云渲染的实战技术。通过对比传统QVTKWidget,详细介绍了QVTKOpenGLNativeWidget在渲染效率、内存占用和兼容性方面的显著优势,并提供了完整的代码示例和性能优化策略,助力开发者在工业检测、自动驾驶等领域实现更高效的点云可视化。

keras9composer的博客 686

(Java可复用课程设计)关于小型学生信息管理系统项目——基于Java和MySQL的mis系统(有问题的私信作者可远程指导)

这个学期,学校奇葩的给我这个专业开了个Java(说怪也不怪,大学学校总要教你那么一两门高级语言嘛),唉!作为这个物联网工程专业的学生,总是有说不完的苦,有些学校放在电子信息工程学院,有些则放在计算机学院,当然也有厉害的双一流重点大学,比如江南大学,人家牛逼,开了个物联网工程学院!可以说,物联网的学生是软硬通吃,这边数据结构还没看懂,那边单片机电路图,数电逻辑门电路图又来了。...

qq_36462631的博客 6569

YOLOv11低光照检测性能优化:基于Retinexformer主干网络的深度改进实践

购买即可解锁300+YOLO优化文章,并且还有海量深度学习复现项目,价格仅需两杯奶茶的钱,别人有的本专栏也有!@[TOC]在自动驾驶、安防监控、遥感探测等关键领域,目标检测系统必须保证24小时全天候的可靠工作。然而,现有最先进的目标检测模型,包括YOLOv11,其训练数据大多源于光照良好的场景。当环境光照条件急剧下降时,图像会出现严重的噪声、低对比度、颜色失真和细节丢失,直接导致模型性能断崖式下跌。常规的解决方案如图像直方图均衡化或简单的伽马校正,往往收效甚微,甚至可能放大噪声,进一步干扰检测。

m0_71589036的博客 189

YOLOv5源码逐行超详细注释与解读(5)——配置文件yolov5s.yaml

全网最详细的YOLOv5源码解读之配置文件yaml。逐行注释,逐句讲解,一文带你了解yaml。小白必看!

路人贾的博客 1万+

如何高效的自学编程(新手篇)

如何高效的自学编程(新手篇) 你好! 这是你第一次使用 Markdown编辑器 所展示的欢迎页。如果你想学习如何使用Markdown编辑器, 可以仔细阅读这篇文章,了解一下Markdown的基本语法知识。 提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录如何高效的自学编程(新手篇)前言一、pandas是什么?二、使用步骤1.引入库2.读入数据总结新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表

wqd_jy的博客 8682

整理 钢琴 铃木钢琴教程(铃木)

铃木钢琴 超清PDF

TS的博客 1212

闲谈Python语言入门

想学编程,作为自学 `Python` 过来人,跟你讲讲。

qq_43629857的博客 2318

YOLOv5改进系列(4)——添加ECA注意力机制

手把手教你在YOLOv5中加入ECA注意力机制,文内含两种方法,小白也能看懂!

路人贾的博客 8546

DC/DC开关电源学习笔记(十三)Buck-Boost升降压电路工作原理

Buck-Boost电路是一种能够实现输出电压高于或低于输入电压的DC-DC变换器,且输出电压极性与输入电压相反。它结合了Buck(降压)和Boost(升压)两种拓扑的特点,广泛应用于需要灵活电压调整的场合,如电池供电设备、LED驱动和工业控制系统。本文将从电路结构、工作原理、关键公式推导及实际应用等方面进行详细分析。

小幽余生不加糖 3503

致年轻时如此拼搏的你我

致年轻时如此拼搏的你,愿你一如既往的无畏和坚强,踏破一切困难,绽放你最灿烂的光芒。

薛建新的博客 1850

【科研数据获取】根据Excel表个中的企业/公司信息批量获取经纬度坐标,并进行地图可视化

批量获取企业/公司的经纬度坐标,并进行地图可视化1 需求2 实现途径3 需求逐步实现 1 需求 在做项目的时候,老板或者项目答辩时候甲方最喜欢看到的就是可视化结果,尤其是涉及到地图可视化。很多时候会遇到企业/公司的数据,想要做地图可视化,必不可少的就是要获取它们具体地址:第一种就是像查户口一样精准一下具体的城镇街道,还有一种就是经纬度信息,前一种属于文字内容往往用于管理方面,第二种数字信息多用于数据处理与分析。 2 实现途径 获取地理信息数据,自然需要使用到地图的功能,这里直接采用百度地图的拾取坐标系统,

lys_828的博客 2336

火爆全网!这个 Python 项目很骚气!一秒生成可爱像素风图片!

本文转自量子位,作者郭一璞整理来自:大邓和他的Python像文字云一样,用各种小图拼出大的图片,构建一个像素风的世界,就像《我的世界》里一样,一定非常有...

cainiao_python的博客 1482

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

python骚气表情包_火爆全网!这个 Python 项目很骚气!

点击上方Python知识圈,选择设为星标回复1024获取Python资料本文转自量子位,作者郭一璞阅读文本大概需要 5分钟点击「阅读原文」查看pk哥原创精品视频。像文字云一样,用各种小图拼出大的图片,构建一个像素风的世界,就像《我的世界》里一样,一定非常有趣。还可以拿来做拼贴画、十字绣等装饰。在这个名为 tiler的 GitHub 开源项目里你就可以自动实现这一切,它刚刚开源一天,就已经涨到了 ...

weixin_39803207的博客 754

温度PID控制PLC程序

温度PID稳定控制程序,适用于欧姆龙PLC,对其他PLC也具有很大参考价值

画星空图python_火爆全网!这个 Python 项目很骚气!一秒生成可爱像素风图片!...

本文转自量子位,作者郭一璞整理来自:大邓和他的Python像文字云一样,用各种小图拼出大的图片,构建一个像素风的世界,就像《我的世界》里一样,一定非常有趣。还可以拿来做拼贴画、十字绣等装饰。在这个名为 tiler 的 GitHub 开源项目里你就可以自动实现这一切,它刚刚开源一天,就已经涨到了 1500 星,增长速度肉眼可见。https://github.com/nuno-faria/t...

weixin_28931507的博客 364

ssm框架搭建

这个是一个在idea上成功跑起来的ssm框架项目,保存在这里方便以后使用直接下载

java版本实现推箱子小游戏

java版本实现推方块小游戏

meisir666的博客 6225

基于JAVA实现的推箱子小游戏

java实现推箱子小游戏,一起回忆童年的记忆。

小蜜蜂vs码农 2284

【java毕业设计】基于java+swing+Eclipse的推箱子游戏设计与实现(毕业论文+程序源码)——推箱子游戏

大家好,今天给大家介绍基于java+swing+Eclipse的推箱子游戏设计与实现,文章末尾附有本毕业设计的论文和源码下载地址哦。文章目录: 项目难度:中等难度 适用场景:相关题目的毕业设计 配套论文字数:31887个字 包含内容:整套源码+完整毕业论文+答辩PPT+任务书+辅导视频+运行截图提示:以下为毕业设计的简略介绍,项目源码及完整毕业论文下载地址见文末。引 言 策略性游戏可以锻炼人的思维能力还能缓解人的压力,使人们暂时忘却生活当中的烦恼,增强人们的逻辑思维能力,游戏的艺术美也吸引着越来越多的

m0_66238867的博客 7674

推箱子游戏设计与实现(Java+swing+JAWT)

本文摘要: 本文围绕推箱子游戏开发展开系统分析,从技术可行性、需求分析到方案论证,详细探讨了游戏设计的关键环节。通过C++、Java、C语言等方案比较,最终确定开发语言,并完成概要设计与详细设计,包括地图绘制、移动算法、悔棋模块等功能实现。测试阶段验证了系统性能,项目经验总结强调了需求分析在软件开发中的核心地位。附录包含参考文献、致谢及外文资料,完整呈现了推箱子游戏从设计到实现的全过程。

毕业作品网站 4047

简易推箱子【java版】

作为一种富有挑战性和趣味性的游戏,它可以锻炼玩家的思维能力和判断能力,让人感到十分有趣和满足。我们希望通过这个小游戏,让更多人感受到推箱子的乐趣。操作起来也非常简单,你只需要使用方向键来控制主角移动,推动箱子就像推自己一样,将箱子推到指定位置即可完成任务。玩家需要谨慎行动,避免将箱子推到墙壁或者角落里,导致无法完成任务。推箱子小游戏就是这样一个简单而有趣的休闲游戏,让你能够在闲暇时刻享受游戏的乐趣,缓解生活的疲惫。现在,快来挑战我们的推箱子小游戏,放松心情,挑战智慧,开启一段简单而有趣的游戏之旅吧!

littletomorrow的博客 2120
上一篇: N皇后问题 (简单回溯)
下一篇: 磁盘调度算法
Puppet__
博客等级 码龄9年 319粉丝 328原创
评论 10
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值