欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

JAVA学习,写的一个2048小游戏

程序员文章站 2022-04-09 10:48:29
...

       很久之前写的一个2048小游戏,最开始没考虑动画,动画后来加上去的,导致代码有点乱。

       到2048分就赢,想多加点把数组扩大就行。

 

截图:

JAVA学习,写的一个2048小游戏
            
    
    博客分类: JAVA
 

 

4个类:

Start--------------入口

MainFrame-----主类

BlockData-------动画相关

Direct------------方向

 

 

代码:

类Start:

import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.UIManager;

public class Start {

    public static void main(String[] args) {
        // 使用Windows的界面风格
        try {
            UIManager.setLookAndFeel("com.sun.java.swing.plaf.windows.WindowsLookAndFeel");
        } catch (Exception e) {
            e.printStackTrace();
        }
        MainFrame mf = new MainFrame();
        mf.setVisible(true);
        try {
            mf.getGraphics().drawImage(ImageIO.read(Start.class.getResource("logo.png")), 10, 35, 295, 370, null);
        } catch (IOException e) {e.printStackTrace();}
    }

}

 

 

类MainFrame:

import java.awt.BorderLayout;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.Toolkit;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Random;

import javax.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JTextField;

/**
 * 游戏主界面
 * @author kyda
 */
public class MainFrame extends JFrame implements ActionListener {
   
    private static final long serialVersionUID = 1L;
    // 方块大小
    private static final int PER_PIECE_SIZE = 70;
    // 方块间距
    private static final int BORDER_SIZE = 10;
    // 方块显示起始坐标
    private static final int GAMEAREA_X = 10, GAMEAREA_Y = 90;
    // 最大阶数,根据屏幕大小设定
    private static final int MAX_PIECES_DEGREE = (Toolkit.getDefaultToolkit().getScreenSize().height - 250) / PER_PIECE_SIZE;
    // 方块移动次数
    private static final int MOVE_TIMES = 20;
    // 分数移动次数
    private static final int SCORE_MOVE_TIMES = 20;
    // 方块闪烁次数
    private static final int FLASH_TIMES = 10;
    // 所有方块数值和背景颜色
    private static final int BLOCKS[][] = {{0, 0xffccc0b4}, {2, 0xffeee4da}, {4, 0xffede0c8},
                                           {8, 0xfff2b179}, {16, 0xfff59563}, {32, 0xfff67c5f}, 
                                           {64, 0xfff65e3b}, {128, 0xffedcf72}, {256, 0xffedcc61}, 
                                           {512, 0xffedc850}, {1024, 0xffedc53f}, {2048, 0xffedc22e}};
    // 字体名
    private static final String FONTNAME = "Arial";
    // 圆角半径
    private static final int RADIUS = 4;
    
    private GamePanel gamePanel;
    private JPanel configPanel;
    private JTextField sizeTF;
    private JButton startBtn;
    private JLabel stepLabel;
    
    private int block[][]; // 方块
    private int bk[][]; // 方块
    private int rows; // 阶数
    private boolean isMoved; // 是否有方块移动过
    private int steps; // 游戏步数
    private int scores; // 游戏分数
    private int isWin; // 输赢状态,-1-输,0-可继续移动,1-赢
    private Thread t1, t2, t3; // 三种线程,移动,闪烁,分数
    private boolean t1Alive, t2Alive, t3Alive; // 三种线程是否活着
    private boolean merge[]; // 储存是否合并至数组下标位置的方块,闪烁用
    private int currentScore, currentScoreY; // 分数和Y坐标
    private int currentSize; // 方块大小,闪烁用
    private Random rand = new Random(System.currentTimeMillis());
    private List<BlockData> list; // 方块移动信息

    public MainFrame() {
        setTitle("2048 by kyda");
        setSize(315, 450);
        //setLayout(null);
        setResizable(false);
        setLocationRelativeTo(null);
        setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        addMouseListener(new GestureListener());
        
        gamePanel = new GamePanel();
        gamePanel.addKeyListener(new GameKeyListener());
        add(gamePanel, BorderLayout.CENTER);
        
        configPanel = new JPanel();
        add(configPanel, BorderLayout.SOUTH);
        
        sizeTF = new JTextField("4");
        sizeTF.setColumns(6);
        sizeTF.addKeyListener(new SizeTFListener());
        configPanel.add(sizeTF);
        
        startBtn = new JButton("开始");
        startBtn.addActionListener(this);
        configPanel.add(startBtn);
        
        stepLabel = new JLabel();
        configPanel.add(stepLabel);
    }
    
    // 初始化方块数值
    public void init() {
        block = new int[rows][];
        for (int row = 0; row < rows; row++) {
            block[row] = new int[rows];
        }
        createBlock(2);
    }
    
    // 随机在空白区域创建方块,如果有空格
    public void createBlock() {
        int r = 0;
        boolean hasBlank = false;
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < rows; col++) {
                if (block[row][col] == 0) {
                    hasBlank = true;
                    row = rows;
                    break;
                }
            }
        }
        if (!hasBlank) return;
        do {
            r = Math.abs(rand.nextInt() % (rows * rows));
        } while (block[r / rows][r % rows] != 0);
        block[r / rows][r % rows] = Math.abs(rand.nextInt() % 2) + 1;
    }
    
    // 创建指定数目的方块
    public void createBlock(int count) {
        while (count-- > 0) {
            createBlock();
        }
    }
    
    // 点击开始按钮
    public void start() {
        rows = 0;
        try {
            rows = Integer.valueOf(sizeTF.getText().trim());
            if (rows < 2) {
                JOptionPane.showMessageDialog(null, "大点行么?", "干", JOptionPane.INFORMATION_MESSAGE);
                sizeTF.setText("");
                sizeTF.requestFocus();
                return;
            } else if (rows > MAX_PIECES_DEGREE) {
                JOptionPane.showMessageDialog(null, "小点行么,你屏幕放的下?", "干", JOptionPane.INFORMATION_MESSAGE);
                sizeTF.setText("");
                sizeTF.requestFocus();
                return;
            }
        } catch (Exception e1) {
            JOptionPane.showMessageDialog(null, "不要乱输入,OK?", "无语", JOptionPane.ERROR_MESSAGE);
            sizeTF.setText("");
            sizeTF.requestFocus();
            return;
        }
        init();
        int width = PER_PIECE_SIZE * rows + transform(GAMEAREA_X) + 10;
        int height = PER_PIECE_SIZE * rows + transform(GAMEAREA_Y) + 10;
        gamePanel.setSize(width, height);
        steps = 0;
        scores = 0;
        isWin = 0;
        t1Alive = false;
        t2Alive = false;
        t3Alive = false;
        stepLabel.setText("");
        setSize(width + transform(GAMEAREA_X + 5), height + 70);
        repaint();
        setLocationRelativeTo(null);
        gamePanel.repaint();
        gamePanel.requestFocus();
        merge = new boolean[rows * rows];
    }

    @Override
    public void actionPerformed(ActionEvent e) {
        start();
    }

    // 按照方向移动方块,先将数组行列转成按上方向移动
    public void moveBlocks(Direct direct) {
        switch (direct) {
            case UP:
                isMoved = moveByUpDirect(Direct.UP);
                break;
            case DOWN:
                reverse();
                isMoved = moveByUpDirect(Direct.DOWN);
                reverse();
                break;
            case LEFT:
                transpose();
                isMoved = moveByUpDirect(Direct.LEFT);
                transpose();
                break;
            case RIGHT:
                transpose();
                reverse();
                isMoved = moveByUpDirect(Direct.RIGHT);
                reverse();
                transpose();
                break;
            default:
                break;
        }
        if (isMoved) {
            createBlock();
            steps++;
            stepLabel.setText("步数:" + steps);
        }
    }
    
    // 将转换后的数组按照上方向移动(由于动画信息是后来加的,比较混乱)
    public boolean moveByUpDirect(Direct direct) {
        int index;
        int r, c;
        for (int col = 0; col < rows; col++) {
            index = 0;
            boolean hasNext = false, isFirst = true;
            if (block[0][col] != 0) {
                for (int row = 1; row < rows; row++) {
                    if (block[row][col] != 0) {
                        hasNext = true;
                        break;
                    }
                }
                if (!hasNext) {
                    list.add(calculate(0, col, 0, col, block[0][col], direct));
                }
            }
            for (int row = 1; row < rows; row++) {
                if (block[row][col] == 0) continue;
                
                if (block[index][col] == block[row][col]) {
                    if (isFirst) {
                        list.add(calculate(index, col, index, col, block[index][col], direct));
                        isFirst = false;
                    }
                    scores += BLOCKS[block[row][col] + 1][0];
                    currentScore += BLOCKS[block[row][col] + 1][0];
                    list.add(calculate(row, col, index, col, block[index][col], direct));
                    block[index][col]++;
                    block[row][col] = 0;
                    if (!isMoved) isMoved = true;
                    r = index;
                    c = col;
                    switch (direct) {
                        case DOWN:
                            r = rows - index - 1;
                        case UP:
                            break;
                        case RIGHT:
                            r = rows - index - 1;
                        case LEFT:
                            int tmp = r;
                            r = c;
                            c = tmp;
                            break;
                    }
                    merge[r * rows + c] = true;
                    index++;
                } else {
                    if (block[index][col] != 0) {
                        if (isFirst)
                            list.add(calculate(index, col, index, col, block[index][col], direct));
                        index++;
                    }
                    block[index][col] = block[row][col];
                    list.add(calculate(row, col, index, col, block[index][col], direct));
                    isFirst = false;
                    if (index != row) {
                        block[row][col] = 0;
                        if (!isMoved) isMoved = true;
                    }
                }
            }
            for (int row = 0; row < rows; row++) {
                if (block[row][col] == 0) {
                    list.add(calculate(row, col, row, col, 0, direct));
                }
            }
        }
        return isMoved;
    }
    
    // 将移动信息从上方向转回原方向
    public BlockData calculate(int startRow, int startCol, int endRow, int endCol, int data, Direct direct) {
        BlockData bd = new BlockData(startRow, startCol, data, direct, 0);
        int tmp;
        switch (direct) {
            case DOWN:
                bd.row = rows - bd.row - 1;
            case UP:
                bd.distance = Math.abs(endRow - startRow);
                //System.out.println("add:" + bd.row + " " + bd.col + " " + bd.speed + " " + endRow + " " + endCol);
                break;
            case RIGHT:
                tmp= bd.row;
                bd.row = bd.col;
                bd.col = rows - tmp - 1;
                bd.distance = Math.abs(endRow - startRow);
                break;
            case LEFT:
                tmp = bd.row;
                bd.row = bd.col;
                bd.col = tmp;
                bd.distance = Math.abs(endRow - startRow);
                break;
            default:
                break;
        }
        return bd;
    }
    
    // 将方块每列逆转
    public void reverse() {
        int tmp;
        for (int col = 0; col < rows; col++) {
            for (int row = 0; row < rows / 2; row++) {
                tmp = block[rows - row - 1][col];
                block[rows - row - 1][col] = block[row][col];
                block[row][col] = tmp;
            }
        }
    }
    
    // 对所有方块行列置换
    public void transpose() {
        int tmp;
        for (int col = 0; col < rows; col++) {
            for (int row = col; row < rows; row++) {
                tmp = block[col][row];
                block[col][row] = block[row][col];
                block[row][col] = tmp;
            }
        }
    }
    
    // 复制二维数组
    public int[][] copy(int[][] src) {
        int len = src.length;
        int[][] ret = new int[len][];
        for (int i = 0; i < len; i++) {
            ret[i] = new int[src[0].length];
            System.arraycopy(src, 0, ret, 0, src[0].length);
        }
        return ret;
    }
    
    // 判断游戏输赢
    public int win() {
        boolean canMove = false;
        if (isWin == 1) return 1;
        for (int row = 0; row < rows; row++) {
            for (int col = 0; col < rows; col++) {
                if (block[row][col] == BLOCKS.length - 1) { // 达到2048游戏结束
                    isWin = 1;
                    return 1;
                }
                if (!canMove && block[row][col] == 0) {
                    canMove = true;
                }
            }
        }
        
        if (!canMove) { // 没有空格(分开判断节约时间)
            for (int row = 0; row < rows; row++) {
                for (int col = 0; col < rows; col++) {
                    // System.out.println(row +" " + col);
                    canMove = canMove(row, col);
                    if (canMove) {
                        row = rows;
                        break;
                    }
                }
            }
        }
        if (canMove) {
            isWin = 0;
            return 0;
        }
        isWin = -1;
        return -1;
    }
    
    // 在没有空格的情况下,判断当前方块是否可以移动
    public boolean canMove(int row, int col) {
        if (row > 0 && block[row - 1][col] == block[row][col])
            return true;
        if (row < rows - 1 && block[row + 1][col] == block[row][col])
            return true;
        if (col > 0 && block[row][col - 1] == block[row][col])
            return true;
        if (col < rows - 1 && block[row][col + 1] == block[row][col])
            return true;
        return false;
    }
    
    /** 计算缩放后的坐标,适应当前界面大小 */
    public int transform(int src) {
        if (rows == 4) return src;
        return src * rows / 4;
    }
    
    // 按方向移动
    public void gameMove(Direct direct) {
        if (isWin != 0 || block == null) return;
        bk = copy(block);
        list = new LinkedList<>();
        Arrays.fill(merge, false);
        isMoved = false;
        currentScore = 0;
        currentScoreY = transform(60);
        moveBlocks(direct);
        win();
        //gamePanel.repaint();
        if (isMoved) {
        	/*if (t1 != null) {
        		t1Alive = false;
        		stopThread(t1);
                //t1.join();
        	}*/
            if (t1 != null && t1.isAlive()) t1.stop(); // 让线程自动停止动画效果不理想,只能想到这么干了。。
            t1 = new MoveThread();
            t1.start();
        }
        if (isMoved) {
            if (t2 != null && t2.isAlive()) t2.stop();
            t2 = new FlashThread();
            t2.start();
        }
        if (currentScore != 0) {
            if (t3 != null && t3.isAlive()) t3.stop();
            t3 = new ScoreMoveThread();
            t3.start();
        }
        //System.out.println(Arrays.deepToString(block));
        //if (t1Alive)
        //    gamePanel.repaint();
    }
    
    // 效果不好
    public void stopThread(Thread t) {
    	while (t.isAlive()) {};
    }
    
    // 监听输入框,Enter键
    class SizeTFListener extends KeyAdapter {
        @Override
        public void keyPressed(KeyEvent e) {
            if (e.getKeyCode() == KeyEvent.VK_ENTER) {
                start();
            }
        }
    }
    
    // 监听手势
    class GestureListener extends MouseAdapter {
    	private int startX, startY;
    	
    	@Override
		public void mousePressed(MouseEvent e) {
    		startX = e.getX();
			startY = e.getY();
			if (!gamePanel.isFocusOwner()) // 获得焦点,不知道为啥不能自动获取
		        gamePanel.requestFocus();
		}
    	
        @Override
        public void mouseReleased(MouseEvent e) {
    		if (startX < 10 || startX > getSize().width - 10 || startY < transform(GAMEAREA_X + 70) || startY > getSize().height - 60) return;
        	int endX = e.getX();
        	int endY = e.getY();
    		int dx = (int) Math.abs(startX - endX);
    		int dy = (int) Math.abs(startY - endY);
    		if (dx - dy < 0 && dy > 20) {
    			if (startY > endY) {
    				gameMove(Direct.UP);
    			} else {
    				gameMove(Direct.DOWN);
    			}
    	    } else if (dx - dy > 0 && dx > 20) {
    	    	if (startX > endX) {
    				gameMove(Direct.LEFT);
    			} else {
    				gameMove(Direct.RIGHT);
    			}
    	    }
        }
    }
    
    class GamePanel extends JPanel {
        private static final long serialVersionUID = 1L;

        @Override
        public void paint(Graphics g) {
            super.paint(g);
            if (block == null) return;
            // 背景
            g.setColor(new Color(0xffbfafa2));
            g.fillRoundRect(transform(GAMEAREA_X), transform(GAMEAREA_Y), PER_PIECE_SIZE * rows + GAMEAREA_X + BORDER_SIZE - 10, PER_PIECE_SIZE * rows + BORDER_SIZE, RADIUS, RADIUS);
            
            // 标题
            //g.setColor(new Color(0xffecc400));
            //g.fillRect(transform(20), transform(10), transform(80), transform(70));
            g.setColor(new Color(0xff776e65));
            g.setFont(new Font(FONTNAME, Font.PLAIN, transform(40)));
            g.drawString("2048", transform(25), transform(60));
            
            g.setColor(new Color(0xffbfafa2));
            g.fillRoundRect(transform(130), transform(10), transform(70), transform(70), RADIUS, RADIUS);
            g.setColor(Color.WHITE);
            g.setFont(new Font(FONTNAME, Font.BOLD, transform(12)));
            g.drawString("SCORE", transform(130 + 15), transform(35));
            int len = String.valueOf(scores).length();
            g.setFont(new Font(FONTNAME, Font.BOLD, transform(16)));
            g.drawString("" + scores, transform(130 + ((70 - len * 8) >> 1)), transform(60));
            
            g.setColor(new Color(0xffbfafa2));
            g.fillRoundRect(transform(220), transform(10), transform(70), transform(70), RADIUS, RADIUS);
            g.setColor(Color.WHITE);
            g.setFont(new Font(FONTNAME, Font.BOLD, transform(12)));
            g.drawString("STEPS", transform(238), transform(35));
            
            len = String.valueOf(steps).length();
            g.setFont(new Font(FONTNAME, Font.BOLD, transform(16)));
            g.drawString("" + steps, transform(220 + ((70 - len * 8) >> 1)), transform(60));

            if (t3Alive && currentScore != 0) {
                g.setColor(new Color(0xff776e65));
                len = String.valueOf(currentScore).length();
                g.drawString("+" + currentScore, transform(130 + ((70 - len * 8) >> 1) - 8), currentScoreY);
                //return;
            }

            int x = 0, y = 0, size = 0, data;
            g.setColor(new Color(BLOCKS[0][1]));
            for (int i = 0; i < rows; i++) {
                for (int j = 0; j < rows; j++) {
                    x = j * PER_PIECE_SIZE + transform(GAMEAREA_X) + BORDER_SIZE;
                    y = i * PER_PIECE_SIZE + transform(GAMEAREA_Y) + BORDER_SIZE;
                    g.fillRoundRect(x, y, PER_PIECE_SIZE - BORDER_SIZE, PER_PIECE_SIZE - BORDER_SIZE, RADIUS, RADIUS);
                }
            }
            g.setFont(new Font(FONTNAME, Font.BOLD, 24));
            if (t1Alive) {
                for (BlockData bd : list) {
                    if (bd.data == 0) continue;
                    x = transform(GAMEAREA_X) + BORDER_SIZE + bd.x;
                    y = transform(GAMEAREA_Y) + BORDER_SIZE + bd.y;
                    size = PER_PIECE_SIZE - BORDER_SIZE;
                    data = bd.data;
                    g.setColor(new Color(BLOCKS[data][1]));
                    g.fillRoundRect(x, y, size, size, RADIUS, RADIUS);
                    if (data <= 2)
                        g.setColor(new Color(0xff776e65));
                    else
                        g.setColor(Color.WHITE);
                    if (BLOCKS[data][0] != 0) {
                        len = String.valueOf(BLOCKS[data][0]).length();
                        g.drawString("" + BLOCKS[data][0], x + ((size - len * 12) >> 1) - 1, y + (PER_PIECE_SIZE >> 1) + 4);
                    }
                }
            } else {
                for (int i = rows - 1; i >= 0; i--) {
                    for (int j = rows - 1; j >= 0; j--) {
                        //if (block[i][j] == 0) continue;
                        x = j * PER_PIECE_SIZE + transform(GAMEAREA_X) + BORDER_SIZE;
                        y = i * PER_PIECE_SIZE + transform(GAMEAREA_Y) + BORDER_SIZE;
                        size = PER_PIECE_SIZE - BORDER_SIZE;
                        data = block[i][j];
                        if (t2Alive) {
                            if (merge[i * rows + j]) {
                                x -= currentSize;
                                y -= currentSize;
                                size += currentSize << 1;
                            }
                        }
                        g.setColor(new Color(BLOCKS[data][1]));
                        if (BLOCKS[data][0] != 0)
                            g.fillRoundRect(x, y, size, size, RADIUS, RADIUS);
                        if (data <= 2)
                            g.setColor(new Color(0xff776e65));
                        else
                            g.setColor(Color.WHITE);
                        if (BLOCKS[data][0] != 0) {
                            len = String.valueOf(BLOCKS[data][0]).length();
                            g.drawString("" + BLOCKS[data][0], x + ((size - len * 12) >> 1) - 1, y + (PER_PIECE_SIZE >> 1) + 4);
                        }
                    }
                }
            }
            g.setColor(Color.GREEN);
            if (rows < 4) 
            	g.setFont(new Font(FONTNAME, Font.BOLD, 14));
            if (isWin == 1) {
                g.drawString("You Win! score:" + scores + "  steps:" + steps, 20, transform(200));
            } else if (isWin == -1) {
                g.drawString("Uh-oh~  You Go Die!!", 20, transform(200));
            }
        }
    }
    
    // 游戏按键
    class GameKeyListener extends KeyAdapter {

        @Override
        public void keyPressed(KeyEvent e) {
        	
            switch (e.getKeyCode()) {
                case KeyEvent.VK_UP:
                	gameMove(Direct.UP);
                    break;
                case KeyEvent.VK_LEFT:
                	gameMove(Direct.LEFT);
                    break;
                case KeyEvent.VK_DOWN:
                	gameMove(Direct.DOWN);
                    break;
                case KeyEvent.VK_RIGHT:
                	gameMove(Direct.RIGHT);
                    break;
                default:
                    return;
            }
        }
    }
    
    // 移动线程
    class MoveThread extends Thread {
        @Override
        public void run() {
            t1Alive = true;
            /*for (BlockData bd : list) {
                if (bd.data != 0)
                    System.out.println(bd);
            }
            System.out.println();*/
            while (t1Alive) {
                for(int time = 1; time <= MOVE_TIMES; time++) {
                    //System.out.println(time);
                    for (BlockData bd : list) {
                        //System.out.println(bd.row + " " + bd.col + " " + bd.distance);
                        bd.x = bd.col * PER_PIECE_SIZE;
                        bd.y = bd.row * PER_PIECE_SIZE;
                        if (bd.distance == 0) continue;
                        switch (bd.direct) {
                            case UP: 
                                bd.y -= (bd.distance * PER_PIECE_SIZE * time) / MOVE_TIMES;
                                break;
                            case DOWN:
                                bd.y += (bd.distance * PER_PIECE_SIZE * time) / MOVE_TIMES;
                                break;
                            case LEFT:
                                bd.x -= (bd.distance * PER_PIECE_SIZE * time) / MOVE_TIMES;
                                break;
                            case RIGHT:
                                bd.x += (bd.distance * PER_PIECE_SIZE * time) / MOVE_TIMES;
                                break;
                        }
                    }
                    gamePanel.repaint();
                    try {
                        Thread.sleep(10);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                t1Alive = false;
                //gamePanel.repaint();
            }
        }
    }
    
    // 闪烁线程
    class FlashThread extends Thread {
        @Override
        public void run() {
            try {
                Thread.sleep(10 * MOVE_TIMES);
            } catch (Exception e1) {
                e1.printStackTrace();
            }
            t2Alive = true;
            while (t2Alive) {
                for (int time = 1; time <= FLASH_TIMES; time++) {
                    currentSize = PER_PIECE_SIZE - BORDER_SIZE;
                    if (time < (FLASH_TIMES >>> 2)) {
                        currentSize = currentSize * time / (FLASH_TIMES << 3);
                    } else {
                        currentSize = currentSize * (FLASH_TIMES - time) / (FLASH_TIMES << 3);
                    }
                    gamePanel.repaint();
                    try {
                        Thread.sleep(20);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                t2Alive = false;
                //gamePanel.repaint();
            }
        }
    }
    
    // 分数移动线程
    class ScoreMoveThread extends Thread {
        @Override
        public void run() {
            t3Alive = true;
            while (t3Alive) {
                for (int time = 0; time <= SCORE_MOVE_TIMES; time++) {
                    if (rows < 4)
                        currentScoreY = transform(((currentScoreY << 2) / rows) - (20 / SCORE_MOVE_TIMES));
                    else
                        currentScoreY -= transform(20 / SCORE_MOVE_TIMES);
                    //gamePanel.repaint();
                    gamePanel.repaint(transform(130), transform(10), transform(70), transform(70));
                    try {
                        Thread.sleep(20);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                t3Alive = false;
                //gamePanel.repaint();
                gamePanel.repaint(transform(130), transform(10), transform(70), transform(70));
            }
        }
    }
}

 

 

类BlockData:

/**
 * 储存每一步方块操作的信息,用于动画
 * @author kyda
 */
public class BlockData {

    public int row; // 移动前行数
    public int col; // 移动前列数
    public int x; // 坐标x,显示时计算
    public int y; // 坐标y
    public int data; // 方块值
    public Direct direct; // 方向
    public int distance; // 移动距离

    public BlockData() {
        
    }
    
    public BlockData(int row, int col, int data, Direct direct, int distance) {
        this.row = row;
        this.col = col;
        this.data = data;
        this.direct = direct;
        this.distance = distance;
    }
    
    @Override
    public String toString() {
        return "["+row+","+col+","+data+","+direct+","+distance+"]";
    }
}

 

 

类Direct:

public enum Direct {
    UP, LEFT, DOWN, RIGHT
}

 

  • JAVA学习,写的一个2048小游戏
            
    
    博客分类: JAVA
  • 大小: 17.4 KB