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

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

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

截图:


 

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
}

猜你喜欢

转载自jimieaaa.iteye.com/blog/2196919