Java《石头迷阵03》黑马程序员官方出版知识重点+笔记源码

Posted 黑马程序员官方

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java《石头迷阵03》黑马程序员官方出版知识重点+笔记源码相关的知识,希望对你有一定的参考价值。

更多Java全套学习资源均在专栏,持续更新中↑↑戳进去领取~

🍅2022年全新Java学习路线图,含源码+笔记,另附在职提升课
🍅跟我20天学Java:01-计算机基础以及JDK、IDEA等安装详解
🍅跟我20天学Java:02-自动类型转换,表达式的自动类型转换,强制类型转换
🍅跟我20天学Java:03-6个案例手把手带你学循环结构

🍉Maven简介以及手把手教你下载安装

🍨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》黑马程序员官方出版知识重点+笔记源码的主要内容,如果未能解决你的问题,请参考以下文章

Java《石头迷阵02》黑马程序员官方出版万字教程+源码

Java《石头迷阵04》涉及Java全部知识点总结

《Java Web程序设计任务教程》重点知识总结(Java高级开发技术知识点总结)

求黑马java的全部全套视频

大学生利用假期恶补Java基础,时间安排+知识整理

黑马Java EE49期基础班+就业班全套 视频教程