java迷宫
来源:互联网 发布:源码下载网站 编辑:程序博客网 时间:2024/06/08 01:11
终于放假了,可以研究一些好玩的东西了,先把之前用c语言写的迷宫用swing重写了下界面,算法部分并没有做什么修改,原来的链接
这个比拼图还要简单,因为并不涉及线程,只要在按键wsad后重绘就行。
尝试了菜单栏的用法,比较奇怪的是JMenu貌似并不能添加监听事件(假设我并没有下拉的子菜单),必须只能给JMenuItem添加监听事件(这就意味着哪怕只有一个选项也必须先写JMen,再在这里面设定一个JMenuItem)
另外注意聚焦的问题,即使用JPanel时需要添加聚焦setFocusable
其余就没什么说的了,按部就班的写下去。生成迷宫算法部分不复杂,大致就是从左上角开始深度优先搜索,但是原来深搜是按照一定模式(比如上下左右)扩展节点,现在我先随机生成一个4个全排列,按照这个顺序随机访问上下左右的点,直到右下角为止,生成一条路径,然后剩下的点大部分(这里设为80%)为墙壁,少部分(这里设为20%)为路径,毕竟不能整个地图空白就是路径,那样一眼就看出来了。
下面贴代码,写的时候思路比较清晰,测试没发现什么明显bug,如果有问题请留言指出哈~~
game类(游戏界面)
public class game extends JFrame implements ActionListener { JMenuBar menuBar;//菜单栏对象 JMenu menu,menu2;//菜单对象 JMenuItem menuitem,menuitem2,menuitem3; Secretmap g;public game(){setTitle("我的迷宫");setLayout(null);setBounds(100,100,700,700);g= new Secretmap();//里面包含一个游戏类继承画板g.setBounds(0,0,600,600);Container container=getContentPane();menuBar=new JMenuBar();//创建菜单栏对象setJMenuBar(menuBar);//添加菜单栏对象menu=new JMenu("开始");//创建菜单对象menuBar.add(menu);//将菜单对象添加到菜单栏对象中menuitem=new JMenuItem("开始游戏");menu.add(menuitem);menuitem.addActionListener(this);//添加监听事件menu2=new JMenu("设置");menuBar.add(menu2); menuitem2=new JMenuItem("设置行数");menu2.add(menuitem2);menuitem2.addActionListener(this);//添加监听事件menuitem3=new JMenuItem("设置列数");menu2.add(menuitem3);menuitem3.addActionListener(this);//添加监听事件container.add(g);setVisible(true);g.setFocusable(true);//关键之关键,jpanel添加键盘监听事件要聚焦到画板setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);} public void actionPerformed(ActionEvent e){ if (e.getSource()==menuitem) {g.startgame();//开始游戏System.out.println("1");}if (e.getSource()==menuitem2){//设置行数System.out.println("2");alert a=new alert(g);}if (e.getSource()==menuitem3){//设置列数System.out.println("3");alert2 b=new alert2(g);//这边涉及到窗口的传值,就是把一个对象传进去} } public static void main(String [] args){ new game();}}
Secretmap(迷宫的内部活动类)
public class Secretmap extends JPanel implements KeyListener{int time;//控制画板的绘画方式int row;//行int column;//列int [][]a;//存储状态的节点int [][]visit;int []direction=new int[4];int Time;int personrow;//人当前所在的行int personcolumn;//人当前所在的列ImageIcon imagecon;public Secretmap(){ time=0;//默认展示背景图片Time=0;//默认没有找到路径row=column=0;//初始化为0(如果不为0说明可以绘制) imagecon=new ImageIcon("./picture/bg.png");//记录完整图片repaint();}public void SetRow(int row){this.row=row;}public void SetColumn(int column){this.column=column;}public void startgame(){ if ((row!=0)&&(column!=0))//当行数和列数均已经设定{ this.removeKeyListener(this);Time=0;System.out.println(row+" "+column);time=1;a=new int[row+1][column+1];visit=new int[row+1][column+1];initsecretmap();//随机生成迷宫的一条线路for (int i=0;i<row;i++)for (int j=0;j<column;j++){if (a[i][j]==0)//如果不在这条线路上{int m=(int)(Math.random()*100);if (m<=20)//除了线路上的点都是空白,肯定还要有一些空白,这个就认为剩下的20%是空白a[i][j]=1;}}this.addKeyListener(this);personrow=0;personcolumn=0;repaint();}}public void initsecretmap(){ for (int i=0;i<row;i++) for (int j=0;j<column;j++) a[i][j]=0;//一开始都标记为不可通行 for (int i=0;i<row;i++) for (int j=0;j<column;j++) visit[i][j]=0; a[0][0]=1;//起点标记为可通行(这里默认左上角为起点,可自行修改) visit[0][0]=1;//标记起点已经被访问过 DFS(0,0);//开始深搜 }public void DFS(int x,int y){int []c={0,0,-1,1};int []d={1,-1,0,0};int dx,dy,i;if ((x==row-1)&&(y==column-1))//如果到达终点{Time=1;return;}initdirection();//随机生成四个方向(其实就是全排列)for (i=0;i<=3;i++){dx=x+c[direction[i]];dy=y+d[direction[i]];if ((dx>=0)&&(dx<row)&&(dy>=0)&&(dy<column)&&(visit[dx][dy]==0)&&(Time==0)){a[dx][dy]=1;//认为它是通路visit[dx][dy]=1;DFS(dx,dy);if (Time==0)a[dx][dy]=0;}}}public void initdirection(){ int i,j,k,ok; for (i=0;i<=3;i++) { j=(int)(Math.random()*4);//注意括号的位置!要先乘再取int ok=1; for (k=0;k<i;k++) if (j==direction[k]) ok=0; if (ok==1) direction[i]=j; else i--; }}public boolean isreach(){if ((personrow==row-1)&&(personcolumn==column-1))return true;return false; }@Overridepublic void keyPressed(KeyEvent e){char c=e.getKeyChar();System.out.println(c);switch(c){case 'w'://如果是向上if ((personrow>0)&&(a[personrow-1][personcolumn]==1))//如果上方可以到达personrow--;if (isreach()){new alert3();Time=0;this.removeKeyListener(this);}break;case 's'://如果是向下if ((personrow<row-1)&&(a[personrow+1][personcolumn]==1))//如果下方可以到达personrow++;if (isreach()){new alert3();Time=0;this.removeKeyListener(this);}break;case 'a'://如果是向左if ((personcolumn>0)&&(a[personrow][personcolumn-1]==1))//如果左方可以到达personcolumn--;if (isreach()){new alert3();Time=0;this.removeKeyListener(this);}break;case 'd'://如果是向右if ((personcolumn<column-1)&&(a[personrow][personcolumn+1]==1))//如果右方可以到达personcolumn++;if (isreach()){new alert3();Time=0;//标记为没有找到this.removeKeyListener(this);}break; }repaint();}public void paint(Graphics g){if (time==0)//如果是一开始没有开始游戏时,随便放一张背景图片{ Image r=imagecon.getImage(); g.drawImage(r,0,0,600,600,this);//画出原来的完整图案}elseif (time==1)//否则就是在游戏中重绘{g.clearRect(0,0,600,600);for (int i=0;i<row;i++)for (int j=0;j<column;j++){if ((i==personrow)&&(j==personcolumn)){Color c=g.getColor();g.setColor(Color.RED);//人是红色g.fillRect(600/column*j,600/row*i,600/column,600/row);g.setColor(c);}elseif (a[i][j]==1){Color c=g.getColor();g.setColor(Color.WHITE);//白色是路g.fillRect(600/column*j,600/row*i,600/column,600/row);g.setColor(c);}elseif (a[i][j]==0){Color c=g.getColor();g.setColor(Color.GRAY);//灰色是墙壁g.fillRect(600/column*j,600/row*i,600/column,600/row);g.setColor(c);}}}}@Overridepublic void keyReleased(KeyEvent arg0) {// TODO Auto-generated method stub}@Overridepublic void keyTyped(KeyEvent arg0) {// TODO Auto-generated method stub}}
接下去就是几个弹窗
alert类
public class alert extends JDialog { int row; public alert(Secretmap g){setTitle("注意!");setLayout(null);setBounds(300,300,400,400);Container container=getContentPane();container.setBackground(Color.white);JLabel jl= new JLabel("请输入新的行数");jl.setBounds(50,50,300,100); JTextField jt=new JTextField(""); jt.setBounds(50,150,300,50); JButton jb=new JButton("确定"); jb.setBounds(100,250,150,75); jb.addActionListener(new ActionListener() {//设立确定按钮的点击事件@Overridepublic void actionPerformed(ActionEvent arg0) {// TODO Auto-generated method stu9b String s=jt.getText(); if (s.matches("\\d+"))//如果是数字 row=Integer.valueOf(s); System.out.println(row); g.SetRow(row); setVisible(false);}}); container.add(jl); container.add(jt); container.add(jb); setVisible(true); } }
alert2类
public class alert2 extends JDialog { int column; public alert2(Secretmap g){setTitle("注意!");setLayout(null);setBounds(300,300,400,400);Container container=getContentPane();container.setBackground(Color.white);JLabel jl= new JLabel("请输入新的列数"); jl.setBounds(50,50,300,100); JTextField jt=new JTextField(""); jt.setBounds(50,150,300,50); JButton jb=new JButton("确定"); jb.setBounds(100,250,150,75); jb.addActionListener(new ActionListener() {//设立确定按钮的点击事件@Overridepublic void actionPerformed(ActionEvent arg0) {// TODO Auto-generated method stu9b String s=jt.getText(); if (s.matches("\\d+"))//如果是数字 column=Integer.valueOf(s); System.out.println(column); g.SetColumn(column); setVisible(false); }}); container.add(jl); container.add(jt); container.add(jb); setVisible(true); } }alert3类
public class alert3 extends JDialog {ImageIcon li;public alert3(){win g=new win();g.setBounds(0,0,400,400);setTitle("you win!");setLayout(null);setBounds(400,300,450,400);Container container=getContentPane();container.add(g);container.setBackground(Color.white); setVisible(true); }}win类
public class win extends JPanel{ ImageIcon li; public win(){ li=new ImageIcon("./picture/you win.png"); repaint(); } public void paint(Graphics g) { Image r=li.getImage(); g.drawImage(r,0,0,400,400,this); } }
github:https://github.com/fengsigaoju/secretmap
0 0
- java迷宫
- java迷宫
- java实现迷宫算法
- 迷宫问题--java
- 迷宫 java实验
- java迷宫算法
- java堆栈迷宫算法
- java走迷宫
- java实现走迷宫
- java实现迷宫算法
- 迷宫求解java解决方案
- java解决迷宫问题
- java 蓝桥杯 走出迷宫
- java游戏之迷宫
- java寻找迷宫路径
- 迷宫问题(java)
- 迷宫算法(JAVA实现)
- 迷宫问题-(Java源码)
- Css cursor鼠标指针鼠标光标样式
- linux gdb 调试工具
- 【JQuery笔记】animate中的params参数
- matlab C代码生成
- Nodejs 微信加密消息开发
- java迷宫
- debug.keystore
- hdoj 1013 Digital Roots
- Css3 transform matrix()的使用
- Shell Sudo With Password On Command
- 新的Android开发环境——Android Studio
- Android中Activity生命周期测试分析
- oracle学习笔记 Oracle体系结构概述
- 负载均衡学习笔记