JAVA语言课程设计——俄罗斯方块

1.设计内容

设计一个常规的俄罗斯方块游戏,方块形状有7个形状,如果在一条水平线上所有位置都填满,就可消去一行,得10分,如果某一列高度超过上限,游戏结束。

效果如图:俄罗斯方块界面

2.设计要求

界面美观,键盘的上下左右键好用。上箭头:出现的方块顺时针旋转。下箭头:加速下落。左键头,向左平移。右箭头:向右平移。颜色鲜艳,用随机数产生。

3.设计思想

定义砖块类Brick,定义数字代表砖块形状

:0,:1,:2,:3,:4,:5,:6;定义旋转角度:旋转90度:0,旋转180度:1,旋转270度:2,旋转360:3;定义砖块的宽度和高度; 初始化所有可能出现的砖块的模型:定义一个四维数组,第一维代表7种不同的图案,第二维代表每个团旋转的4个角度,第三维和第四维定义行列,代表每个图形的样子。如

:四个角度都一样

:四个角度分别是

:四个角度分别是

定义一个Color数组,是砖块可能出现的所有颜色;定义变量记录当前砖块的形状、颜色、和颜色数组的索引、旋转角度、当前砖块所在的坐标值。用构造函数初始化砖块的有关属性(形状、角度、颜色、坐标)

  1. 搭建界面,响应键盘时间,上下左右四个方向键头,分别调用旋转,下落,向左移动,向右移动方法。主函数显示界面,界面上显示的是M类对象,启动游戏。
  2. 定义一个Panel的子类M,实现多线程接口。

A.构造函数M(){1. 整个界面包含边界,边界内算作一个二维数组,清空二维数组中的砖块信息;2. 产生当前砖块和下一个提示的砖块;3.计算提示的砖块的位置}

B.显示界面方法 Paint(){1.画得分; 2.画边界; 3. 画当前下落的砖块; 4.画下一个砖块}

C.线程方法Run(){砖块继续下落,只要当前砖块到达界面底部,判定是否需要消掉一行,是否得分。初始化相关变量信息。将原来下一个砖块的信息赋值给当前砖块,产生一个新砖块,新生成的砖块信息赋值给下一个提示砖块}

D.下落函数drop(){将当前砖块位置全部清空,纵坐标+1,重新画当前下落砖块形状,如果y不能再次+1,y==0,说明砖块落不下去了,游戏结束,如果y不能再次+1,但y!=0,说明到达底部。}

E.旋转砖块函数(){当前砖块角度顺时针旋转90度。即角度的索引下标+1;}

F.向左移动函数(){当前砖块x值-1;}

G.向右移动函数(){当前砖块x值+1;}

H.消行函数(){如果某一行全部有颜色,说明这一行满了,将上面的砖块全体下移,并将最上面一行全部置空}

其中我分割成三个文件,代码如下:

砖块类 Brick.java

package sqare;

import java.awt.*;

/**
 * 该类为砖块类 定义了游戏中可能出现的所有砖块的形状索引、角度索引、颜色索引、
 * 以及其模型各种情况下的模型,规定了游戏中可能出现的所有颜色,定义了获取当前
 * 砖块的形状的方法getCurrentShape(),获取角度的方法getCurrentAngle(),获取颜色
 * 的方法getCurrentColor(),重置砖块各属性的方法resetBrick()和根据给定的坐标值绘
 * 制当前砖块的方法drawCurrentBrick(Graphics g,int begin_x,int begin_y)
 */

public class Brick {
    //定义砖块形状索引
    public static final int ZERO_SHAPE = 0;
    public static final int I_SHAPE = 1;
    public static final int T_SHAPE = 2;
    public static final int Z_SHAPE = 3;
    public static final int S_SHAPE = 4;
    public static final int L_SHAPE = 5;
    public static final int REVERSE_L_SHAPE = 6;
    //定义砖块所处的角度(顺时针旋转)
    public static final int ANGLE_90 = 0;
    public static final int ANGLE_180 = 1;
    public static final int ANGLE_270 = 2;
    public static final int ANGLE_360 = 3;
    //定义每一个砖块的宽和高
    public static final int BRICK_WIDTH = 10;//占10个像素
    public static final int BRICK_HEIGHT = 10;
    //初始化所有可能出现的砖块的模型
    public static final int[][][][] BRICK_MODEL = {
            //ZERO_SHAPE型砖块处于不同角度时的形状模型
            {
                    {
                            {1, 1, 0, 0},
                            {1, 1, 0, 0},  //ANGLE_90时的模型
                            {0, 0, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {1, 1, 0, 0},
                            {1, 1, 0, 0},
                            {0, 0, 0, 0},  //ANGLE_180时的模型
                            {0, 0, 0, 0}
                    },
                    {
                            {1, 1, 0, 0},
                            {1, 1, 0, 0},
                            {0, 0, 0, 0},  //ANGLE_270时的模型
                            {0, 0, 0, 0}
                    },
                    {
                            {1, 1, 0, 0},
                            {1, 1, 0, 0},
                            {0, 0, 0, 0},  //ANGLE_360时的模型
                            {0, 0, 0, 0}
                    }
            },
            //I_SHAPE型的砖块处于不同角度时的形状模型
            {
                    {
                            {1, 0, 0, 0},
                            {1, 0, 0, 0},  //ANGLE_90时的模型
                            {1, 0, 0, 0},
                            {1, 0, 0, 0}
                    },
                    {
                            {1, 1, 1, 1},
                            {0, 0, 0, 0},  //ANGLE_180时的模型
                            {0, 0, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {1, 0, 0, 0},
                            {1, 0, 0, 0},  //ANGLE_270时的模型
                            {1, 0, 0, 0},
                            {1, 0, 0, 0}
                    },
                    {
                            {1, 1, 1, 1},
                            {0, 0, 0, 0},  //ANGLE_360时的模型
                            {0, 0, 0, 0},
                            {0, 0, 0, 0}
                    }
            },
            //T_SHAPE型的砖块处于不同角度时的形状模型
            {
                    {
                            {1, 1, 1, 0},
                            {0, 1, 0, 0},  //ANGLE_90时的模型
                            {0, 0, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {0, 1, 0, 0},
                            {1, 1, 0, 0},  //ANGLE_180时的模型
                            {0, 1, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {0, 1, 0, 0},
                            {1, 1, 1, 0},  //ANGLE_270时的模型
                            {0, 0, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {1, 0, 0, 0},
                            {1, 1, 0, 0},  //ANGLE_360时的模型
                            {1, 0, 0, 0},
                            {0, 0, 0, 0}
                    }
            },
            //Z_SHAPE型的砖块处于不同角度时的形状模型
            {
                    {
                            {1, 1, 0, 0},
                            {0, 1, 1, 0},  //ANGLE_90时的模型
                            {0, 0, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {0, 1, 0, 0},
                            {1, 1, 0, 0},  //ANGLE_180时的模型
                            {1, 0, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {1, 1, 0, 0},
                            {0, 1, 1, 0}, //ANGLE_270时的模型
                            {0, 0, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {0, 1, 0, 0},
                            {1, 1, 0, 0},  //ANGLE_360时的模型
                            {1, 0, 0, 0},
                            {0, 0, 0, 0}
                    }
            },
            //S_SHAPE型的砖块处于不同角度时的形状模型
            {
                    {
                            {0, 1, 1, 0},
                            {1, 1, 0, 0},  //ANGLE_90时的模型
                            {0, 0, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {1, 0, 0, 0},
                            {1, 1, 0, 0}, //ANGLE_180时的模型
                            {0, 1, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {0, 1, 1, 0},
                            {1, 1, 0, 0},  //ANGLE_270时的模型
                            {0, 0, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {1, 0, 0, 0},
                            {1, 1, 0, 0}, //ANGLE_360时的模型
                            {0, 1, 0, 0},
                            {0, 0, 0, 0}
                    }
            },
            //L_SHAPE型的砖块处于不同角度时的形状模型
            {
                    {
                            {1, 0, 0, 0},
                            {1, 0, 0, 0},  //ANGLE_90时的模型
                            {1, 1, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {1, 1, 1, 0},
                            {1, 0, 0, 0},  //ANGLE_180时的模型
                            {0, 0, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {1, 1, 0, 0},
                            {0, 1, 0, 0},  //ANGLE_270时的模型
                            {0, 1, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {0, 0, 1, 0},
                            {1, 1, 1, 0},  //ANGLE_360时的模型
                            {0, 0, 0, 0},
                            {0, 0, 0, 0}
                    }
            },
            //REVERSE_L_SHAPE型的砖块处于不同角度时的形状模型
            {
                    {
                            {0, 1, 0, 0},
                            {0, 1, 0, 0},  //ANGLE_90时的模型
                            {1, 1, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {1, 0, 0, 0},
                            {1, 1, 1, 0},  //ANGLE_180时的模型
                            {0, 0, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {1, 1, 0, 0},
                            {1, 0, 0, 0},  //ANGLE_180时的模型
                            {1, 0, 0, 0},
                            {0, 0, 0, 0}
                    },
                    {
                            {1, 1, 1, 0},
                            {0, 0, 1, 0},  //ANGLE_360时的模型
                            {0, 0, 0, 0},
                            {0, 0, 0, 0}
                    }
            }


    };
    //初始化可能出现的砖块的所有颜色
    public static final Color[] ALL_COLOR = {
            new Color(21, 170, 122), new Color(138, 87, 53), new Color(187, 18, 4), new Color(103, 57, 134),
            new Color(17, 174, 45), new Color(158, 33, 139)
    };
    //当前砖块的形状
    public int current_shape;
    //当前砖块的颜色
    public Color current_color;
    //当前砖块颜色对应颜色数组中的索引
    public int current_color_index;
    //当前砖块的角度
    public int current_angle;
    //当前砖块所在的坐标值
    public int x, y;

    //构造函数 初始化砖块的有关属性
    public Brick(int shape, int angle, int color_index) {
        current_shape = shape % 7;
        current_angle = angle % 4;
        current_color_index = color_index % 6;
        x = -1;
        y = -1;
    }

    //返回当前砖块的形状
    public int getCurrentBrickShape() {
        return current_shape;
    }

    //返回当前砖块的角度
    public int getCurrentBrickAngle() {
        return current_angle;
    }

    //返回当前砖块的颜色的索引值
    public int getCurrentBrickColor() {
        return current_color_index;
    }

    //返回当前砖块的模型
    public int[][] getCurrentBrickModle(int shape, int angle) {
        return BRICK_MODEL[shape][angle];
    }

    //重新设置一个砖块
    public void resetBrick(int shape, int angle, int color_index) {
        current_shape = shape % 7;
        current_angle = angle % 4;
        current_color_index = color_index % 6;
    }

    //根据给定的角度旋转砖块
    public void turnAngle(int angle) {
        current_angle += angle;
        current_angle = (current_angle >= 4 ? current_angle % 4 : current_angle);
    }
}

砖块形状类 BrickUI.java

package sqare;

import javax.swing.*;
import java.awt.*;
import java.awt.event.*;

public class BrickUI extends KeyAdapter {

    private JFrame frame;
    private JButton startButton;
    private Map m;

    public void init() {
        m = new Map();          //线程实现类
        frame = new JFrame("俄罗斯方块");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.addKeyListener(this);   //界面相应键盘事件
        frame.setSize(500, 500);
        frame.setLocation(200, 200);   //界面大小位置
        frame.add(m);                  //添加游戏界面Panel
        frame.setVisible(true);
        m.startGame();                //线程开始
    }

    public void keyPressed(KeyEvent e) {        //键盘事件
        int keyNum = e.getKeyCode();       //获取键盘代码
        switch (keyNum) {
            case KeyEvent.VK_LEFT:         //左箭头,向左平移
                m.moveLeftOrRight(-1);
                break;
            case KeyEvent.VK_RIGHT:         //右箭头,向右平移
                m.moveLeftOrRight(1);
                break;
            case KeyEvent.VK_UP:            //上箭头,旋转
                m.turnAngle();
                break;
            case KeyEvent.VK_DOWN:          //下箭头,下落
                m.drop();
                break;
        }
    }

    public static void main(String[] args) {
        BrickUI bu = new BrickUI();//创建对象
        bu.init();    //初始化;
    }
}

地图类 Map.java

package sqare;

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

public class Map extends JPanel implements Runnable {
    private boolean flag = false;
    private boolean flagother = false;
    private boolean flagtwo = false;
    //定义游戏中最多出现多少行和列
    private static final int MAX_ROWS = 24;
    private static final int MAX_COLS = 16;
    //定义延迟时间 决定游戏的速度
    private int delay = 1000;
    //该值表示此处为空 没有任何砖块
    private static final int NULL_BRICK = -1;
    //定义边界
    private static final int BORDER = 20;
    /**
     * 此数组表示游戏进行时的整个面板,当某位置无砖块时数组的值为NULL_BRICK,当有砖块
     * 时数组的值为此处砖块颜色的索引值
     */
    private int[][] brick_info;
    //记录游戏得分
    private static int score;
    //标识游戏是否结束,true为结束false为未结束
    private boolean gameOver = true;
    //标识砖块是否已经到达底部,投入额为达到false为未到达
    private boolean reachBottom = true;
    //显示下一个砖块的横坐标和纵坐标
    private int msgX, msgY;
    //当前砖块和预览砖块
    private Brick brick, next_brick;
    private Random ran;

    //构造方法,初始化游戏中的一些参数
    public Map() {
        brick_info = new int[MAX_ROWS][MAX_COLS];//游戏区域
        resetBrick_info();        //清空二维数组中的砖块信息
        brick = new Brick(0, 0, 0);   //产生当前砖块和下一个提示的砖块
        next_brick = new Brick(0, 0, 0);
        msgX = BORDER + (MAX_COLS + 1) * Brick.BRICK_WIDTH + BORDER;
        msgY = BORDER * 3;           //提示的下一个砖块的显示位置
        ran = new Random();
        score = 0;
    }

    /**
     * 重置brick_info数组
     */
    private void resetBrick_info() {     //清空二维数组中的砖块信息
        for (int i = 0; i < MAX_ROWS; i++) {
            for (int j = 0; j < MAX_COLS; j++) {
                brick_info[i][j] = NULL_BRICK;
            }
        }
    }

    /**
     * 游戏开始时调用此方法,初始化一些有戏中必须的参数
     */
    public void startGame() {
        gameOver = false;
        reachBottom = false;
        score = 0;        //变量赋初值
        (new Thread(this)).start();
        repaint();
    }
    /**
     *此方法用来结束游戏
     */

    /**
     * 进行游戏的线程,游戏开始时会被调用。当有戏结束标志为false时则继续游戏,若砖块的
     * x坐标为-1或到达底部标志为true则重新创建一个砖块并将reachBottom置为false,清空brick_info
     * 数组中当前位置,将当前砖块的信息填充到brick_info数组的当前位置。若x坐标不为-1且reachBottom
     * 不为true则向下移动砖块,若到达底部则继续下一次循环,否则延时delay毫秒继续循环
     */
    public void run() {
        while (!gameOver) {                   //只要游戏没有结束,继续
            if (brick.x == -1 || reachBottom) {   //只要当前砖块到达界面底部,
                createNewBrick();              //产生一个新砖块
                reachBottom = false;           //将到达底部的变量重置为假
                //updataBrick_info(true);       //将当前砖块区域清空
                //updataBrick_info(false);      //根据当前砖块位置重画
            } else {
                drop();                        //砖块下落
            }
            try {
                Thread.sleep(delay);           //线程休眠一会
            } catch (InterruptedException e) {

            }
        }
    }

    /**
     * 创建砖块函数,利用下一个砖块的信息重置当前砖块的信息,同时重新生成下一个砖块的信息
     * 以备下一次创建砖块使用
     */
    synchronized private void createNewBrick() {
        if (next_brick.x == -1) {
            int shape = ran.nextInt(200);
            int angle = ran.nextInt(200);
            int color_index = ran.nextInt(200);
            next_brick.resetBrick(shape, angle, color_index);
            next_brick.x = 0;
        }               //将下一个砖块的信息赋给当前信息,将下一个砖块变成正在进行的砖块
        brick.resetBrick(next_brick.current_shape, next_brick.current_angle, next_brick.current_color_index);
        brick.x = 8;
        brick.y = 0;
        flagother = true;
        brick.current_color = Brick.ALL_COLOR[next_brick.current_color_index];//下一砖块颜色赋给当前砖块
        int shape1 = ran.nextInt(200);
        int angle1 = ran.nextInt(200);
        int color_index1 = ran.nextInt(200);//使用随机数,生成形状,角度,颜色
        next_brick.resetBrick(shape1, angle1, color_index1); //下一个砖块生成
    }

    /**
     * 清空或填充brick_info数组中当前砖块位置的信息,当清空时,将该处信息全部至为NULL_BRICK
     * 当时填充时将当前砖块的颜色索引值填入相应的位置
     */
    private void updataBrick_info(boolean clear) {
        //clear为真,将临时区域全部清空;
        //clear为假,将当前砖块填充到临时区域
        int[][] tempBrick = brick.getCurrentBrickModle(brick.current_shape, brick.current_angle);
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (tempBrick[i][j] != 0) {
                    brick_info[brick.y + i][brick.x + j] = clear ? NULL_BRICK : brick.current_color_index;
                }
            }
        }
        if (!clear) {
            repaint();
        }
    }

    /**
     * 定义砖块向下移动的方法,先清空当前砖块在brick_info数组中的信息,然后判断是否可以
     * 移动到brick.y+1的位置,如果可以则将brick.y+1,brick.x不变,
     * 如果不可以移动,判断brick.y的值是否为0,为0说明游戏结束,将gameOver置为true否则是
     * 到达底部,将reachBottom置为true。最后填充brick_info数组检查是否可以消行
     */
    public void drop() {
        if (brick.x == -1) {
            return;
        }
        updataBrick_info(true);

        if (canMove(brick.x, brick.y + 1)) {
            brick.y += 1;
        } else {
            if (brick.y == 0) {
                gameOver = true;
            } else {
                reachBottom = true;
            }
        }
        updataBrick_info(false);
        if (reachBottom) {
            checkRowAndGetScore();
        }
    }

    /**
     * 检查砖块是否可以移动,当x<0时超过左边界返回false。当重叠或者超过右边界或底边界
     * 时返回false。不超出任何边界也不重叠返回true
     */
    private boolean canMove(int x, int y) {
        //超过左边界返回false
        if ((x < 0) || (y >= MAX_ROWS)) {
            return false;
        }
        //不能重叠和超过下边界和右边界否则返回false
        int[][] tempBrick = brick.getCurrentBrickModle(brick.current_shape, brick.current_angle);
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (tempBrick[i][j] != 0) {
                    if (x + j >= MAX_COLS || y + i >= MAX_ROWS || brick_info[y + i][x + j] != NULL_BRICK) {
                        return false;
                    }
                }
            }
        }
        return true;
    }

    /**
     * 实现左右移动,当传递参数为-1时代表左移一个单位,参数为1时代表右移一个单位
     */
    public void moveLeftOrRight(int left) {
        if (brick.x != -1) {
            updataBrick_info(true);


            if (canMove(brick.x + left, brick.y)) {
                updataBrick_info(true);

                brick.x += left;
            }
        }
        updataBrick_info(false);
    }

    /**
     * 检查是否有满行,并记录有几行满行,跟据一次削去行数的不同相应的得分也不同,并记录
     * 相同颜色的行数,颜色相同的行数不同相应的得分也不同。最后绘制得分削去符合条件的行
     */
    public void checkRowAndGetScore() {
        int s = 0;
        int full_lines_score = 50;  //满一行的基础得分
        int color_score = 200;       //一行颜色相同的基础得分
        int full_rows_lines = 0;     //满的行数
        int same_colors_lines = 0;   //颜色相同的行数
        boolean full_rows;           //标记是否满行
        boolean same_colors;         //标记是否颜色相同
        for (int i = MAX_ROWS - 1; i >= 0; i--) {
            full_rows = true;
            same_colors = true;
            //如果此行内brick_info数组中有NULL_BRICK说明该行不可消除则跳出本行进行下一行检验
            for (int j = 0; j < MAX_COLS; j++) {
                if (brick_info[i][j] == NULL_BRICK) {
                    full_rows = false;
                    break;
                }
                if (j + 1 <= MAX_COLS - 1 && brick_info[i][j] != brick_info[i][j + 1]) {
                    same_colors = false;
                }
            }
            if (full_rows == true) {                //如果满行,满行数加一,如果颜色相同,颜色数加一并削去该行
                full_rows_lines++;
                if (same_colors == true) {
                    same_colors_lines++;
                }
                for (int z = i; z > 0; z--) {              //将上面的砖块全体下移,并将最上面一行全部置空
                    //brick_info[z]= brick_info[z-1];
                    System.arraycopy(brick_info[z - 1], 0, brick_info[z], 0, MAX_COLS);
                }
                for (int n = 0; n < MAX_COLS; n++) {
                    brick_info[0][n] = NULL_BRICK;
                    flag = true;
                }
                i++;
            }
        }

        //记算得分并根据得分更改游戏速度
        s += (full_lines_score + full_rows_lines % 4 * 50) * full_rows_lines;
        s += (color_score + same_colors_lines % 4 * 100) * same_colors_lines;
        this.score += s;
        delay -= s / 50;
    }

    /**
     * 绘制游戏边界
     */
    private void drawBorder(Graphics g) {
        int rightX = BORDER + (MAX_COLS + 1) * Brick.BRICK_WIDTH;//右边界横坐标
        int bottomY = BORDER + MAX_ROWS * Brick.BRICK_HEIGHT;  //底部边界的纵坐标
        int x, y;
        g.setColor(Color.BLACK);  //设定边界颜色
        //绘制左右边界
        for (int i = 0; i < MAX_ROWS; i++) {
            y = BORDER + i * Brick.BRICK_WIDTH; //一个边界砖块的纵坐标
            g.fill3DRect(BORDER, y, Brick.BRICK_WIDTH, Brick.BRICK_HEIGHT, true);
            g.fill3DRect(rightX, y, Brick.BRICK_WIDTH, Brick.BRICK_HEIGHT, true);
        }
        //绘制底部边界
        for (int j = 0; j <= MAX_COLS + 1; j++) {
            x = BORDER + j * Brick.BRICK_WIDTH;  //每一个底部边界砖块的横坐标
            g.fill3DRect(x, bottomY, Brick.BRICK_WIDTH, Brick.BRICK_HEIGHT, true);
        }
    }

    /**
     * 根据brick_info数组绘制游戏面板中的所有砖块
     */
    private void drawBrick(Graphics g) {
        int index, x, y;
        for (int i = 0; i < MAX_ROWS; i++) {
            for (int j = 0; j < MAX_COLS; j++) {
                index = brick_info[i][j];
                if (index != NULL_BRICK) {
                    x = BORDER + (j + 1) * Brick.BRICK_WIDTH;  //该砖块的横坐标
                    y = BORDER + i * Brick.BRICK_HEIGHT;  //该砖块的纵坐标
                    g.setColor(Brick.ALL_COLOR[index]);
                    g.fill3DRect(x, y, Brick.BRICK_WIDTH, Brick.BRICK_HEIGHT, true);
                }
            }
        }
    }

    /**
     * 根据next_brick中的信息绘制出下一个砖块
     */
    private void drawNextBrick(Graphics g) {
        int[][] msgBrick = next_brick.getCurrentBrickModle(next_brick.current_shape, next_brick.current_angle);
        int index = next_brick.current_color_index;
        int x, y;
        g.setColor(Brick.ALL_COLOR[index]);
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 4; j++) {
                if (msgBrick[i][j] != 0) {
                    x = msgX + j * Brick.BRICK_WIDTH;
                    y = msgY + i * Brick.BRICK_HEIGHT;
                    g.fill3DRect(x, y, Brick.BRICK_WIDTH, Brick.BRICK_HEIGHT, true);
                }
            }
        }
        repaint();
    }

    /**
     * 用来旋转砖块,每次旋转90度,
     */
    public void turnAngle() {
        if (brick.x != -1) {
            updataBrick_info(true);
            brick.turnAngle(1);
            if (!canMove(brick.x, brick.y)) {
                brick.turnAngle(3);
            }
        }
        updataBrick_info(false);
    }

    /**
     * 绘制得分
     */
    private void drawScore(Graphics g, int score) {
        String str = "得分:" + score;
        int x = BORDER + (MAX_COLS + 1) * Brick.BRICK_WIDTH + BORDER;
        int y = BORDER + BORDER / 2;
        g.setColor(Color.RED);
        g.drawString(str, x, y);
    }

    /**
     * 重载JPanel的paint()方法
     */
    public void paint(Graphics g) {
        super.paint(g);
        drawBorder(g);
        if (brick.x == -1) {
            return;
        }
        drawBrick(g);
        drawNextBrick(g);
        drawScore(g, this.score);
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值