2021-01-23、24学习记录 || 2048小游戏的实现代码

由于离散老师放假了还不放过我们,本来昨天就应该完成的事拖到了今天现在,经过今天数个小时的学习和实践,2048小游戏成功制作完成,明天就可以把这个给妹妹玩。
太累了,今天先把代码给放出来,明天再把代码的注释和其他内容完善一下,这篇博客应该会长期修改,以最终完成所有功能的解释为最终版,加油!加油!

以下是源代码

import javax.swing.*;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.util.Random;


//创建子类继承JFrame类,目的是方便添加左移、右移等方法
public class MainFrame extends JFrame implements KeyListener {

    //制造二维数组对象来保存16个位置的图片编号
    int[][] dates = new int[4][4];

    //score用来记录得分
    int score = 0;

    //构造函数用于初始化一个Mainframe对象
    public MainFrame() {
        setframe();
        initdates();
        paintframe();
        this.addKeyListener(this);
        setVisible(true);
    }

    //setframe()用于窗口的初始化
    private void setframe() {

        //定义窗口宽度、高度
        setSize(500, 500);
        //设置窗口名
        setTitle("2048小游戏");
        //设置窗口居中
        setLocationRelativeTo(null);
        //设置窗口置顶
        setAlwaysOnTop(true);
        //设置窗口关闭程序运行结束,否则关闭窗口程序运行不会结束,需要手动结束
        setDefaultCloseOperation(3);
        //通过窗口对象,取消窗体内默认布局
        setLayout(null);
    }

    //initdates()用于数组初始化
    public void initdates(){
        addnum();
        addnum();
    }

    //paintframe()用于将窗体初始状况进行绘制
    private void paintframe() {
        //移除窗口所有图片
        getContentPane().removeAll();

        //检查是否还可以移动,不可以的话则显示失败的图片
        if(CheckMove() == false){
            JLabel loseJlabel = new JLabel(new ImageIcon("image\\A-lose.png"));
            loseJlabel.setBounds(83,130,334,228);
            getContentPane().add(loseJlabel);

        }

        //遍历二维数组将图片添加
        for (int i = 0; i < dates.length; i++) {
            for (int j = 0; j < dates[0].length; j++) {
                ImageIcon II = new ImageIcon("image\\A-" + dates[i][j] + ".png");
                JLabel jl = new JLabel(II);
                jl.setBounds(50 + 100 * j, 35 + 100 * i, 100, 100);
                getContentPane().add(jl);
            }
        }

        //添加背景图
        ImageIcon IBack = new ImageIcon("image\\A-Background.jpg");
        JLabel jlback = new JLabel(IBack);
        jlback.setBounds(50, 35, 400, 400);
        getContentPane().add(jlback);

        getContentPane().repaint();

        JLabel scorelabel = new JLabel("得分"+ score);
        scorelabel.setBounds(50,15,100,20);
        getContentPane().add(scorelabel);

    }

    @Override
    //根据按键进行相关操作
    public void keyPressed(KeyEvent e) {
        int key = e.getKeyCode();
        if (key == 37 || key == 65) {
            MoveToLeft();
            addnum();
        } else if (key == 38 || key == 87) {
            MoveToUp();
            addnum();
        } else if (key == 39 || key == 68) {
            MoveToRight();
            addnum();
        } else if (key == 40 || key == 83) {
            MoveToDown();
            addnum();
        }

        paintframe();

    }

    //此方法用于实现数据左移
    public void MoveToLeft() {
        for (int x = 0; x < dates.length; x++) {
            //完成0号后置
            int[] arr = new int[4];
            int index = 0;
            for (int i = 0; i < dates[0].length; i++) {
                if (dates[x][i] != 0) {
                    arr[index] = dates[x][i];
                    index++;
                }
            }

            dates[x] = arr;
            //完成一次左移操作
            for (int n = 0; n < 3; n++) {
                if (dates[x][n] == dates[x][n + 1]) {
                    dates[x][n] *= 2;

                    score += dates[x][n];

                    for (int j = n + 1; j < 3; j++) {
                        dates[x][j] = dates[x][j + 1];
                    }
                    dates[x][3] = 0;
                }
            }

        }
    }

    //一维数组翻转
    public void reverseArray(int[] arr) {
        for (int start = 0, end = arr.length - 1; start < end; start++, end--) {
            int temp = arr[start];
            arr[start] = arr[end];
            arr[end] = temp;
        }

    }

    //二维数组翻转
    public void re2DArray() {
        for (int i = 0; i < dates.length; i++) {
            reverseArray(dates[i]);
        }
    }

    //实现数据右移
    public void MoveToRight() {
        re2DArray();
        MoveToLeft();
        re2DArray();
    }

    //实现二维数组逆时针翻转
    public void ArrayCounterclockwise() {
        int[][] newarr = new int[4][4];
        for (int i = 0; i < dates.length; i++) {
            for (int j = 0; j < dates[0].length; j++) {
                newarr[3 - j][i] = dates[i][j];
            }
        }
        dates = newarr;
    }

    //实现数组顺时针翻转
    public void ArrayClockwise() {
        int[][] newarr = new int[4][4];
        for (int i = 0; i < dates.length; i++) {
            for (int j = 0; j < dates[0].length; j++) {
                newarr[j][3 - i] = dates[i][j];
            }
        }
        dates = newarr;
    }

    //实现数据上移动
    public void MoveToUp() {
        ArrayCounterclockwise();
        MoveToLeft();
        ArrayClockwise();
    }

    //实现数据下移动
    public void MoveToDown() {
        ArrayClockwise();
        MoveToLeft();
        ArrayCounterclockwise();
    }

    //判断是否可以移动
    public boolean CheckMove(){
        boolean bool = true;
        if(CheckLeft() == false && CheckRight() == false && CheckUp() == false && CheckDown() == false){
            bool = false;
        }
        return bool;
    }

    //判断是否则可以左移动
    public boolean CheckLeft(){
        int[][] newarr  = new int[4][4];
        copyArray(dates,newarr);
        MoveToLeft();
        boolean bool = CompareArray(dates,newarr);
        copyArray(newarr,dates);
        return bool;
    }

    //判断是否则可以右移动
    public boolean CheckRight(){
        int[][] newarr  = new int[4][4];
        copyArray(dates,newarr);
        MoveToRight();
        boolean bool = CompareArray(dates,newarr);
        copyArray(newarr,dates);
        return bool;
    }

    //判断是否则可以上移动
    public boolean CheckUp(){
        int[][] newarr  = new int[4][4];
        copyArray(dates,newarr);
        MoveToUp();
        boolean bool = CompareArray(dates,newarr);
        copyArray(newarr,dates);
        return bool;
    }

    //判断是否则可以下移动
    public boolean CheckDown(){
        int[][] newarr  = new int[4][4];
        copyArray(dates,newarr);
        MoveToDown();
        boolean bool = CompareArray(dates,newarr);
        copyArray(newarr,dates);
        return bool;
    }

    //复制源数组从原数组到新数组
    public void copyArray(int[][] src, int[][] newarr ) {
        for (int i = 0; i < src.length; i++) {
            for (int j = 0; j < src[0].length; j++) {
                newarr[i][j] = src[i][j];
            }
        }

    }

    //比较两数组所有元素是否相同
    public boolean CompareArray(int[][] dates, int[][] newarr) {
        boolean bool = false;
        loop1:
        for (int i = 0; i < dates.length; i++) {
            for (int j = 0; j < dates[0].length; j++) {
                if(newarr[i][j] != dates[i][j]){
                    bool = true;
                    break loop1;
                };
            }
        }
        return bool;
    }

    //实现每次移动之后添加一个2号数字块
    public void addnum(){
        int[] arrayi = new int[16];
        int[] arrayj = new int[16];
        int count = 0;
        //将两个数组所有元素初始化为-1
        for (int i = 0; i < arrayi.length; i++) {
            arrayi[i] = -1;
            arrayj[i] = -1;
        }

        for (int i = 0; i < dates.length; i++) {
            for (int j = 0; j < dates[i].length; j++) {
                if(dates[i][j] == 0){
                    arrayi[count] = i;
                    arrayj[count] = j;
                    count++;
                }
            }
        }

        if(count != 0){
            Random r = new Random();
            int index = r.nextInt(count);
            int x = arrayi[index];
            int y = arrayj[index];
            dates[x][y] = 2;
        }
    }

    @Override
    public void keyTyped(KeyEvent e) {

    }

    @Override
    public void keyReleased(KeyEvent e) {

    }


}

初始界面如图

昨天没有看电影,今晚好累也没力气看了。
明日目标:1、完善这个2048小游戏
2、观看电影《辛德勒的名单》
冲冲冲!

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值