Java《石头迷阵03》黑马程序员官方出版知识重点+笔记源码
Posted 黑马程序员官方
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java《石头迷阵03》黑马程序员官方出版知识重点+笔记源码相关的知识,希望对你有一定的参考价值。
更多Java全套学习资源均在专栏,持续更新中↑↑戳进去领取~
🍅2022年全新Java学习路线图,含源码+笔记,另附在职提升课
🍅跟我20天学Java:01-计算机基础以及JDK、IDEA等安装详解
🍅跟我20天学Java:02-自动类型转换,表达式的自动类型转换,强制类型转换
🍅跟我20天学Java:03-6个案例手把手带你学循环结构
🍨Java《石头迷阵01》黑马程序员官方出版教程+源码
🍨Java《石头迷阵02》黑马程序员官方出版万字教程+源码
1,事件机制
在游戏中,用户可以进行很多不同的操作。
当用户按左键时,那么空白右边的9就需要往左移。
如图所示:
当用户按右键时,那么空白左边的4就需要往右移。
当用户按上键时,那么空白下面的5就需要往上移。
当用户按下键时,那么空白上面的8就需要往下移。
当用户点击了菜单里面的重新开始时,游戏里面的数字就需要重新打乱顺序。重开一局游戏。
当用户点击了联系我们的时候,就需要弹出一个黑马官方公众号的二维码
也就是说,当用户进行不同的操作,我们要执行的代码就不一样了。
所以,此时就需要有监听机制。监听机制可以监听到用户进行的不同操作。针对于不同的操作我们可以写不同的代码。而监听到用户的操作,也叫做事件。
在刚刚的分析中:用户在键盘上进行的按键操作,就是键盘事件。
用户点击不同的按钮,就是点击事件。
那么在代码中如何写呢?就要用到下面学习的接口了。
2,接口
- Java 接口是一系列方法的声明,是一些方法特征的集合。
- 用于制定 规则
2.1接口定义
我们可以定义两个方法,当键盘按下的时候,执行按下方法里面的代码。当键盘按键松开的时候。执行松开的代码。
public class KeyListener
public void 按下()
...
public void 松开()
...
但是因为不同的项目中,所操作的业务逻辑是不一样的。所以这个方法里面的代码就是谁用谁写。
所以,在定义接口的时候,干脆里面的方法就不写大括号。那一旦不写大括号,上面的class也要变一下,变成interface。
所以,接口定义格式如下:
public interface KeyListener
public void 按下();
public void 松开();
2.2接口使用
在使用一个接口时,可以定义一个类实现这个接口,并补全里面所有的方法。
此时,实现这个接口的类,叫做该接口的实现类。
代码如下:
public class MainFrame implements KeyListener
public void 按下()
...
public void 松开()
...
此时,如果我想监听键盘按键的时候,就可以使用这个接口。
当键盘任意一个按键被按下的时候,会自动调用按下这个方法。
当键盘任意一个按键松开的时候,会自动调用松开这个方法。
2.3Java中的接口
这些接口,都不需要我们自己写。Java已经帮我们写好了。
如果我们想监听键盘事件,就实现KeyListener这个接口。
如果我们想监听游戏中哪个东西被点击了,就实现ActionListener接口。
不管实现哪个接口,接口里面所有的方法我们都要写一遍。
3,KeyListener接口
现在,我想按上下左右键之后,图片可以移动起来。那么此时必须要实现Java已经写好的KeyListener。
示例代码如下:
public class MyJFrame extends JFrame implements KeyListener
...
然后把里面所有的方法自己补全。但是不需要自己手写,用鼠标点击一下红色波浪线,按下快捷键:alt+enter。这样就可以自动生成。
public class MyJFrame extends JFrame implements KeyListener
...
@Override
public void keyTyped(KeyEvent e)
...
//按下
@Override
public void keyPressed(KeyEvent e)
...
//松开
@Override
public void keyReleased(KeyEvent e)
...
其中有两个方法要知道,当键盘上按键被按下的时候,系统会自动调用keyPressed方法,当按键松开的时候,会自动调用keyReleased方法。所以我们可以在方法中分别写输出语句实现一下。
public class MyJFrame extends JFrame implements KeyListener
...
@Override
public void keyTyped(KeyEvent e)
//按下
@Override
public void keyPressed(KeyEvent e)
System.out.println("键盘上按键被按下了");
//松开
@Override
public void keyReleased(KeyEvent e)
System.out.println("键盘上按键松开了");
最后还要让整个界面绑定一下键盘监听事件。
此时就相当于有一个人在监听界面的键盘事件,如果此时键盘按下了,则会自动调用对应的方法
public void initFrame()
...
//让界面添加键盘监听
this.addKeyListener(this);
...
游戏启动后,如果没有按键盘上的键,那么这两个方法不会被调用。
如果我们按下任意一个键,会发现。控制台输出:
键盘上按键被按下了
键盘上按键松开了
这可以说明三件事情:
- 按键时,会有多个动作。先是按下动作,最后是松开动作。
- 按下按键时,keyPressed自动被调用。不需要我们自己调用。
- 松开按键时,keyReleased自动被调用。不需要我们自己调用。
细节:当我们要写代码实现按某一个键实现对应的逻辑时,一般会把代码写在松开的方法中。
4,键位与数字的对应关系
在刚刚我们已经监听到了键盘事件了。但是有一个问题,不管我们按下什么键,都会去自动调用keyPressed方法,不管我们松开什么键,都会自动调用keyReleased方法。
所以我们还要对按键进行一个判断。
在Java中,键盘上的每一个键位都会跟一个数字一一对应。
- 左键 — 37
- 上键 — 38
- 右键 — 39
- 下键 — 40
这些数字不需要我们记住。可以通过getKeyCode
方法获取到。
代码示例:
public class MyJFrame extends JFrame implements KeyListener
...
@Override
public void keyTyped(KeyEvent e)
//按下
@Override
public void keyPressed(KeyEvent e)
System.out.println("键盘上按键被按下了");
//松开
@Override
public void keyReleased(KeyEvent e)
//获取按键对应的数字
int keyCode = e.getKeyCode();
//打印数字
System.out.println(keyCode);
System.out.println("键盘上按键松开了");
那么这样,我们通过对这些数字判断就可以实现移动效果了。
5,图片移动
咱们已经学习了事件机制的相关知识,那么下面我们就让图片动起来。
我们可以获取到按键对应的数字,然后对数字进行判断。
针对于不同的按键,执行不同的代码逻辑。
步骤:
1,在keyReleased方法中获取按键对应的数字
2,定义一个move方法。在move方法中对上下左右进行判断。
3,在keyReleased中调用move方法,并传递按键对应的数字。
4,移动之后要重新绘制整个游戏界面。
代码示例:
public class MyJFrame extends JFrame implements KeyListener
...
@Override
public void keyTyped(KeyEvent e)
//松开
@Override
public void keyReleased(KeyEvent e)
//获取按键的数字
int keyCode = e.getKeyCode();
//调用move方法并传递数字
move(keyCode);
//判断上下左右,来执行不同的代码
public void move(int keyCode)
if (keyCode == 37)
//左
//表示空格右边的图片要向左移动
datas[x0][y0] = datas[x0][y0 + 1];
datas[x0][y0 + 1] = 0;
y0++;
else if (keyCode == 38)
//上
//表示空格下面的图片要向上移动
datas[x0][y0] = datas[x0 + 1][y0];
datas[x0 + 1][y0] = 0;
x0++;
else if (keyCode == 39)
//右
//表示空格在左边的图片要向右移动
datas[x0][y0] = datas[x0][y0 - 1];
datas[x0][y0 - 1] = 0;
y0--;
else if (keyCode == 40)
//下
//表示空格在上面的图片要向下移动
datas[x0][y0] = datas[x0 - 1][y0];
datas[x0 - 1][y0] = 0;
x0--;
else
System.out.println("只能按上下左右");
public void initImage()
//表示将界面中原来所有的图片全部删除
this.getContentPane().removeAll();
...//中间的代码不用动
//将整个界面重新绘制
this.getContentPane().repaint();
6,作弊码
到目前为止,游戏的主体功能都已经全部写完了。那么下面,我们再添加一些额外的小功能。首先是作弊码。
当我们在玩游戏的时候,觉得自己可能无法通关了。那么就可以按这个作弊码一键通关,惊呆你的小伙伴。
首先,咱们得定一个按键是作弊码。假设,我定w为作弊码。当我按下w的时候,就可以一键通关。
但是此时我还不知道w按键对应的数字怎么办啊?其实没关系,打印一下就可以了。
public class MyJFrame extends JFrame implements KeyListener
...
@Override
public void keyTyped(KeyEvent e)
//松开
@Override
public void keyReleased(KeyEvent e)
//获取按键的数字
int keyCode = e.getKeyCode();
//打印数字
System.out.println(keyCode);
//调用move方法并传递数字
move(keyCode);
...
我们可以在keyReleased方法中获取按键对应的数字,再把数字打印出来。启动游戏之后,我们按下w键。
控制台输出:
87
此时就证明,w按键对应的数字为87。
在move方法中,加上对87的判断就可以了。如果按下87的时候,直接将二维数组中的数字变成最终的数字。
代码示例:
public void move(int keyCode)
...
else if (keyCode == 87)
//w 表示作弊码
datas = new int [][]1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0;
...
7,判断胜利
现在游戏可以正常玩耍了,也可以用作弊码一键通关。但是有一个小问题。当游戏成功通关之后,根本没有胜利提示,这让我绞尽脑汁之后总感觉少了一点成就感(如下左图所示)。我想着如果游戏成功通关后,在界面上有成提示,那么玩起来也有一点动力。很多人玩单机游戏,都想看看通关之后的画面是什么样的。所以,我就要在通关之后,加上一个胜利标志(如下右图所示)。
其实胜利标志就是一张图片而已。在资料的image文件中有一张win.png。在游戏通关之后,把他显示出来即可。如下图所示:
所以,我们在每次绘制整个页面之前,都要判断一下二维数组中的数字是否已经排列成功,如果已经排列成功,那么就显示胜率图标,如果没有排列成功,就不显示胜利图标。
步骤:
1,定义一个方法victory,需要判断datas数组中数字是否排列成功,将判断结果返回。
2,对victory方法的结果进行判断。
3,如果为真,则加载胜利图标,如果为假,则不加载。
7.1带有返回值的方法
其中带有返回值的方法,跟之前学习的方法是一样的。
7.1.1定义格式:
public 返回值类型 方法名()
//方法执行的代码
return xxx;
在以前的方法中,不需要方法的执行结果。所以我们一律写成public void。其中void表示该方法没有返回值。
现在我们要定义victory方法,在方法中要判断二维数组中的数据。所以需要把方法比较的结果返回给调用者。
7.1.2return关键字
victory方法中,用了一个关键字return。
return关键字的两个使用地点:
-
没有返回值的方法中的作用
结束方法
-
有返回值的方法中的作用
1,结束方法
2,后面紧跟方法的最终结果,将方法的最终结果返回给调用者。
注意点:
方法实际返回的值,要跟返回值类型保持一致即可。
举例:
如果返回整数,那么返回值类型就写int
如果返回小数,那么返回值就写double
如果返回字符串,那么返回值就写String
现在我返回一个判断结果,要么是true,要么是false。在Java中这叫做布尔类型,用boolean表示。
7.2代码实现
判断的二维数组元素的步骤如下:
1,在类的上面定义一个新的二维数组,该二维数组中的元素是按照正确方式排列的。
2,在victory方法中,对两个二维数组进行比较即可。
如果完全一致,那么返回true。
只要有一个不一样,那么返回false
3,在initImage方法中对victory的结果进行判断。
如果为真,表示游戏通关,显示胜利图标。
如果为假,表示游戏未通关,不显示胜利图标。
public class MyJFrame extends JFrame implements KeyListener
...
//定义一个二维数组,元素是最终胜利的元素。
int [][] victory = 1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0;
public void initImage()
...
//判断游戏是否胜利
if(victory())
//如果该方法的结果是true
//那么就表示游戏胜利
ImageIcon imageIcon = new ImageIcon("image\\\\win.png");
JLabel jLabel = new JLabel(imageIcon);
jLabel.setBounds(514/2-266/2,230,266,88);
this.add(jLabel);
...
//判断两个数组中元素是否相同
public boolean victory()
//datas 和 victory
for (int i = 0; i < datas.length; i++)
for (int j = 0; j < datas[i].length; j++)
if(datas[i][j] != victory[i][j])
//return --- 可以写在方法当中
// 1,停止方法
// 2,将return后面的数据,返回给调用者。
return false;
return true;
...
8,计步功能
我们在玩游戏的时候,为了体现我们很厉害,通常都会看多少步完成了这个游戏。所以,我们也要加一个计步功能。
计步功能其实就是定义一个变量,每移动一步就自增一次。将这个变量的最新值显示在界面上就可以了。
实现步骤:
1,因为在多个方法中使用,所以在类的上面定义一个变量step
2,在move方法中,按上下左右的时候,按一次step需要++一次。
3,讲step显示在界面上。
public class MyJFrame extends JFrame implements KeyListener
//第一步:统计走了多少步的变量
int step = 0;
//第二步:move方法中step自增。
public void move(int keyCode)
if (keyCode == 37)
//左
//表示空格右边的图片要向左移动
datas[x0][y0] = datas[x0][y0 + 1];
datas[x0][y0 + 1] = 0;
y0++;
step++;
else if (keyCode == 38)
//上
//表示空格下面的图片要向上移动
datas[x0][y0] = datas[x0 + 1][y0];
datas[x0 + 1][y0] = 0;
x0++;
step++;
else if (keyCode == 39)
//右
//表示空格在左边的图片要向右移动
datas[x0][y0] = datas[x0][y0 - 1];
datas[x0][y0 - 1] = 0;
y0--;
step++;
else if (keyCode == 40)
//下
//表示空格在上面的图片要向下移动
datas[x0][y0] = datas[x0 - 1][y0];
datas[x0 - 1][y0] = 0;
x0--;
step++;
else if (keyCode == 87)
//w 表示作弊码
datas = new int [][]1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,0;
else
System.out.println("只能按上下左右");
//第三步:将step的值显示到界面上
public void initImage()
...
JLabel label_step = new JLabel("步数:" + step);
label_step.setBounds(50,20,100,20);
this.add(label_step);
...
9,重新开始
当一局游戏结束了,想重新开始玩第二局的时候,可以点击菜单里面的功能—重新游戏。
重新游戏,顾名思义,一切从头开始。
- 1-15张数字图片要重新打乱顺序。
- 计步器的值要清0。
9.1ActionListener接口
我们点击重新游戏按键是没有任何反应的,因为我们还没有监听他。
所以,我们还要学习一个接口,ActionListener接口。这个接口就可以监听用户按了游戏里面的哪些组件。
示例代码如下:
如果实现多个接口,那么接口之间要用逗号隔开。
public class MyJFrame extends JFrame implements KeyListener, ActionListener
...
然后把里面所有的方法自己补全。但是不需要自己手写,用鼠标点击一下红色波浪线,按下快捷键:alt+enter。这样就可以自动生成。
public class MyJFrame extends JFrame implements KeyListener, ActionListener
...
@Override
public void actionPerformed(以上是关于Java《石头迷阵03》黑马程序员官方出版知识重点+笔记源码的主要内容,如果未能解决你的问题,请参考以下文章