Java课设 2048小游戏

题目:2048小游戏

目录

1. 引言

2. 主要模块设计

1)游戏面板

2)移动

3)失败

4)新游戏

5)退出

3. 系统实现

1)游戏面板

2)移动

3)失败

4)新游戏

5)退出

4. 结论


1. 引言

2048》是一款比较流行的数字游戏,最早于2014320日发行。原版2048首先在GitHub上发布,原作者是Gabriele Cirulli,后被移植到各个平台。这款游戏是基于《1024》和《小3传奇》的玩法开发而成的新型数字游戏。

2. 主要模块设计

1)游戏面板

Java课设 2048小游戏_第1张图片

   图2.1

        显示得分,最高分,当你的分数大于最高分BEST将记录到最高分BEST

2)移动

Java课设 2048小游戏_第2张图片Java课设 2048小游戏_第3张图片

               2.2.1                                                           2.2.2

如上二图,2.2.2是图2.2.1向左移动了一步

当键盘按下”↑↓←→”,便可进行移动操作.

合并后的数值将记录到得分里

3)失败

Java课设 2048小游戏_第4张图片

                      2.3.1

如图当游戏界面没有可合并的方块了,并且没有空的方块了,则游戏失败.

4)新游戏

Java课设 2048小游戏_第5张图片

图2.2.4

点击”newgame”按钮,开始新一轮游戏.

5)退出

如图2.2.4所示,点击”exit”按钮,退出游戏.

3. 系统实现

1)游戏面板

Java课设 2048小游戏_第6张图片

“SCORE”,” BEST”是分别添加了两个JPanel面板.

        “BEST”面板记录的分数是通过文本文件记录.

        下面的方块面板,是在4*4的二维数组的辅助下实现的,每个方块都是一个JLabel,

存放一个图片.通过对二维数组的元素的值的设置和图片名称的设置.

//用二维数组来控制面板图片

int [][] arr = {

                     {2,4,8,256},

                     {256,128,16,4},           

                     {4,32,4,8},

                     {8,2,8,2} };

for(int i=0;i<4;i++) {

                     for(int j=0;j<4;j++) {

                  //通过二维数组的元素的值与图片一一对应

                            JLabel img=new JLabel(new ImageIcon("F:\\Java\\Game\\icon\\icon-    "+arr[i][j]+".png"));

                           

                            p3.add(img);

                            img.setBounds(5+j*105, 5+i*105, 100, 100);

                     }                         

              }

2)移动

Java课设 2048小游戏_第7张图片Java课设 2048小游戏_第8张图片

               2.2.1                                     2.2.2

如上二图,2.2.2是图2.2.1向左移动了一步

首先,添加键盘监听给窗口frame,当键盘按下”↑↓←→”,便可进行移动操作.

比如,某一行在左移动时,需要先判断该行是否有0元素,如果有就需要将其移动到该行的最后,其他元素向前移动.然后判断该元素与后一个元素是否相同,如果相同就进行合并.合并的数字大小的值计入得分SCROCE.

在移动一次后,便重新绘制面板.

以左移动为例

public void MoveLeft(int flag) {//左移动

         //1.将每一行的中的0放到最后

         for(int i=0;i<arr.length;i++) {

             int[] newarr =new int[4]; //创建一个新的一维数组,

             int index=0;               //在该数组的前面存放第i行的非0元素,0元素放到

                                        //后面(系统默认值为0,所以不用管)

             for(int x=0;x<arr[i].length;x++) {

                 if(arr[i][x]!=0) {//不等于0的元素就先放进去

                    newarr[index]=arr[i][x];

                    index++;

                 }

             }

             arr[i]=newarr;//重新给arr[i]           

             //2.合并元素

             for(int x=0;x<3;x++) {//注意:当某一个元素合并后,不会再和后面的元素作合并

                 if(arr[i][x]==arr[i][x+1]) {//若该元素与后面的元素相同则合并

                    arr[i][x]*=2;

                    if(flag==1) {

                        score+=arr[i][x];//计算得分

                    }

                    //后面的元素向前移动

                    for(int j=x+1;j<3;j++) {

                        arr[i][j]=arr[i][j+1];

                    }

                    arr[i][3]=0;//最后再补0

                 }

             }                            

         }

         cude();

         p3.repaint();//刷新界面

     }

之所以要加个int 参数,是为了区分和模拟移动的操作.下面会说明.

3)失败

每次进行移动前,进行当前游戏界面模拟移动,若上下左右都不能移动,则游戏结束,

弹出失败面板.

依旧以左移动为例

public boolean checkLeft() {//判断是否可以向左移动

        boolean flag=true;

        copy(arr,beifen); 

        //左移动

        MoveLeft(0);

        //判断是否相同   

        flag=notEquals(arr,beifen);//若不相同则返回true

        //System.out.println(flag);

        copy(beifen,arr);//恢复原来的数组

        return flag;

     }

因为要调用到左移动函数,若不加参数控制,在进行模拟的时候,得分会被记录进去.所有当参数为1,才记录得分,参数为0,不记录得分.

4)新游戏

Java课设 2048小游戏_第9张图片

点击”newgame”按钮,进入endAction监听器处理,对部分数值进行重新设置,对面板重新绘制.

class endAction implements ActionListener{

              @Override

              public void actionPerformed(ActionEvent e) {

                     // TODO Auto-generated method stub

                     String s=e.getActionCommand();//获取命令

                     switch (s) {

                     case "newgame":{                      

                            loseflat=0;//更新失败标志

                            score=0;

                            view();

                            cude();

                            p3.remove(losePanel);

                            p3.repaint();

                            frame.this.requestFocus();//将该窗口设为焦点                

                     }

                            break;

                     default:

                            savePoint();

                            System.exit(0);

                            break;

                     }           

              }           

        }

5)退出

点击”exit”按钮,进入endAction监听器处理事件,关闭窗口,将最高分写入文本文件.

void savePoint() {//将最高分储存在BEST.txt

               try{                                                         

                    FileWriter fileWritter = new FileWriter(file.getName());

                    fileWritter.write(bestscore+"");      

                    fileWritter.close();         

                   }catch(IOException e){

                    e.printStackTrace();

                   }

        }

4. 结论

本程序大体上虽然实现了2048游戏的功能,但依然存在部分功能需要改进,如方块移动的画面,该程序只有移动过去后的结果,而没有方块移动的过程.看上去有点生硬,不是很流畅.在完成这个程序时,遇到了焦点的问题,即在点击完”newgame”,焦点已经不是游戏窗口.我还以为要用FocusEvent来处理,调试了许久还是不行,最后, requestFocus()(为控件设置焦点)解决了.

源码

        关注公众号,领取资源

你可能感兴趣的:(java,java,swing)