Java迷宫小游戏,老程序员花一天时间完成,你可以吗?
Posted 编程界明世隐
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java迷宫小游戏,老程序员花一天时间完成,你可以吗?相关的知识,希望对你有一定的参考价值。
Java迷宫,老程序员又来了
作者简介
作者名:编程界明世隐
简介:CSDN博客专家,从事软件开发多年,精通Java、javascript,博主也是从零开始一步步把学习成长、深知学习和积累的重要性,喜欢跟广大ADC一起打野升级,欢迎您关注,期待与您一起学习、成长、起飞!
系列目录
1. Java俄罗斯方块
2. Java五子棋小游戏
3. 老Java程序员花一天时间写了个飞机大战
4. Java植物大战僵尸
5. 老Java程序员花2天写了个连连看
6. Java消消乐(天天爱消除)
7. Java贪吃蛇小游戏
8. Java扫雷小游戏
9. Java坦克大战
效果图
实现思路
1.创建运行窗口。
2.创建菜单。
3.绘制迷宫的每个单元。
4.通过算法计算迷宫路径,并打通路径,形成迷宫。
5.绘制起点终点。
6.添加键盘事件控制起点方块移动。
7.收尾。
迷宫算法(网上参考的)
- 将起点作为当前迷宫单元并标记为已访问
- 当还存在未标记的迷宫单元,进行循环
1).如果当前迷宫单元有未被访问过的的相邻的迷宫单元
(1).随机选择一个未访问的相邻迷宫单元
(2).将当前迷宫单元入栈
(3).移除当前迷宫单元与相邻迷宫单元的墙
(4).标记相邻迷宫单元并用它作为当前迷宫单元
2).如果当前迷宫单元不存在未访问的相邻迷宫单元,并且栈不空
(1).栈顶的迷宫单元出栈
(2).令其成为当前迷宫单元
**这个算法叫做“深度优先”,简单来说,就是从起点开始走,寻找它的上下左右4个邻居,然后随机一个走,到走不通的时候就返回上一步继续走,直到全部单元都走完。 **
相关图示说明
- 每个单元的墙,分为上墙、右墙、下墙、左墙,把这些墙用长度为4的数组表示,元素的值为true则表示墙存在,否则墙不存在,代码里数组的下标方式来确定墙是否存在。
- 单元是根据行列来创建的,会用到双循环,类似表格,比如第二行用 i 来表示的话就是 1,第3列用 j 来表示就是2,那第二行第3列的元素组合起来就是(1,2)
- 那同理它的上邻居就是(0,2),右邻居(1,3),下邻居(2,2),左邻居(1,1),也就是上下邻居是 i 减加1,左右邻居是 j 减加1。
- 正方形4个点的坐标分别为(x1,y1)(x2,y2)(x3,y3)(x4,y4),计算坐标的公式为(其中start为相对偏移量,为了让迷宫两边有些空隙):
//i代表行 j代表列 h为单元高度
//左上角坐标
this.x1=start+j*h;
this.y1=start+i*h;
//右上角坐标
this.x2=start+(j+1)*h;
this.y2=start+i*h;
//右下角坐标
this.x3=start+(j+1)*h;
this.y3=start+(i+1)*h;
//左下角坐标
this.x4=start+j*h;
this.y4=start+(i+1)*h;
计算坐标,假如每个正方形的宽高都是40,那么(1,2)这个单元的坐标如下图:
5. 墙的处理,之前说到墙是以一个4个元素的数组来表示的,比如数组为:[true,true,true,true],则图为:
如果数组为[false,true,true,true],则图为:
6. 如果要联通右边的邻居要怎么做呢?当前单元去除右墙,右边单元去除左墙,这样就联通了。
去除后就这样,以此类推
代码实现
创建窗口
首先创建一个游戏窗体类GameFrame,继承至JFrame,用来显示在屏幕上(window的对象),每个游戏都有一个窗口,设置好窗口标题、尺寸、布局等就可以。
import javax.swing.JFrame;
/**
*窗体类
*/
public class GameFrame extends JFrame {
//构造方法
public GameFrame(){
setTitle("迷宫");//设置标题
setSize(420, 470);//设置窗体大小
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//关闭后进程退出
setLocationRelativeTo(null);//居中
setResizable(false);//不允许变大
//setVisible(true);//设置显示窗体
}
}
创建面板容器GamePanel继承至JPanel
import javax.swing.JMenuBar;
import javax.swing.JPanel;
/*
* 画布类
*/
public class GamePanel extends JPanel{
private JMenuBar jmb = null;
private GameFrame mainFrame = null;
private GamePanel panel = null;
private String gameFlag="start";//游戏状态
//构造方法
public GamePanel(GameFrame mainFrame){
this.setLayout(null);
this.setOpaque(false);
this.mainFrame=mainFrame;
this.panel =this;
}
}
再创建一个Main类,来启动这个窗口。
//Main类
public class Main {
public static void main(String[] args) {
GameFrame frame = new GameFrame();
GamePanel panel = new GamePanel(frame);
frame.add(panel);
frame.setVisible(true);
}
}
右键执行这个Main类,窗口建出来了
创建菜单及菜单选项
创建菜单
private Font createFont(){
return new Font("思源宋体",Font.BOLD,18);
}
//创建菜单
private void createMenu() {
//创建JMenuBar
jmb = new JMenuBar();
//取得字体
Font tFont = createFont();
//创建游戏选项
JMenu jMenu1 = new JMenu("游戏");
jMenu1.setFont(tFont);
//创建帮助选项
JMenu jMenu2 = new JMenu("帮助");
jMenu2.setFont(tFont);
JMenuItem jmi1 = new JMenuItem("新游戏");
jmi1.setFont(tFont);
JMenuItem jmi2 = new JMenuItem("退出");
jmi2.setFont(tFont);
//jmi1 jmi2添加到菜单项“游戏”中
jMenu1.add(jmi1);
jMenu1.add(jmi2);
JMenuItem jmi3 = new JMenuItem("操作帮助");
jmi3.setFont(tFont);
JMenuItem jmi4 = new JMenuItem("胜利条件");
jmi4.setFont(tFont);
//jmi13 jmi4添加到菜单项“游戏”中
jMenu2.add(jmi3);
jMenu2.add(jmi4);
jmb.add(jMenu1);
jmb.add(jMenu2);
mainFrame.setJMenuBar(jmb);
//添加监听
jmi1.addActionListener(this);
jmi2.addActionListener(this);
jmi3.addActionListener(this);
jmi4.addActionListener(this);
//设置指令
jmi1.setActionCommand("restart");
jmi2.setActionCommand("exit");
jmi3.setActionCommand("help");
jmi4.setActionCommand("win");
}
实现ActionListener并重写方法actionPerformed
此时GamePanel是报错的,需重写actionPerformed方法。
actionPerformed方法的实现
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
System.out.println(command);
UIManager.put("OptionPane.buttonFont", new FontUIResource(new Font("思源宋体", Font.ITALIC, 18)));
UIManager.put("OptionPane.messageFont", new FontUIResource(new Font("思源宋体", Font.ITALIC, 18)));
if ("exit".equals(command)) {
Object[] options = { "确定", "取消" };
int response = JOptionPane.showOptionDialog(this, "您确认要退出吗", "",
JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,
options, options[0]);
if (response == 0) {
System.exit(0);
}
}else if("restart".equals(command)){
restart();
}else if("help".equals(command)){
JOptionPane.showMessageDialog(null, "通过键盘的上下左右来移动",
"提示!", JOptionPane.INFORMATION_MESSAGE);
}else if("win".equals(command)){
JOptionPane.showMessageDialog(null, "移动到终点获得胜利",
"提示!", JOptionPane.INFORMATION_MESSAGE);
}
}
此时的GamePanel代码如下:
package main;
import java.awt.Font;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.UIManager;
import javax.swing.plaf.FontUIResource;
/*
* 画布类
*/
public class GamePanel extends JPanel implements ActionListener{
private JMenuBar jmb = null;
private GameFrame mainFrame = null;
private GamePanel panel = null;
private String gameFlag="start";//游戏状态
//构造方法
public GamePanel(GameFrame mainFrame){
this.setLayout(null);
this.setOpaque(false);
this.mainFrame=mainFrame;
this.panel =this;
//创建菜单
createMenu();
}
private Font createFont(){
return new Font("思源宋体",Font.BOLD,18);
}
//创建菜单
private void createMenu() {
//创建JMenuBar
jmb = new JMenuBar();
//取得字体
Font tFont = createFont();
//创建游戏选项
JMenu jMenu1 = new JMenu("游戏");
jMenu1.setFont(tFont);
//创建帮助选项
JMenu jMenu2 = new JMenu("帮助");
jMenu2.setFont(tFont);
JMenuItem jmi1 = new JMenuItem("新游戏");
jmi1.setFont(tFont);
JMenuItem jmi2 = new JMenuItem("退出");
jmi2.setFont(tFont);
//jmi1 jmi2添加到菜单项“游戏”中
jMenu1.add(jmi1);
jMenu1.add(jmi2);
JMenuItem jmi3 = new JMenuItem("操作帮助");
jmi3.setFont(tFont);
JMenuItem jmi4 = new JMenuItem("胜利条件");
jmi4.setFont(tFont);
//jmi13 jmi4添加到菜单项“游戏”中
jMenu2.add(jmi3);
jMenu2.add(jmi4);
jmb.add(jMenu1);
jmb.add(jMenu2);
mainFrame.setJMenuBar(jmb);
//添加监听
jmi1.addActionListener(this);
jmi2.addActionListener(this);
jmi3.addActionListener(this);
jmi4.addActionListener(this);
//设置指令
jmi1.setActionCommand("restart");
jmi2.setActionCommand("exit");
jmi3.setActionCommand("help");
jmi4.setActionCommand("win");
}
@Override
public void actionPerformed(ActionEvent e) {
String command = e.getActionCommand();
System.out.println(command);
UIManager.put("OptionPane.buttonFont", new FontUIResource(new Font("思源宋体", Font.ITALIC, 18)));
UIManager.put("OptionPane.messageFont", new FontUIResource(new Font("思源宋体", Font.ITALIC, 18)));
if ("exit".equals(command)) {
Object[] options = { "确定", "取消" };
int response = JOptionPane.showOptionDialog(this, "您确认要退出吗", "",
JOptionPane.YES_OPTION, JOptionPane.QUESTION_MESSAGE, null,
options, options[0]);
if (response == 0) {
System.exit(0);
}
}else if("restart".equals(command)){
restart();
}else if("help".equals(command)){
JOptionPane.showMessageDialog(null, "通过键盘的上下左右来移动",
"提示!", JOptionPane.INFORMATION_MESSAGE);
}else if("win".equals(command)){
JOptionPane.showMessageDialog(null, "移动到终点获得胜利",
"提示!", JOptionPane.INFORMATION_MESSAGE);
}
}
void restart(){
}
}
运行它
绘制迷宫的每个单元
- 初始化相关参数
public final int ROWS=20;//行
public final int COLS=20;//列
public final int H=20;//每一块的宽高
Block[][] blocks = null;//存储每个单元的二维数组
- 创建迷宫单元类(如果对坐标计算不明白,可以往上翻,有图示说明解释)
import java.awt.Graphics;
import java.util.ArrayList;
import java.util.List;
/*
* 迷宫单元类
*/
public class Block {
private GamePanel panel = null;
private int i=0;//二维数组的下标i
private int j=0;//二维数组的下标j
private int h=0;//宽高
private int start=6;//偏移像素
//4个顶点坐标
private int x1=0;//x1坐标
private int y1=0;//y1坐标
private int x2=0;//x2坐标
private int y2=0;//y2坐标
private int x3=0;//x3坐标
private int y3=0;//y3坐标
private int x4=0;//x4坐标
private int y4=0;//y4坐标
//上下左右4个墙是否显示,true:显示&以上是关于Java迷宫小游戏,老程序员花一天时间完成,你可以吗?的主要内容,如果未能解决你的问题,请参考以下文章
C系列Unity3D | 花一天时间做个经典小游戏Pacman
花一天时间做一个高质量飞机大战游戏,过万字Unity完整教程!漂亮学妹看了直呼666!