当前位置:网站首页 > Java教程 > 正文

java 2048教程



package com.baidu.czy;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.util.Arrays;
import java.util.Random;
import javax.swing.*;


public class ComponentListener extends KeyAdapter implements ActionListener {


    private GameStart UI;// 界面对象
    private int Numbers[][];// 存放数据的数组
    private Random rand = new Random();
    private int BackUp[][] = new int[4][4];//用于备份数组,供回退时使用
    private int BackUp2[][] = new int[4][4];//用于备份数组,供起死回生时使用
    public JLabel lb;   //分数标签
    int score = 0;
    int tempscore, tempscore2;//记录回退的分数值
    public JButton bt, about, back;
    public JCheckBox isSoundBox;
    //是否胜利,true:胜利,false:失败
    private boolean isWin = false;
    //是否复活,true:使用复活,false:不使用复活
    private boolean relive = false;
    //是否可以回退,true:不可回退,false:可以回退  (是否已经进行过一次回退了)
    private boolean hasBack = false;
    //是否播放音乐,true:播放音效,false:不播放音效
    private boolean isSound = true;
    //事件
    private ActionEvent e;



    public ComponentListener(GameStart UI, int[][] Numbers, JLabel lb, JButton bt, JButton about, JButton back, JCheckBox isSoundBox) {
        this.UI = UI;
        this.Numbers = Numbers;
        this.lb = lb;
        this.bt = bt;
        this.about = about;
        this.back = back;
        this.isSoundBox = isSoundBox;
    }

   @Override
   public void actionPerformed(ActionEvent e) {
          if (e.getSource() == bt ) {
              //游戏开始
              isWin = false;
              //各个小格赋初值0
              for (int i = 0; i < 4; i++)
                  for (int j = 0; j < 4; j++)
                      Numbers[i][j] = 0;
                      //游戏开始,分数为0
                      score = 0;
                      lb.setText("分数:" + score);
                      //生成4个0-3之间的随机数
                      int r1 = rand.nextInt(4);
                      int r2 = rand.nextInt(4);
                      int c1 = rand.nextInt(4);
                      int c2 = rand.nextInt(4);
                      //由r1,c1;r2,c2组成两个初始值,所以初始值的坐标不能重复
                      while (r1 == r2 && c1 == c2) {
                          r2 = rand.nextInt(4);
                          c2 = rand.nextInt(4);
                      }
                      // 生成初始数字(2或者4)
                      int value1 = rand.nextInt(2) * 2 + 2;
                      int value2 = rand.nextInt(2) * 2 + 2;

                      // 把数字存进对应的位置
                      Numbers[r1][c1] = value1;
                      Numbers[r2][c2] = value2;
                      //数字更改,重新绘制图形,为此组件创建图形上下文
                      UI.paint(UI.getGraphics());




        } else if (e.getSource() == about) {
            //点击了关于标签
            JOptionPane.showMessageDialog(UI, "游戏规则:
"
                    + "1、开始时棋盘内随机出现两个数字,出现的数字仅可能为2或4
"
                    + "2、玩家可以选择上下左右四个方向,若棋盘内的数字出现位移或合并,视为有效移动
"
                    + "3、玩家选择的方向上若有相同的数字则合并,每次有效移动可以同时合并,但不可以连续合并
"
                    + "4、合并所得的所有新生成数字相加即为该步的有效得分
"
                    + "5、玩家选择的方向行或列前方有空格则出现位移
"
                    + "6、每有效移动一步,棋盘的空位(无数字处)随机出现一个数字(依然可能为2或4)
"
                    + "7、棋盘被数字填满,无法进行有效移动,判负,游戏结束
"
                    + "8、棋盘上出现2048,判胜,游戏结束。
"
            );
        } else if (e.getSource() == back && hasBack == false) {
            System.out.println("回退");
            //点击了回退一步标签,而且只能回退一次,只有再执行一次上下左右操作才可以再次回退
            hasBack = true;
            //判断本次回退是回退上一步,还是复活,回退上上步
            if (relive == false) {
                //替换上一步的分数
                score = tempscore;
                lb.setText("分数:" + score);
                for (int i = 0; i < BackUp.length; i++) {
                    Numbers[i] = Arrays.copyOf(BackUp[i], BackUp[i].length);
                }
            } else {
                //选择了起死回生
                score = tempscore2;
                lb.setText("分数:" + score);
                for (int i = 0; i < BackUp2.length; i++) {
                    Numbers[i] = Arrays.copyOf(BackUp2[i], BackUp2[i].length);
                }
                //再给一次复活的机会
                relive = false;
            }
            //重新绘制
            UI.paint(UI.getGraphics());
        } else if (e.getSource().equals(isSoundBox)) {
            //是否选中静音复选框
            if (isSoundBox.isSelected()) {
                isSound = false;
            } else {
                isSound = true;
            }
        }
    }




    // 键盘监听,监听游戏焦点的←,↑,→,↓;方向键键值:左:37上:38右:39下:40
    public void keyPressed(KeyEvent event) {

        int Counter = 0;// 记录数字有效移动位数,判断是否移动了
        int NumCounter = 0;// 记录当前有数字的小方格数量,判断是否已满
        int NumNearCounter = 0;// 记录相邻格子数字相同的对数

        hasBack = false;
        //每次进行真正的移位合并操作之前,记录前一步

        //记录上上步
        if (BackUp != null || BackUp.length != 0) {
            tempscore2 = tempscore;// 先把分数备份好
            // 下面的for循环调用java.util.Arrays.copyOf()方法复制数组,实现备份
            for (int i = 0; i < BackUp.length; i++) {
                BackUp2[i] = Arrays.copyOf(BackUp[i], BackUp[i].length);
            }
        }
        //记录上步
        tempscore = score;// 先把分数备份好
        // 下面的for循环调用java.util.Arrays.copyOf()方法复制数组,实现备份
        for (int i = 0; i < Numbers.length; i++) {
            BackUp[i] = Arrays.copyOf(Numbers[i], Numbers[i].length);
        }

        if (isWin == false) {
            switch (event.getKeyCode()) {

                case 37:
                    // 向左移动
                    /*
                    (1)在移动的过程中,判断与其相邻的格子,如果相邻的格子为空,则移动,并将当前的格子清0
                    (2)移动后,若格子相邻并且数值相等,则求和并且清0
                     */
                    if (isSound == true) {
                        new PlaySound("E:\JavaProject\HandleGame2048(2)\src\main\resources\res\move.wav").start();// 播放移位音乐
                    }
                    //经过这个循环,把每行有值的格子,都被搬到最左边了,同一行右侧有值的格子,覆盖左侧值为0的格子
                    for (int h = 0; h < 4; h++)
                        for (int l = 0; l < 4; l++)
                            if (Numbers[h][l] != 0) {
                                int temp = Numbers[h][l];
                                //per相当于是相邻位置
                                int pre = l - 1;
                                while (pre >= 0 && Numbers[h][pre] == 0) {
                                    Numbers[h][pre] = temp;
                                    //移动后清0
                                    Numbers[h][pre + 1] = 0;
                                    pre--;
                                    Counter++;
                                }
                            }
                    //表盘当前左侧相邻相等的值会相加,造成左边值为【和】,相邻右边值为【0】
                    for (int h = 0; h < 4; h++)
                        for (int l = 0; l < 4; l++)
                            if (l + 1 < 4
                                    && (Numbers[h][l] == Numbers[h][l + 1])     //相邻两列数值相加,并要求两列不同时为0
                                    && (Numbers[h][l] != 0 || Numbers[h][l + 1] != 0)) {
                                if (isSound == true)
                                    new PlaySound("E:\JavaProject\HandleGame2048(2)\src\main\resources\res\merge.wav").start();
                                //数值合并
                                Numbers[h][l] = Numbers[h][l] + Numbers[h][l + 1];
                                Numbers[h][l + 1] = 0;
                                Counter++;
                                score += Numbers[h][l];
                                if (Numbers[h][l] == 2048) {
                                    isWin = true;
                                }
                            }
                    //经过这个循环,把每行有值的格子,都被搬到最左边了,同一行右侧有值的格子,覆盖左侧值为0的格子
                    for (int h = 0; h < 4; h++)
                        for (int l = 0; l < 4; l++)
                            if (Numbers[h][l] != 0) {
                                int temp = Numbers[h][l];
                                int pre = l - 1;
                                while (pre >= 0 && Numbers[h][pre] == 0) {
                                    Numbers[h][pre] = temp;
                                    Numbers[h][pre + 1] = 0;
                                    pre--;
                                    Counter++;
                                }
                            }
                    break;

                case 39:// 向右移动
                    if (isSound == true)
                        new PlaySound("E:\JavaProject\HandleGame2048(2)\src\main\resources\res\move.wav").start();
                    for (int h = 3; h >= 0; h--)
                        for (int l = 3; l >= 0; l--)
                            if (Numbers[h][l] != 0) {
                                int temp = Numbers[h][l];
                                int pre = l + 1;
                                while (pre <= 3 && Numbers[h][pre] == 0) {
                                    Numbers[h][pre] = temp;
                                    Numbers[h][pre - 1] = 0;
                                    pre++;
                                    Counter++;
                                }
                            }

                    for (int h = 3; h >= 0; h--)
                        for (int l = 3; l >= 0; l--)
                            if (l + 1 < 4
                                    && (Numbers[h][l] == Numbers[h][l + 1])
                                    && (Numbers[h][l] != 0 || Numbers[h][l + 1] != 0)) {
                                if (isSound == true)
                                    new PlaySound("E:\JavaProject\HandleGame2048(2)\src\main\resources\res\merge.wav").start();
                                Numbers[h][l + 1] = Numbers[h][l]
                                        + Numbers[h][l + 1];
                                Numbers[h][l] = 0;
                                Counter++;
                                score += Numbers[h][l + 1];
                                if (Numbers[h][l + 1] == 2048) {
                                    isWin = true;
                                }
                            }
                    for (int h = 3; h >= 0; h--)
                        for (int l = 3; l >= 0; l--)
                            if (Numbers[h][l] != 0) {
                                int temp = Numbers[h][l];
                                int pre = l + 1;
                                while (pre <= 3 && Numbers[h][pre] == 0) {
                                    Numbers[h][pre] = temp;
                                    Numbers[h][pre - 1] = 0;
                                    pre++;
                                    Counter++;
                                }
                            }
                    break;

                case 38:
                    // 向上移动
                    if (isSound == true)
                        new PlaySound("E:\JavaProject\HandleGame2048(2)\src\main\resources\res\move.wav").start();
                    for (int l = 0; l < 4; l++)
                        for (int h = 0; h < 4; h++)
                            if (Numbers[h][l] != 0) {
                                int temp = Numbers[h][l];
                                int pre = h - 1;
                                while (pre >= 0 && Numbers[pre][l] == 0) {
                                    Numbers[pre][l] = temp;
                                    Numbers[pre + 1][l] = 0;
                                    pre--;
                                    Counter++;
                                }
                            }
                    for (int l = 0; l < 4; l++)
                        for (int h = 0; h < 4; h++)
                            if (h + 1 < 4
                                    && (Numbers[h][l] == Numbers[h + 1][l])
                                    && (Numbers[h][l] != 0 || Numbers[h + 1][l] != 0)) {
                                if (isSound == true)
                                    new PlaySound("E:\JavaProject\HandleGame2048(2)\src\main\resources\res\merge.wav").start();
                                Numbers[h][l] = Numbers[h][l] + Numbers[h + 1][l];
                                Numbers[h + 1][l] = 0;
                                Counter++;
                                score += Numbers[h][l];
                                if (Numbers[h][l] == 2048) {
                                    isWin = true;
                                }
                            }

                    for (int l = 0; l < 4; l++)
                        for (int h = 0; h < 4; h++)
                            if (Numbers[h][l] != 0) {
                                int temp = Numbers[h][l];
                                int pre = h - 1;
                                while (pre >= 0 && Numbers[pre][l] == 0) {
                                    Numbers[pre][l] = temp;
                                    Numbers[pre + 1][l] = 0;
                                    pre--;
                                    Counter++;
                                }
                            }
                    break;

                case 40:
                    // 向下移动
                    if (isSound == true)
                        new PlaySound("E:\JavaProject\HandleGame2048(2)\src\main\resources\res\move.wav").start();
                    for (int l = 3; l >= 0; l--)
                        for (int h = 3; h >= 0; h--)
                            if (Numbers[h][l] != 0) {
                                int temp = Numbers[h][l];
                                int pre = h + 1;
                                while (pre <= 3 && Numbers[pre][l] == 0) {
                                    Numbers[pre][l] = temp;
                                    Numbers[pre - 1][l] = 0;
                                    pre++;
                                    Counter++;
                                }
                            }
                    for (int l = 3; l >= 0; l--)
                        for (int h = 3; h >= 0; h--)
                            if (h + 1 < 4
                                    && (Numbers[h][l] == Numbers[h + 1][l])
                                    && (Numbers[h][l] != 0 || Numbers[h + 1][l] != 0)) {
                                if (isSound == true)
                                    new PlaySound("E:\JavaProject\HandleGame2048(2)\src\main\resources\res\merge.wav").start();
                                Numbers[h + 1][l] = Numbers[h][l]
                                        + Numbers[h + 1][l];
                                Numbers[h][l] = 0;
                                Counter++;
                                score += Numbers[h + 1][l];
                                if (Numbers[h + 1][l] == 2048) {
                                    isWin = true;
                                }
                            }

                    for (int l = 3; l >= 0; l--)
                        for (int h = 3; h >= 0; h--)
                            if (Numbers[h][l] != 0) {
                                int temp = Numbers[h][l];
                                int pre = h + 1;
                                while (pre <= 3 && Numbers[pre][l] == 0) {
                                    Numbers[pre][l] = temp;
                                    Numbers[pre - 1][l] = 0;
                                    pre++;
                                    Counter++;
                                }
                            }
                    break;

            }
            //移位,合并,移位完成后,判断是否有可重复值
            for (int i = 0; i < 3; i++) {
                for (int j = 0; j < 3; j++) {
                    //判断相邻左右位置有没有重复值
                    if (Numbers[i][j] == Numbers[i][j + 1]
                            && Numbers[i][j] != 0) {
                        NumNearCounter++;
                    }
                    //判断相邻上下位置有没有重复值
                    if (Numbers[i][j] == Numbers[i + 1][j]
                            && Numbers[i][j] != 0) {
                        NumNearCounter++;
                    }
                    if (Numbers[3][j] == Numbers[3][j + 1]//第四行只需要判断是否与右边有重复
                            && Numbers[3][j] != 0) {
                        NumNearCounter++;
                    }
                    if (Numbers[i][3] == Numbers[i + 1][3]//第四列只需要判断与下边是否有重复
                            && Numbers[i][3] != 0) {
                        NumNearCounter++;
                    }
                }
            }
            //判断不为0的空余格子数
            for (int i = 0; i < 4; i++) {
                for (int j = 0; j < 4; j++) {
                    if (Numbers[i][j] != 0) {
                        NumCounter++;
                    }
                }
            }
            System.out.println(Counter);

            //有效移位数>0,则补充一个新的2或者4
            if (Counter > 0) {
                lb.setText("分数:" + score);
                //随机产生0~3的数字,选中位置
                int r1 = rand.nextInt(4);
                int c1 = rand.nextInt(4);
                while (Numbers[r1][c1] != 0) {
                    r1 = rand.nextInt(4);
                    c1 = rand.nextInt(4);
                }
                //产生2或4
                int value1 = rand.nextInt(2) * 2 + 2;
                Numbers[r1][c1] = value1;
            }

            if (isWin == true) {
                UI.paint(UI.getGraphics());
                JOptionPane.showMessageDialog(UI, "恭喜你赢了!
您的最终得分为:" + score);
            }

            if (NumCounter == 16 && NumNearCounter == 0) {
                //移动后满格并且没有可合并的小格子,游戏结束relive:复活一次
                relive = true;
                JOptionPane.showMessageDialog(UI, "没地方可以合并咯!!"
                        + "
很遗憾,您输了~>_<~" + "
悄悄告诉你,游戏有起死回生功能哦,不信你“退一步”试试?"
                        + "
说不定能扭转乾坤捏 (^_~)");
            }
            UI.paint(UI.getGraphics());
        }

    }

}

  • 上一篇: java客户端es教程
  • 下一篇: 兰州java教程
  • 版权声明


    相关文章:

  • java客户端es教程2024-10-12 20:26:01
  • java傻瓜教程2024-10-12 20:26:01
  • java蓝牙教程2024-10-12 20:26:01
  • 好的java教程2024-10-12 20:26:01
  • java版光影安装教程2024-10-12 20:26:01
  • 兰州java教程2024-10-12 20:26:01
  • layui与Java视频教程2024-10-12 20:26:01
  • java ocr教程2024-10-12 20:26:01
  • java全家桶教程2024-10-12 20:26:01
  • java教程92024-10-12 20:26:01