用Java实现连连看小游戏

 更新时间:2022年05月09日 14:42:27   作者:zoeZiYu  
这篇文章主要为大家详细介绍了用Java实现连连看小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

很多人写游戏都是从连连看或者五子棋这类的简单小游戏入手的,最近我也尝试着写了一个连连看,想要再梳理一遍其中的思路。

连连看的规则

连连看要求在一定范围内找到两个特征一样并且能够通过空白的通道在两折(直角)以内相连的东西,连续点击两个东西之后消除。
通常我们会选择用图片来进行匹配,这样更直观有趣。

如何存储连连看的数据

使用二维数组进行存储,每一个数组元素对应一个位置上的图片种类。
例如我们分别用1,2,3,4代表四个不同的图片,用0代表没有图片;那么二维数组{{},{},{},{}}就相应地存储对应位置的数据。如果要对图片进行变更(连连看中的消除),那么只需要改变该位置对应的数组元素的值就行了(在这个例子中,消除就改为0)。

如何实现数组数据的初始化

1、一般来说连连看开始都会随机生成图片,此处的随机生成需要用到Random类里面的nextInt方法,能随机生成给定范围内的随机一个整数。
2、我们生成数组的时候要考虑一个问题:连连看相同的图片个数是偶数,这样才不会到最后形成落单的尴尬局面。

//随机给出数组值,初始化游戏数据
public int[][] DATA(int[][] data){
            
            int[][] d=data;
            Random random=new Random();
            for(int i=0;i<8;i++){
                d[0][i]=0;
                d[7][i]=0;
            }
            for(int i=1;i<7;i++){
                d[i][0]=0;
                d[i][7]=0;
            }
            for(int i=0;i<18;i++){
                
            
                int m=random.nextInt(Const.Const_TYPECOUNNT)+1;
                int x1=random.nextInt(Const.COL)+1;
                int y1=random.nextInt(Const.COL)+1;
                
                while(d[x1][y1]!=0){
                    
                    x1=random.nextInt(Const.COL)+1;
                    y1=random.nextInt(Const.COL)+1;
                }
                d[x1][y1]=m;    
                int x2=random.nextInt(Const.COL)+1;
                int y2=random.nextInt(Const.COL)+1;
                while(d[x2][y2]!=0){
                    
                    x2=random.nextInt(Const.COL)+1;
                    y2=random.nextInt(Const.COL)+1;
                
            }
            d[x2][y2]=m;
            }
            return(d);
            
        }

如何绘制图片

连连看的存储都是以int的类型存储的,可我们要呈现出来的效果是一张一张的图片……
先用Image导入所有图片,最好图片的命名能够用数字命名,这样就可以批量导入了。这里就不过多赘述了,看实例代码吧:

 public void init(){
        imgArr = new Image[Const.Const_TYPECOUNNT];
        for(int i=0; i < imgArr.length; i++){
        imgArr[i] = new ImageIcon("llkImage/"+i+".jpg").getImage();
        }
    }

关于图片大小的调整我用的是比较原始的方法:编辑图片本身像素大小;还可以通过drawImage来直接规定大小。

重绘棋子

没有重绘的窗体在我们对其进行拖动或者最小化等改变的时候会变成空白的,重绘就是将窗体的paint方法重写,这样对窗体的任何操作都会将paint方法重新写一遍。也就是在屏幕上重新画一遍。
我们的棋子都存在一个二维数组里面,那么我们就可以将棋子绘制的步骤放在重绘里面来实现,那么棋子就跟窗体一样,可以“一直存在”了,也可以根据数组的改变来改变。

代码示例:

public void paint(Graphics g) {
        // 重绘paint方法
        super.paint(g);
        //

        for (int i = 1; i < Const.COL+1; i++) {
            for (int j = 1; j < Const.ROW+1; j++) {        
        if (data[i][j] == 0) {
            g.setColor(new Color(69,175,198));
            g.fillRect(Const.START_X + i * Const.SIZE, Const.START_Y + j * Const.SIZE, Const.SIZE, Const.SIZE);
        } 
        else {
            g.drawImage(imgArr[data[i][j]-1], Const.START_X + i * Const.SIZE, Const.START_Y + j * Const.SIZE, null);
             
            }
        }
    }

连连看的实现算法

两个图片消除的方法有三种:

1.直线连接
2.一折连接
3.二折连接

其中二折连接可以找一个点既与其中一个图片一折连接又与另一个图片直线连接;一折连接又可以找一个点与其中一个图片直线连接又与另一个图片直线连接。
所以综上所述,只需要写出一个直线连接的判断方法,我们所有的规则方法就都可以实现了。

数组的元素=0时代表这里的图片为空,有路可走。
首先,两个数组元素直线相连的前提是这两个元素的横坐标或者纵坐标相等且路径上的数组元素全部为零。

代码示例:

//0折点的方法
public boolean zero(int[][] data,int X1, int Y1,int X2,int Y2){
        int max; 
        int min;
    
        //x值相等
        if(X1==X2){
            max=Y1 > Y2 ? Y1:Y2;
            min=Y1 < Y2 ? Y1:Y2;
            for(int i=min+1;i<max;i++){
                if(data[X1][i]!=0){
                    return false;
                }
            }
            return true;
        }
        //y值相等
        else if(Y1==Y2){
            max=X1 > X2 ? X1:X2;
            min=X1 < X2 ? X1:X2;
            for(int i=min+1;i<max;i++){
                if(data[i][Y1]!=0){
                    return false;
                }
            }
        return true;
        }
        else return false;
    }
    //1折点的方法
    public boolean one(int[][] data,int X1, int Y1,int X2,int Y2){
        
        if((zero(data,X1,Y1,X1,Y2)&&zero(data,X1,Y2,X2,Y2)&&data[X1][Y2]==0)||(data[X2][Y1]==0&&zero(data,X1,Y1,X2,Y1)&&zero(data,X2,Y1,X2,Y2))){
            return true;
        }
        return false;
        }
    
    //2折点的方法
    public boolean two(int[][] data,int X1, int Y1,int X2,int Y2){ 
        //向下寻找一个第一折点
        for(int i=X1+1;i<=Const.COL+1;i++){
            if(zero(data,X1,Y1,i,Y1)&&one(data,i,Y1,X2,Y2)){
                return true;
            }
        }
        //向上寻找一个第一折点
        for(int i=X1-1;i>=0;i--){
            if(zero(data,X1,Y1,i,Y1)&&one(data,i,Y1,X2,Y2)){
                return true;
            }
        }
        //向左
        for(int i=Y1-1;i>=0;i--){
            if(zero(data,X1,Y1,X1,i)&&one(data,X1,i,X2,Y2)){
                return true;
            }
        }
        //向右
        for(int i=Y1+1;i<=Const.ROW+1;i++){
            if(zero(data,X1,Y1,X1,i)&&one(data,X1,i,X2,Y2)){
                return true;
            }
        }
        return false;
    }

如何获取两次鼠标点击的位置

废话不多说,直接上代码:

//鼠标点击松开事件
public void mouseReleased(MouseEvent e) {
        int x,y;
        Rule rule = new Rule();
        x = e.getX();
        y = e.getY();
        
        if(count%2==0){
        X1 = (x - Const.START_X) / Const.SIZE;
        Y1 = (y - Const.START_Y) / Const.SIZE;
        count++;
        }
        else {
        X2 = (x - Const.START_X) / Const.SIZE;
        Y2 = (y - Const.START_Y) / Const.SIZE;
        count++;
        if (rule.judge(X1, Y1, X2, Y2, data)&&
                (rule.zero(data,X1,Y1,X2,Y2)||rule.one(data, X1, Y1, X2, Y2)||rule.two(data, X1, Y1, X2, Y2))){
            data[X1][Y1]=0;data[X2][Y2]=0;
        }
        }
        
        ui.repaint();
        
    }

成果展示

以上,我的游戏还是个很简单的模板,仍待完善,可以把界面做得更精美,还可以增加游戏难度的选择以及时间和步数的规定,最后还可以加上游戏的输赢判断,希望能够帮助到有需要的人。

相关文章

  • InputStreamReader和BufferedReader用法及实例讲解

    InputStreamReader和BufferedReader用法及实例讲解

    这篇文章主要介绍了InputStreamReader和BufferedReader用法及实例讲解的相关资料,需要的朋友可以参考下
    2015-12-12
  • Java 覆盖equals时总要覆盖hashcode

    Java 覆盖equals时总要覆盖hashcode

    这篇文章主要介绍了Java 覆盖equals时总要覆盖hashcode的相关资料,这里附有实例代码,具有参考价值,需要的朋友可以参考下
    2016-12-12
  • 6种Java创建对象的方式总结

    6种Java创建对象的方式总结

    在Java中,创建对象可以使用多种方式,本文将详细介绍以下六种创建对象的方式,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起了解一下
    2023-04-04
  • java数据结构与算法之希尔排序详解

    java数据结构与算法之希尔排序详解

    这篇文章主要介绍了java数据结构与算法之希尔排序,结合实例形式分析了希尔排序的概念、原理、实现方法与相关注意事项,需要的朋友可以参考下
    2017-05-05
  • SpringBoot校园综合管理系统实现流程分步讲解

    SpringBoot校园综合管理系统实现流程分步讲解

    这篇文章主要介绍了SpringBoot+Vue实现校园综合管理系统流程分步讲解,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-09-09
  • 最最常用的 100 个 Java类分享

    最最常用的 100 个 Java类分享

    这篇文章主要介绍了最最常用的 100 个 Java类分享,需要的朋友可以参考下
    2015-04-04
  • 深入了解为什么Java中只有值传递?

    深入了解为什么Java中只有值传递?

    这篇文章主要介绍了为什么 Java 中只有值传递?下面我们来简单了解一下吧
    2019-05-05
  • 解决springboot配置logback-spring.xml不起作用问题

    解决springboot配置logback-spring.xml不起作用问题

    这篇文章主要介绍了解决springboot配置logback-spring.xml不起作用问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-11-11
  • Java实现SM3加密和验证的示例代码

    Java实现SM3加密和验证的示例代码

    在商用密码体系中,SM3主要用于数字签名及验证、消息认证码生成及验证、随机数生成等,其算法公开,本文给大家详细介绍了使用Java实现SM3加密和验证,文中有详细的代码示例供大家参考,需要的朋友可以参考下
    2023-12-12
  • java实现飞机大战小游戏

    java实现飞机大战小游戏

    这篇文章主要为大家详细介绍了java实现飞机大战小游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-06-06

最新评论