用Java实现2048小游戏

 看完视频后自己写了一下这段代码,记录一下Java的学习,可能有点简陋。

换肤功能是无效的,不想自己画图。。。

1、界面展示

2、相关代码

package LearningProject;

import javax.swing.*;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;

public class Main2048 extends JFrame implements KeyListener, ActionListener {
    int[][] s = new int[4][4];

//测试游戏结束是否成功的例子
//            {
//            {1,2,4,3},
//            {2,5,3,4},
//            {4,3,1,2},
//            {2,1,3,1}
//    };

    int score = 0;

    JMenuItem menuItem1 = new JMenuItem("经典");
    JMenuItem menuItem2 = new JMenuItem("霓虹");
    JMenuItem menuItem3 = new JMenuItem("糖果");

    public Main2048(){
//构造方法 创建该类对象即运行构造方法

        initFrame();
        initMeum();
        generate();
        generate();
        paintView();
//        setVisible(true);

    }


    public void initMeum() {                //设置菜单
        JMenuBar menuBar = new JMenuBar();
        JMenu menu1 = new JMenu("换肤");
        JMenu menu2 = new JMenu("关于我们");

        menu1.add(menuItem1);
        menu1.add(menuItem2);
        menu1.add(menuItem3);
        menu2.add("一切待开发......");
        menuBar.add(menu1);
        menuBar.add(menu2);
        //给 menuItem 注册监听
        menuItem1.addActionListener(this);
        menuItem2.addActionListener(this);
        menuItem3.addActionListener(this);

        setJMenuBar(menuBar);                   //将menuBar加到框架中

    }

    public void initFrame(){


        setTitle("2048小游戏");
        setSize(600,600);
        setLocationRelativeTo(null);      //设置居中
        setAlwaysOnTop(true);             //设置总位于页面上方
        setDefaultCloseOperation(3);      //设置关闭模式,关闭窗体时程序停止
        setLayout(null);                  //取消默认布局
        addKeyListener(this);


//        for(int i=0; i<4; i++)
//            for(int j=0; j<4; j++)
//            {
//                s[i][j] = (int) (Math.random() * 5);  //随机产生0-4的整数
//            }

    }

    public void paintView(){

        getContentPane().removeAll(); //重置界面
        if(isGameOver()==true) {
            JLabel Over = new JLabel(new ImageIcon("C:\\2048素材\\gameOver.png")); 
            Over.setBounds(0, 0, 600, 600);
            getContentPane().add(Over);
        }
        for(int i=0; i<4; i++)
            for(int j=0; j<4; j++) {
                ImageIcon img = new ImageIcon("C:\\2048素材\\" + (int) Math.pow(2, s[i][j]) + ".png");      //图片的命名与图片中的数字相同,并把其统一放在2048素材文件夹中
                JLabel label = new JLabel(img);
                label.setBounds(104 + j * 100, 105 + i * 100, 90, 90);
                getContentPane().add(label);
            }
        JLabel background = new JLabel(new ImageIcon("C:\\2048素材\\background.png"));
        background.setBounds(0,0,600,600);
        getContentPane().add(background);

        JLabel getScore = new JLabel("得分:"+score);
        getScore.setBounds(90,30,90,90);
        getContentPane().add(getScore);

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

        setVisible(true);                 //设置可见
    }


    @Override
    public void keyTyped(KeyEvent e) {

    }


    @Override
    public void keyPressed(KeyEvent e) {
        if (e.getKeyCode()==37) {

            moveLeft(1);     //参数为1时,运行此代码得分会累加
            generate();
        }
        else if (e.getKeyCode()==38) {

            counterClockWise();
            moveLeft(1);
            clockWise();
            generate();
        }
        else if(e.getKeyCode()==39){
//            System.out.println("向右滑动");
            reverse();
            moveLeft(1);
            reverse();
            generate();
        }
        else if(e.getKeyCode()==40){
//            System.out.println("向下滑动");
            clockWise();
            moveLeft(1);
            counterClockWise();
            generate();
        }
        else{
            return;
        }
        isGameOver();
        paintView();   //更新图片
    }


    @Override
    public void keyReleased(KeyEvent e) {

    }

    public void moveLeft(int flag) {
        int[][] data = new int[4][4];

        for (int i = 0; i < 4; i++) {
            int t = 0;
            for (int j = 0; j < 4; j++) {
                if(s[i][j] != 0) {
                    data[i][t] = s[i][j];
                    t++;
                }
            }
            s[i] = data[i];
            for(int j = 0; j < 3; j++){
                if (s[i][j]==s[i][j+1]&&s[i][j]!=0) {
                    s[i][j] += 1;
                    if(flag == 1){              //flag为1时,才进行得分累加;判断是否游戏结束时(flag为2)只是模拟移动,得分不变
                        score += (int)Math.pow(2,s[i][j]);

                    }
                    for (int k = j+1; k < 3; k++) {
                        s[i][k] = s[i][k+1];
                    }
                    s[i][3] = 0;       //移动后最后一个格子为空
                }

            }


        }

    }

//    左右颠倒
    public void reverse(){
        int[][] data = new int[4][4];
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++){
                data[i][j] = s[i][3-j];
            }
            s[i] = data[i];
        }

    }

//    顺时针旋转90°
    public void clockWise() {
        int[][] data = new int[4][4];
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                data[j][3-i] = s[i][j];
            }
        }
        s = data;
    }
    //逆时针旋转90°
    public void counterClockWise() {
        int[][] data = new int[4][4];
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                data[3-j][i] = s[i][j];

            }
        }
        s = data;
    }
    //拷贝数组,s拷贝到data
    public void copeArr(int[][] s,int[][] data){
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                data[i][j] = s[i][j];
            }
        }
    }

    boolean flag = true;
    //左移判断是否成功
    public boolean checkLeft() {
        flag = true;
        int[][] data = new int[4][4];
        copeArr(s,data);
        moveLeft(2);
        lo:
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if(s[i][j]!=data[i][j]) {
                    flag = false;
                    break lo;
                }
            }
        }
        s = data;
        return flag;
    }
    public boolean checkRight() {
        flag = true;
        int[][] data = new int[4][4];
        copeArr(s,data);
        reverse();
        moveLeft(2);
        reverse();
        lo:
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if(s[i][j]!=data[i][j]) {
                    flag = false;
                    break lo;
                }
            }
        }
        s = data;
        return flag;
    }
    public boolean checkForward() {
        flag = true;
        int[][] data = new int[4][4];
        copeArr(s,data);
        counterClockWise();
        moveLeft(2);
        clockWise();
        lo:
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if(s[i][j]!=data[i][j]) {
                    flag = false;
                    break lo;
                }
            }
        }
        s = data;
        return flag;
    }
    public boolean checkBack() {
        flag = true;
        int[][] data = new int[4][4];
        copeArr(s,data);
        clockWise();
        moveLeft(2);
        counterClockWise();
        lo:
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if(s[i][j]!=data[i][j]) {
                    flag = false;
                    break lo;
                }
            }
        }
        copeArr(data,s);
        return flag;
    }
//判断是否游戏结束
    public boolean isGameOver() {
        flag = false;
        if(checkLeft()==true && checkRight()==true && checkForward() ==true && checkBack() == true ) {
            System.out.println("游戏结束");
            flag = true;
        }
        return flag;
    }

//    在空的地方随机产生数值为2的新方块
    public void generate(){
        int k = 0;
        int[] line = new int[16];
        int[] column = new int[16];
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (s[i][j] == 0){
                    line[k] = i;
                    column[k] = j;
                    k++;
                }
            }

        }

        if(k!=0){
            int Num = (int)(Math.random()*k);   //随机产生[0,k)的整数,在空的位置产生方块
            s[line[Num]][column[Num]] = 1;      //产生的方块 其数字为2

        }
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        if(e.getSource() == menuItem1){               //getSource() 可以得知点击的内容
            System.out.println("换肤为经典");
        } else if (e.getSource() == menuItem2) {
            System.out.println("换肤为霓虹");
        } else if (e.getSource() == menuItem3) {
            System.out.println("换肤为糖果");
        }
    }
}

主函数 

package LearningProject;

import javax.swing.*;
import java.util.Random;

public class App {
    public static void main(String[] args) {

        Main2048 m = new Main2048();

    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值