Java实现拼图小游戏(6)—— 移动图片(键盘监听实操练习)

简介: 当我们实现向上移动图片的时候,其实就是把空图片的下面一张图片往上移动,然后将空图片的下面那张图片设置为空图片,最后再调整初始位置为现在空图片所在位置即可,注意做完这些以后还要再加载图片,否则显示不出来

一、前言


在美化完界面以后,我们就要给拼图小游戏注入灵魂了!那就是要实现移动图片的效果,这里我们使用键盘的上下左右键来实现移动图片的效果,也就是我们上一次说到的键盘监听效果,如果对于键盘监听效果还是不明白的小伙伴可以点击查看文章回顾一下【Java中的键盘监听机制(含实例)】


二、步骤


1.让我们的类继承KeyListener接口


public class GameJFrame extends JFrame implements KeyListener


2.改写initData方法


我们曾经提到过,对于存放图片我们要使用二维数组来存放,并且有一个非常简洁的写法,由于我们一共要添加15张图片,还有一张图片是空白的,也就是编号为0的图片,所以当我们遇到为0的图片时,要把其对应的二维数组的坐标提取出来,方便与其上下左右的图片进行交换,来达到移动图片的效果,遇到编号不为0的图片那就放入二维数组即可


这里给出判断的部分代码


  if(tempArr[i] == 0){
    x = i / 4;
      y = i % 4;
  }
  else{
    data[i/4][i%4] = tempArr[i];
   }


3.实现向上移动


这里我们要重新接口内的方法,但是由于游戏需要,我们只需要重写松开键盘时触发的代码块即可,剩下的就不需要重写了,可以空着

当我们实现向上移动图片的时候,其实就是把空图片的下面一张图片往上移动,然后将空图片的下面那张图片设置为空图片,最后再调整初始位置为现在空图片所在位置即可,注意做完这些以后还要再加载图片,否则显示不出来


2505553e47054350b2a2c0a002516944.png


像这张图片就是将右下角的空图片上移,并把右下角设置为空图片,最后将右下角的坐标设置为初始坐标


      //将下面的图片上移
            data[x][y] = data[x+1][y];
            //将下面的图片设为空白图片(编号为0)
            data[x+1][y] = 0;
            //将初始图片位置设置为空白图片位置
            x++;
            //加载图片
            initImage();


4.实现向下移动


同理,将上面的图片往下移


  //将上面的图片上移
  data[x][y] = data[x-1][y];
    //将上面的图片设为空白图片(编号为0)
    data[x-1][y] = 0;
    //将初始图片设置为空白图片对应位置
    x--;
    //加载图片
  initImage();


5.实现向左移动


  //将右面的图片左移
  data[x][y] = data[x][y+1];
  //将右面的图片设为空白图片(编号为0)
  data[x][y+1] = 0;
  //将初始图片设置为空白图片对应位置
  y++;
  //加载图片
  initImage();


6.实现向右移动


  //将左面的图片右移
    data[x][y] = data[x][y-1];
    //将左面的图片设为空白图片(编号为0)
    data[x][y-1] = 0;
    //将初始图片设置为空白图片对应位置
    y--;
    //加载图片
    initImage();


7.改写initImage方法


在上文中我们提到,先加载的图片会出现在上方,所以当我们移动图片并重写加载的时候,我们需要将原先的图片清除才可以展现出移动后的图片,否则会出现覆盖,无法看到正确效果,在加载完图片以后也要再刷新一次,以保证其效果能够正确展示


清除图片(写在方法体第一行)


this.getContentPane().removeAll();


刷新界面(写在方法体最后一行)


this.getContentPane().repaint();


8.为JFrame添加键盘监听


this.addKeyListener(this);


三、优化代码


当我们遇到边界的时候,无法执行操作,那么这时候就需要重新让用户去操作,这里的判断条件在于每个上下左右操作的最后一行代码,让变量不要超过数组定义的长度即可


例如:

方法体内最后语句是:x++,由于数组最大长度是3,所以当x等于3时无法执行该语句,就要返回,让用户重新操作


if(x == 3){
  return;
}


四、完整代码


    @Override
    public void keyReleased(KeyEvent e){
        int code = e.getKeyCode();
        //向左移动
        if(code == 37){
            System.out.println("向左移动");
            if(y == 3){
                return;
            }
            //将右面的图片左移
            data[x][y] = data[x][y+1];
            //将右面的图片设为空白图片(编号为0)
            data[x][y+1] = 0;
            //将初始图片设置为空白图片对应位置
            y++;
            //加载图片
            initImage();
        }
        //向上移动
        else if(code == 38){
            System.out.println("向上移动");
            if(x == 3){
                return;
            }
            //将下面的图片上移
            data[x][y] = data[x+1][y];
            //将下面的图片设为空白图片(编号为0)
            data[x+1][y] = 0;
            //将初始图片位置设置为空白图片位置
            x++;
            //加载图片
            initImage();
        }
        //向右移动
        else if(code == 39){
            System.out.println("向右移动");
            if(y == 0){
                return;
            }
            //将左面的图片右移
            data[x][y] = data[x][y-1];
            //将左面的图片设为空白图片(编号为0)
            data[x][y-1] = 0;
            //将初始图片设置为空白图片对应位置
            y--;
            //加载图片
            initImage();
        }
        //向下移动
        else if(code == 40){
            System.out.println("向下移动");
            if(x == 0){
                return;
            }
            //将上面的图片下移
            data[x][y] = data[x-1][y];
            //将上面的图片设为空白图片(编号为0)
            data[x-1][y] = 0;
            //将初始图片设置为空白图片对应位置
            x--;
            //加载图片
            initImage();
        }
    }


五、结语


如果不知道上下左右对应编号,可以通过文章开头的连接去查看方法,找到编号,这里主要是移动的思路比较难,搞清楚思路后写代码其实会很方便,如果有任何问题欢迎留言评论

目录
打赏
0
0
0
0
1
分享
相关文章
|
4月前
|
Java开发实现图片URL地址检验,如何编码?
【10月更文挑战第14天】Java开发实现图片URL地址检验,如何编码?
132 4
|
4月前
|
Java开发实现图片地址检验,如果无法找到资源则使用默认图片,如何编码?
【10月更文挑战第14天】Java开发实现图片地址检验,如果无法找到资源则使用默认图片,如何编码?
97 2
菜鸟之路day02-04拼图小游戏开发一一JAVA基础综合项目
本项目基于黑马程序员教程,涵盖面向对象进阶、继承、多态等知识,历时约24小时完成。项目去除了登录和注册模块,专注于单机游戏体验。使用Git进行版本管理,代码托管于Gitee。项目包含窗体搭建、事件监听、图片加载与打乱、交互逻辑实现、菜单功能及美化界面等内容。通过此项目,巩固了Java基础并提升了实际开发能力。 仓库地址:[https://gitee.com/zhang-tenglan/puzzlegame.git](https://gitee.com/zhang-tenglan/puzzlegame.git)
41 6
Java ffmpeg 实现视频加文字/图片水印功能
【10月更文挑战第22天】在 Java 中使用 FFmpeg 实现视频加文字或图片水印功能,需先安装 FFmpeg 并添加依赖(如 JavaCV)。通过构建 FFmpeg 命令行参数,使用 `drawtext` 滤镜添加文字水印,或使用 `overlay` 滤镜添加图片水印。示例代码展示了如何使用 JavaCV 实现文字水印。
300 1
java基础:map遍历使用;java使用 Patten 和Matches 进行正则匹配;后端传到前端展示图片三种情况,并保存到手机
这篇文章介绍了Java中Map的遍历方法、使用Pattern和matches进行正则表达式匹配,以及后端向前端传输图片并保存到手机的三种情况。
49 1
java制作海报四:java BufferedImage 转 InputStream 上传至OSS。png 图片合成到模板(另一个图片)上时,透明部分变成了黑色
这篇文章主要介绍了如何将Java中的BufferedImage对象转换为InputStream以上传至OSS,并解决了png图片合成时透明部分变黑的问题。
180 1
时间轮-Java实现篇
在前面的文章《[时间轮-理论篇](https://developer.aliyun.com/article/910513)》讲了时间轮的一些理论知识,然后根据理论知识。我们自己来实现一个简单的时间轮。
【JAVA】封装多线程原理
Java 中的多线程封装旨在简化使用、提高安全性和增强可维护性。通过抽象和隐藏底层细节,提供简洁接口。常见封装方式包括基于 Runnable 和 Callable 接口的任务封装,以及线程池的封装。Runnable 适用于无返回值任务,Callable 支持有返回值任务。线程池(如 ExecutorService)则用于管理和复用线程,减少性能开销。示例代码展示了如何实现这些封装,使多线程编程更加高效和安全。
|
1月前
|
java异步判断线程池所有任务是否执行完
通过上述步骤,您可以在Java中实现异步判断线程池所有任务是否执行完毕。这种方法使用了 `CompletionService`来监控任务的完成情况,并通过一个独立线程异步检查所有任务的执行状态。这种设计不仅简洁高效,还能确保在大量任务处理时程序的稳定性和可维护性。希望本文能为您的开发工作提供实用的指导和帮助。
100 17
|
2月前
|
Java—多线程实现生产消费者
本文介绍了多线程实现生产消费者模式的三个版本。Version1包含四个类:`Producer`(生产者)、`Consumer`(消费者)、`Resource`(公共资源)和`TestMain`(测试类)。通过`synchronized`和`wait/notify`机制控制线程同步,但存在多个生产者或消费者时可能出现多次生产和消费的问题。 Version2将`if`改为`while`,解决了多次生产和消费的问题,但仍可能因`notify()`随机唤醒线程而导致死锁。因此,引入了`notifyAll()`来唤醒所有等待线程,但这会带来性能问题。
Java—多线程实现生产消费者
AI助理

你好,我是AI助理

可以解答问题、推荐解决方案等