JFrame如何弄出俄罗斯方块消除游戏的时候有爆炸效果

俄罗斯方块JAVA实现 求思路,求带注释方便阅读的代码
[问题点数:100分,结帖人javaeclipsemysql]
本版专家分:0
结帖率 100%
CSDN今日推荐
本版专家分:46
本版专家分:609
本版专家分:18123
2010年6月 Java大版内专家分月排行榜第一
本版专家分:5277
本版专家分:22671
2010年7月 Java大版内专家分月排行榜第二2010年6月 Java大版内专家分月排行榜第二
2010年8月 Java大版内专家分月排行榜第三
本版专家分:397
本版专家分:0
本版专家分:0
本版专家分:8245
2010年7月 Java大版内专家分月排行榜第三
本版专家分:8245
2010年7月 Java大版内专家分月排行榜第三
本版专家分:8245
2010年7月 Java大版内专家分月排行榜第三
本版专家分:200
本版专家分:0
匿名用户不能发表回复!|
其他相关推荐https://okcthouder.github.io/
用java写的俄罗斯方块小程序
这是java课最后做的课程设计,由于java是初学的,所以做的时候有参考一些技术大牛的博客,在此表示感谢。
发在这里跟大家交流学习一下。
如需要完整工程文件、说明文档以及可运行jar文件,下载地址:
RussianBlocksGame.java
package RussiaBlocksG
import java.awt.*;
import java.awt.event.*;
import javax.swing.*;
import javax.swing.border.B
import javax.swing.border.EtchedB
* 游戏主类,继承自JFrame类,负责游戏的全局控制。 内含: 1.一个GameCanvas画布类的实例对象,
* 2.一个保存当前活动块(RussiaBlock)实例的对象; 3.一个保存当前控制面板(ControlPanel)实例的对象;
public class RussiaBlocksGame extends JFrame {
private static final long serialVersionUID = -9674749L;
* 每填满一行计多少分
public final static int PER_LINE_SCORE = 100;
* 积多少分以后能升级
public final static int PER_LEVEL_SCORE = PER_LINE_SCORE * 20;
* 最大级数是10级
public final static int MAX_LEVEL = 10;
* 默认级数是2
public final static int DEFAULT_LEVEL = 2;
private GameC
private ErsB
private boolean playing =
private ControlPanel ctrlP
//初始化菜单栏
private JMenuBar bar = new JMenuBar();
private JMenu mGame = new JMenu(" 游戏"),
mControl = new JMenu(" 控制"),
mInfo = new JMenu("帮助");
private JMenuItem miNewGame = new JMenuItem("新游戏"),
miSetBlockColor = new JMenuItem("设置方块颜色..."),
miSetBackColor = new JMenuItem("设置背景颜色..."),
miTurnHarder = new JMenuItem("升高游戏难度"),
miTurnEasier = new JMenuItem("降低游戏难度"),
miExit = new JMenuItem("退出"),
miPlay = new JMenuItem("开始"),
miPause = new JMenuItem("暂停"),
miResume = new JMenuItem("恢复"),
miStop = new JMenuItem("终止游戏"),
miRule = new JMenuItem("游戏规则"),
miAuthor = new JMenuItem("关于本游戏");
* 建立并设置窗口菜单
private void creatMenu() {
bar.add(mGame);
bar.add(mControl);
bar.add(mInfo);
mGame.add(miNewGame);
mGame.addSeparator();//在菜单中加水平分割线
mGame.add(miSetBlockColor);
mGame.add(miSetBackColor);
mGame.addSeparator();//在菜单中加水平分割线
mGame.add(miTurnHarder);
mGame.add(miTurnEasier);
mGame.addSeparator();//在菜单中加水平分割线
mGame.add(miExit);
mControl.add(miPlay);
miPlay.setEnabled(true);
mControl.add(miPause);
miPause.setEnabled(false);
mControl.add(miResume);
miResume.setEnabled(false);
mControl.add(miStop);
miStop.setEnabled(false);
mInfo.add(miRule);
mInfo.add(miAuthor);
setJMenuBar(bar);
miNewGame.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
stopGame();
setLevel(DEFAULT_LEVEL);
//设置方块颜色
miSetBlockColor.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Color newFrontColor =
JColorChooser.showDialog(RussiaBlocksGame.this, "设置方块颜色", canvas.getBlockColor());
if (newFrontColor != null) {
canvas.setBlockColor(newFrontColor);
//设置背景颜色
miSetBackColor.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
Color newBackColor =
JColorChooser.showDialog(RussiaBlocksGame.this, "设置背景颜色", canvas.getBackgroundColor());
if (newBackColor != null) {
canvas.setBackgroundColor(newBackColor);
//定义菜单栏"关于"的功能,弹出确认框。
miAuthor.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "软件工程(4)班\n\n杨宇杰\n(C)一切解释权归杨宇杰所有", "关于俄罗斯方块 - 2016", 1);
//游戏规则说明
miRule.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "由小方块组成的不同形状的板块陆续从屏幕上方落下来,\n玩家通过调整板块的位置和方向,使它们在屏幕底部拼\n出完整的一条或几条。这些完整的横条会随即消失,给新\n落下来的板块腾出空间,与此同时,玩家得到分数奖励。\n没有被消除掉的方块不断堆积起来,一旦堆到屏幕顶端,\n玩家便告输,游戏结束。", "游戏规则", 1);
//增加难度
miTurnHarder.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int curLevel = getLevel();
if (!playing && curLevel & MAX_LEVEL) {
setLevel(curLevel + 1);
//减少难度
miTurnEasier.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
int curLevel = getLevel();
if (!playing && curLevel & 1) {
setLevel(curLevel - 1);
//退出按钮动作响应
miExit.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent e) {
System.exit(0);
* 主游戏类的构造方法
* @param title String ,窗口标题
public RussiaBlocksGame(String title) {
super(title);
//设置标题
setSize(500, 600);
//设置窗口大小
setLocationRelativeTo(null);
//设置窗口居中
creatMenu();
Container container = getContentPane();
//创建菜单栏
container.setLayout(new BorderLayout(6, 0));
//设置窗口的布局管理器
canvas = new GameCanvas(20, 15);
//新建游戏画布
ctrlPanel = new ControlPanel(this);
//新建控制面板
container.add(canvas, BorderLayout.CENTER);
//左边加上画布
container.add(ctrlPanel, BorderLayout.EAST);
//右边加上控制面板
//注册窗口事件。当点击关闭按钮时,结束游戏,系统退出。
addWindowListener(new WindowAdapter() {
public void windowClosing(WindowEvent we) {
stopGame();
System.exit(0);
//根据窗口大小,自动调节方格的尺寸
addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent ce) {
canvas.adjust();
setVisible(true);
canvas.adjust();
* 让游戏复位
public void reset() {
//画布复位,控制面板复位
ctrlPanel.setPlayButtonEnable(true);
ctrlPanel.setPauseButtonEnable(false);
ctrlPanel.setPauseButtonLabel(true);
ctrlPanel.setStopButtonEnable(false);
ctrlPanel.setTurnLevelDownButtonEnable(true);
ctrlPanel.setTurnLevelUpButtonEnable(true);
miPlay.setEnabled(true);
miPause.setEnabled(false);
miResume.setEnabled(false);
miStop.setEnabled(false);
ctrlPanel.reset();
canvas.reset();
* 判断游戏是否还在进行
* @return boolean,true -还在运行,false-已经停止
public boolean isPlaying() {
* 得到当前活动的块
* @return ErsBlock,当前活动块的引用
public ErsBlock getCurBlock() {
* 得到当前画布
* @return GameCanvas,当前画布的引用
public GameCanvas getCanvas() {
* 开始游戏
public void playGame() {
ctrlPanel.setPlayButtonEnable(false);
ctrlPanel.setPauseButtonEnable(true);
ctrlPanel.setPauseButtonLabel(true);
ctrlPanel.setStopButtonEnable(true);
ctrlPanel.setTurnLevelDownButtonEnable(false);
ctrlPanel.setTurnLevelUpButtonEnable(false);
miStop.setEnabled(true);
miTurnHarder.setEnabled(false);
miTurnEasier.setEnabled(false);
ctrlPanel.requestFocus();
//设置焦点在控制面板上
* 游戏暂停
public void pauseGame() {
if (block != null) {
block.pauseMove();
ctrlPanel.setPlayButtonEnable(false);
ctrlPanel.setPauseButtonLabel(false);
ctrlPanel.setStopButtonEnable(true);
miPlay.setEnabled(false);
miPause.setEnabled(false);
miResume.setEnabled(true);
miStop.setEnabled(true);
* 让暂停中的游戏继续
public void resumeGame() {
if (block != null) {
block.resumeMove();
ctrlPanel.setPlayButtonEnable(false);
ctrlPanel.setPauseButtonEnable(true);
ctrlPanel.setPauseButtonLabel(true);
miPause.setEnabled(true);
miResume.setEnabled(false);
ctrlPanel.requestFocus();
* 用户停止游戏
public void stopGame() {
if (block != null) {
block.stopMove();
ctrlPanel.setPlayButtonEnable(true);
ctrlPanel.setPauseButtonEnable(false);
ctrlPanel.setPauseButtonLabel(true);
ctrlPanel.setStopButtonEnable(false);
ctrlPanel.setTurnLevelDownButtonEnable(true);
ctrlPanel.setTurnLevelUpButtonEnable(true);
miPlay.setEnabled(true);
miPause.setEnabled(false);
miResume.setEnabled(false);
miStop.setEnabled(false);
miTurnHarder.setEnabled(true);
miTurnEasier.setEnabled(true);
reset();//重置画布和控制面板
* 得到游戏者设置的难度
* @return int ,游戏难度1-MAX_LEVEL
public int getLevel() {
return ctrlPanel.getLevel();
* 用户设置游戏难度
* @param level int ,游戏难度1-MAX_LEVEL
public void setLevel(int level) {
if (level & 11 && level & 0) {
ctrlPanel.setLevel(level);
* 得到游戏积分
* @return int,积分
public int getScore() {
if (canvas != null) {
return canvas.getScore();
* 得到自上次升级以来的游戏积分,升级以后,此积分清零
* @return int,积分
public int getScoreForLevelUpdate() {
if (canvas != null) {
return canvas.getScoreForLevelUpdate();
* 当积分累积到一定数值时,升一次级
* @return Boolean,true-update succeed,false-update fail
public boolean levelUpdate() {
int curLevel = getLevel();
if (curLevel & MAX_LEVEL) {
setLevel(curLevel + 1);
canvas.resetScoreForLevelUpdate();
* 游戏开始
private void play() {
Thread thread = new Thread(new Game());//启动游戏线程
thread.start();
* 报告游戏结束了
private void reportGameOver() {
new gameOverDialog(this, "俄罗斯方块", "游戏结束,您的得分为" + canvas.getScore());
* 一轮游戏过程,实现了Runnable接口 一轮游戏是一个大循环,在这个循环中,每隔100毫秒, 检查游戏中的当前块是否已经到底了,如果没有,
* 就继续等待。如果到底了,就看有没有全填满的行, 如果有就删除它,并为游戏者加分,同时随机产生一个新的当前块并让它自动落下。
* 当新产生一个块时,先检查画布最顶上的一行是否已经被占了,如果是,可以判断Game Over 了。
private class Game implements Runnable {
public void run() {
int col = (int) (Math.random() * (canvas.getCols() - 3));//随机生成方块出现的位置
int style = ErsBlock.STYLES[ (int) (Math.random() * 7)][(int) (Math.random() * 4)];//随机生成一种形状的方块
while (playing) {
if (block != null) {
//第一次循环时,block为空
if (block.isAlive()) {
Thread.currentThread();
Thread.sleep(500);
} catch (InterruptedException ie) {
ie.printStackTrace();
checkFullLine();
//检查是否有全填满的行
if (isGameOver()) {
reportGameOver();
miPlay.setEnabled(true);
miPause.setEnabled(false);
miResume.setEnabled(false);
miStop.setEnabled(false);
ctrlPanel.setPlayButtonEnable(true);
ctrlPanel.setPauseButtonLabel(false);
ctrlPanel.setStopButtonEnable(false);
block = new ErsBlock(style, -1, col, getLevel(), canvas);
block.start();
col = (int) (Math.random() * (canvas.getCols() - 3));
style = ErsBlock.STYLES[ (int) (Math.random() * 7)][(int) (Math.random() * 4)];
ctrlPanel.setTipStyle(style);
//检查画布中是否有全填满的行,如果有就删之
public void checkFullLine() {
for (int i = 0; i & canvas.getRows(); i++) {
int row = -1;
boolean fullLineColorBox =
for (int j = 0; j & canvas.getCols(); j++) {
if (!canvas.getBox(i, j).isColorBox()) {
fullLineColorBox =
if (fullLineColorBox) {
row = i--;
canvas.removeLine(row);
//根据最顶行是否被占,判断游戏是否已经结束了
//@return boolean ,true-游戏结束了,false-游戏未结束
private boolean isGameOver() {
for (int i = 0; i & canvas.getCols(); i++) {
ErsBox box = canvas.getBox(0, i);
if (box.isColorBox()) {
* 定义GameOver对话框。
@SuppressWarnings("serial")
private class gameOverDialog extends JDialog implements ActionListener {
private JButton againButton, exitB
private Border border = new EtchedBorder(EtchedBorder.RAISED, Color.white, new Color(148, 145, 140));
public gameOverDialog(JFrame parent, String title, String message) {
super(parent, title, true);
if (parent != null) {
setSize(240, 120);
this.setLocationRelativeTo(parent);
JPanel messagePanel = new JPanel();
messagePanel.add(new JLabel(message));
messagePanel.setBorder(border);
Container container = this.getContentPane();
container.setLayout(new GridLayout(2, 0, 0, 10));
container.add(messagePanel);
JPanel choosePanel = new JPanel();
choosePanel.setLayout(new GridLayout(0, 2, 4, 0));
container.add(choosePanel);
againButton = new JButton("再玩一局");
exitButton = new JButton("退出游戏");
choosePanel.add(new JPanel().add(againButton));
choosePanel.add(new JPanel().add(exitButton));
choosePanel.setBorder(border);
againButton.addActionListener(this);
exitButton.addActionListener(this);
this.setVisible(true);
public void actionPerformed(ActionEvent e) {
if (e.getSource() == againButton) {
this.setVisible(false);
} else if (e.getSource() == exitButton) {
stopGame();
System.exit(0);
GameCanvas.java
package RussiaBlocksG
import java.awt.C
import java.awt.G
import javax.swing.JP
import javax.swing.border.EtchedB
* 画布类,内有&行数&*&列数& 个方格类实例。 继承自JPanel类。 ErsBlock线程类动态改变画布类的方格颜色,画布类通过
* 检查方格颜色来体现ErsBlock块的移动情况。
public class GameCanvas extends JPanel {
private static final long serialVersionUID = 6089276L;
private Color backColor = Color.darkGray, frontColor = Color.WHITE;
private int rows, cols, score = 0, scoreForLevelUpdate = 0;
private ErsBox[][]
private int boxWidth, boxH
* 画布类的构造函数
* @param rows int,画布的行数
* @param cols int,画布的列数 行数和列数决定着画布拥有方格的数目
public GameCanvas(int rows, int cols) {
this.rows =
this.cols =
boxes = new ErsBox[rows][cols];
for (int i = 0; i & boxes. i++) {
for (int j = 0; j & boxes[i]. j++) {
boxes[i][j] = new ErsBox(false);
setBorder(new EtchedBorder(EtchedBorder.RAISED, Color.white, new Color(148, 145, 140)));
* 画布类的构造函数
* @param rows
* @param cols
* @param backColor
* @param frontColor
public GameCanvas(int rows, int cols,
Color backColor, Color frontColor) {
this(rows, cols);
this.backColor = backC
this.frontColor = frontC
* 设置游戏背景色彩
* @param backColor Color,背景色彩
public void setBackgroundColor(Color backColor) {
this.backColor = backC
* 取得游戏背景色彩
* @return Color ,背景色彩
public Color getBackgroundColor() {
return backC
* 设置游戏方块颜色
* @param frontColor Color,方块颜色
public void setBlockColor(Color frontColor) {
this.frontColor = frontC
* 取得游戏方块色彩
* @return Color,方块颜色
public Color getBlockColor() {
return frontC
* 取得画布中方格的行数
public int getRows() {
* 取得画布中方格的列数
* @return int,方格的列数
public int getCols() {
* 取得游戏成绩
* @return int, 分数
public int getScore() {
* 取得自上一次升级后的积分
* @return int ,上一次升级后的积分
public int getScoreForLevelUpdate() {
return scoreForLevelU
* 升级后,将上一次升级以来的积分清零
public void resetScoreForLevelUpdate() {
scoreForLevelUpdate -= RussiaBlocksGame.PER_LEVEL_SCORE;
* 得到某一行某一列的方格引用
* @return row int ,要引用的方格所在的行
* @param col int, 要引用的方格所在的行
* @return ErsBox,在row行col列的方格的引用
public ErsBox getBox(int row, int col) {
if (row & 0 || row & boxes.length - 1 || col & 0 || col & boxes[0].length - 1) {
return (boxes[row][col]);
* 覆盖JComponent类的函数,画组件。
* @param g 图形设备环境
public void paintComponent(Graphics g) {
super.paintComponent(g);
g.setColor(frontColor);
for (int i = 0; i & boxes. i++) {
for (int j = 0; j & boxes[i]. j++) {
g.setColor(boxes[i][j].isColorBox() ? frontColor : backColor);
g.fill3DRect(j * boxWidth, i * boxHeight,
boxWidth, boxHeight, true);
* 根据窗口大小,自动调节方格的尺寸
public void adjust() {
boxWidth = getSize().width /
boxHeight = getSize().height /
* 当一行被游戏者叠满后,将此行清除,并为游戏者加分
* @param row int,要清除的行,是由ErsBoxesGame类计算的
public synchronized void removeLine(int row) {
for (int i = i & 0; i--) {
for (int j = 0; j & j++) {
boxes[i][j] = (ErsBox) boxes[i - 1][j].clone();
//将上一行的方块颜色克隆下来,
//即消去一行方块
score += RussiaBlocksGame.PER_LEVEL_SCORE;
scoreForLevelUpdate += RussiaBlocksGame.PER_LEVEL_SCORE;
repaint();
* 重置画布,置积分为零
public void reset() {
score = 0;
scoreForLevelUpdate = 0;
for (int i = 0; i & boxes. i++) {
for (int j = 0; j & boxes[i]. j++) {
boxes[i][j].setColor(false);
repaint();
ControlPanel.java
package RussiaBlocksG
import java.awt.BorderL
import java.awt.C
import java.awt.G
import java.awt.GridL
import java.awt.event.ActionE
import java.awt.event.ActionL
import java.awt.event.ComponentA
import java.awt.event.ComponentE
import java.awt.event.KeyA
import java.awt.event.KeyE
import java.text.DateF
import java.text.SimpleDateF
import java.util.D
import javax.swing.JB
import javax.swing.JL
import javax.swing.JP
import javax.swing.JTextF
import javax.swing.T
import javax.swing.border.B
import javax.swing.border.EtchedB
* 控制面板类,继承自JPanel。 上边安放预显窗口,等级,得分,控制按钮 主要用来控制游戏进程。
class ControlPanel extends JPanel {
private static final long serialVersionUID = 6175724L;
private JTextField tfLevel = new JTextField("" + RussiaBlocksGame.DEFAULT_LEVEL),
tfScore = new JTextField(" 0"),
tfTime = new JTextField(" ");
private JButton btPlay = new JButton(" 开始"),
btPause = new JButton(" 暂停"),
btStop = new JButton("终止游戏"),
btTurnLevelUp = new JButton(" 增加难度"),
btTurnLevelDown = new JButton(" 降低难度");
private JPanel plTip = new JPanel(new BorderLayout());
private TipPanel plTipBlock = new TipPanel();
private JPanel plInfo = new JPanel(new GridLayout(4, 1));
private JPanel plButton = new JPanel(new GridLayout(6, 1));
private Border border = new EtchedBorder(EtchedBorder.RAISED, Color.white, new Color(148, 145, 140));
* 控制面板类的构造函数
* @param game ErsBlocksGame,ErsBlocksGame 类的一个实例引用 方便直接控制ErsBlocksGame类的行为。
public ControlPanel(final RussiaBlocksGame game) {
setLayout(new GridLayout(3, 1, 0, 2));
plTip.add(new JLabel(" 下一个方块"), BorderLayout.NORTH);
//添加组件
plTip.add(plTipBlock);
plTip.setBorder(border);
plInfo.add(new JLabel(" 难度系数"));
plInfo.add(tfLevel);
plInfo.add(new JLabel(" 得分"));
plInfo.add(tfScore);
plInfo.setBorder(border);
plButton.add(btPlay);
btPlay.setEnabled(true);
plButton.add(btPause);
btPause.setEnabled(false);
plButton.add(btStop);
btStop.setEnabled(false);
plButton.add(btTurnLevelUp);
plButton.add(btTurnLevelDown);
plButton.add(tfTime);
plButton.setBorder(border);
tfLevel.setEditable(false);
tfScore.setEditable(false);
tfTime.setEditable(false);
add(plTip);
add(plInfo);
add(plButton);
addKeyListener(new KeyAdapter() {
public void keyPressed(KeyEvent ke) {
if (!game.isPlaying()) {
ErsBlock block = game.getCurBlock();
switch (ke.getKeyCode()) {
case KeyEvent.VK_DOWN:
block.moveDown();
case KeyEvent.VK_LEFT:
block.moveLeft();
case KeyEvent.VK_RIGHT:
block.moveRight();
case KeyEvent.VK_UP:
block.turnNext();
btPlay.addActionListener(new ActionListener() {
//开始游戏
public void actionPerformed(ActionEvent ae) {
game.playGame();
btPause.addActionListener(new ActionListener() {
//暂停游戏
public void actionPerformed(ActionEvent ae) {
if (btPause.getText().equals(" 暂停")) {
game.pauseGame();
game.resumeGame();
btStop.addActionListener(new ActionListener() {
//停止游戏
public void actionPerformed(ActionEvent ae) {
game.stopGame();
btTurnLevelUp.addActionListener(new ActionListener() {
//升高难度
public void actionPerformed(ActionEvent ae) {
int level = Integer.parseInt(tfLevel.getText());
if (level & RussiaBlocksGame.MAX_LEVEL) {
tfLevel.setText("" + (level + 1));
} catch (NumberFormatException e) {
requestFocus();
btTurnLevelDown.addActionListener(new ActionListener() {
//降低游戏难度
public void actionPerformed(ActionEvent ae) {
int level = Integer.parseInt(tfLevel.getText());
if (level & 1) {
tfLevel.setText("" + (level - 1));
} catch (NumberFormatException e) {
requestFocus();
addComponentListener(new ComponentAdapter() {
public void componentResized(ComponentEvent ce) {
plTipBlock.adjust();
timer = new Timer(1000, new ActionListener() {
public void actionPerformed(ActionEvent ae) {
DateFormat format = new SimpleDateFormat("时间:HH:mm:ss");
//系统获得时间
Date date = new Date();
tfTime.setText(format.format(date));
tfScore.setText("" + game.getScore());
int ScoreForLevelUpdate = //判断当前分数是否能升级
game.getScoreForLevelUpdate();
if (ScoreForLevelUpdate &= RussiaBlocksGame.PER_LEVEL_SCORE
&& ScoreForLevelUpdate & 0) {
game.levelUpdate();
timer.start();
* 设置预显窗口的样式
* @param style int,对应ErsBlock类的STYLES中的28个值
public void setTipStyle(int style) {
plTipBlock.setStyle(style);
* 取得用户设置的游戏等级。
* @return int ,难度等级,1-ErsBlocksGame.MAX_LEVEL
public int getLevel() {
int level = 0;
level = Integer.parseInt(tfLevel.getText());
} catch (NumberFormatException e) {
* 让用户修改游戏难度等级。
* @param level 修改后的游戏难度等级
public void setLevel(int level) {
if (level & 0 && level & 11) {
tfLevel.setText("" + level);
* 设置“开始”按钮的状态。
public void setPlayButtonEnable(boolean enable) {
btPlay.setEnabled(enable);
public void setPauseButtonEnable(boolean enable) {
btPause.setEnabled(enable);
public void setPauseButtonLabel(boolean pause) {
btPause.setText(pause ? " 暂停" : " 继续");
public void setStopButtonEnable(boolean enable) {
btStop.setEnabled(enable);
public void setTurnLevelUpButtonEnable(boolean enable) {
btTurnLevelUp.setEnabled(enable);
public void setTurnLevelDownButtonEnable(boolean enable) {
btTurnLevelDown.setEnabled(enable);
* 重置控制面板
public void reset() {
tfScore.setText(" 0");
plTipBlock.setStyle(0);
* 重新计算TipPanel里的boxes[][]里的小框的大小
public void adjust() {
plTipBlock.adjust();
* 预显窗口的实现细节类
public class TipPanel extends JPanel {
//TipPanel用来显示下一个将要出现方块的形状
private static final long serialVersionUID = 6997616L;
private Color backColor = Color.darkGray, frontColor = Color.WHITE;
private ErsBox[][] boxes = new ErsBox[ErsBlock.BOXES_ROWS][ErsBlock.BOXES_COLS];
private int style, boxWidth, boxH
private boolean isTiled =
* 预显示窗口类构造函数
public TipPanel() {
for (int i = 0; i & boxes. i++) {
for (int j = 0; j & boxes[i]. j++) {
boxes[i][j] = new ErsBox(false);
* 设置预显示窗口的方块样式
* @param style int,对应ErsBlock类的STYLES中的28个值
public void setStyle(int style) {
this.style =
repaint();
* 覆盖JComponent类的函数,画组件。
* @param g 图形设备环境
public void paintComponent(Graphics g) {
super.paintComponent(g);
if (!isTiled) {
int key = 0x8000;
for (int i = 0; i & boxes. i++) {
for (int j = 0; j & boxes[i]. j++) {
Color color = ((key & style) != 0 ? frontColor : backColor);
g.setColor(color);
g.fill3DRect(j * boxWidth, i * boxHeight,
boxWidth, boxHeight, true);
key &&= 1;
* g根据窗口的大小,自动调整方格的尺寸
public void adjust() {
boxWidth = getSize().width / ErsBlock.BOXES_COLS;
boxHeight = getSize().height / ErsBlock.BOXES_ROWS;
ErsBox.java
package RussiaBlocksG
import java.awt.D
* 方格类,是组成块的基本元素,用自己的颜色来表示块的外观
public class ErsBox implements Cloneable {
private boolean isC
private Dimension size = new Dimension();
* 方格类的构造函数,
* @param isColor 是不是用前景色来为此方格着色 true前景色,false 用背景色
public ErsBox(boolean isColor) {
this.isColor = isC
* 此方格是不是用前景色表现
* @return boolean ,true用前景色表现,false 用背景色表现
public boolean isColorBox() {
return isC
* 设置方格的颜色,
* @param isColor boolean ,true用前景色表现,false 用背景色表现
public void setColor(boolean isColor) {
this.isColor = isC
* 得到此方格的尺寸
* @return Dimension ,方格的尺寸
public Dimension getSize() {
* 设置方格的尺寸,
* @param size Dimension ,方格的尺寸
public void setSize(Dimension size) {
this.size =
* 覆盖Object的Object clone(),实现克隆
* @return Object,克隆的结果
public Object clone() {
Object cloned =
cloned = super.clone();
} catch (Exception ex) {
ex.printStackTrace();
ErsBlock.java
package RussiaBlocksG
* 块类,继承自线程类(Thread) 由4 × 4个方块(ErsBox)构成一个方块, 控制块的移动·下落·变形等
class ErsBlock extends Thread {
* 一个块占的行数是4行
public final static int BOXES_ROWS = 4;
* 一个块占的列数是4列
public final static int BOXES_COLS = 4;
* 让升级变化平滑的因子,避免最后几级之间的速度相差近一倍
public final static int LEVEL_FLATNESS_GENE = 3;
* 相近的两级之间,块每下落一行的时间差别为多少(毫秒)
public final static int BETWEEN_LEVELS_DEGRESS_TIME = 50;
* 方块的样式数目为7
public final static int BLOCK_KIND_NUMBER = 7;
* 每一个样式的方块的反转状态种类为4
public final static int BLOCK_STATUS_NUMBER = 4;
* 分别对应7种模型的28种状态
public final static int[][] STYLES = { //共28种状态
{0x0f00, 0xf00, 0x4444}, //长条型的四种状态
{0x04e0, 0xe4, 0x04c4}, //T型的四种状态
{0xc00, 0xc00}, //反Z型的四种状态
{0x0, 0x0}, //Z型的四种状态
{0x0, 0x0}, //7型的四种状态
{0xe20, 0x44c0, 0x8e00}, //反7型的四种状态
{0x0, 0x0}, //方块的四种状态
private GameC
private ErsBox[][] boxes = new ErsBox[BOXES_ROWS][BOXES_COLS];
private int style, y, x,
private boolean pausing = false, moving =
* 构造函数,产生一个特定的块
* @param style 块的样式,对应STYLES的28个值中的一个
* @param y 起始位置,左上角在canvas中的坐标行
* @param x 起始位置,左上角在canvas中的坐标列
* @param level 游戏等级,控制块的下落速度
* @param canvas 画板
public ErsBlock(int style, int y, int x, int level, GameCanvas canvas) {
this.style =
this.level =
this.canvas =
int key = 0x8000;
for (int i = 0; i & boxes. i++) {
for (int j = 0; j & boxes[i]. j++) {
boolean isColor = ((style & key) != 0);
boxes[i][j] = new ErsBox(isColor);
key &&= 1;
display();
* 线程类的run()函数覆盖,下落块,直到块不能再下落
public void run() {
while (moving) {
sleep(BETWEEN_LEVELS_DEGRESS_TIME
* (RussiaBlocksGame.MAX_LEVEL - level + LEVEL_FLATNESS_GENE));
} catch (InterruptedException ie) {
ie.printStackTrace();
//后边的moving是表示在等待的100毫秒间,moving没有被改变
if (!pausing) {
moving = (moveTo(y + 1, x) && moving);
* 块向左移动一格
public void moveLeft() {
moveTo(y, x - 1);
* 块向右移动一格
public void moveRight() {
moveTo(y, x + 1);
* 块向下移动一格
public void moveDown() {
moveTo(y + 1, x);
public void turnNext() {
for (int i = 0; i & BLOCK_KIND_NUMBER; i++) {
for (int j = 0; j & BLOCK_STATUS_NUMBER; j++) {
if (STYLES[i][j] == style) {
int newStyle = STYLES[i][(j + 1) % BLOCK_STATUS_NUMBER];
turnTo(newStyle);
public void startMove() {
* 暂停块的下落,对应游戏暂停
public void pauseMove() {
* 继续块的下落,对应游戏继续
public void resumeMove() {
* 停止块的下落,对应游戏停止
public void stopMove() {
* 将当前块从画布的对应位置移除,要等到下次重画画布时才能反映出来
private void erase() {
for (int i = 0; i & boxes. i++) {
for (int j = 0; j & boxes[i]. j++) {
if (boxes[i][j].isColorBox()) {
ErsBox box = canvas.getBox(i + y, j + x);
if (box == null) {
box.setColor(false);
* 让当前块放置在画布的对因位置上,要等到下次重画画布时才能看见
private void display() {
for (int i = 0; i & boxes. i++) {
for (int j = 0; j & boxes[i]. j++) {
if (boxes[i][j].isColorBox()) {
ErsBox box = canvas.getBox(i + y, j + x);
if (box == null) {
box.setColor(true);
* 当前块能否移动到newRow/newCol 所指定的位置
* @param newRow int,目的地所在行
* @param newCol int,目的地所在列
* @return boolean,true-能移动,false-不能移动
public boolean isMoveAble(int newRow, int newCol) {
for (int i = 0; i & boxes. i++) {
for (int j = 0; j & boxes[i]. j++) {
if (boxes[i][j].isColorBox()) {
ErsBox box = canvas.getBox(i + newRow, j + newCol);
if (box == null || (box.isColorBox())) {
display();
display();
* 将当前块移动到newRow/newCol 所指定的位置
* @param newRow int,目的地所在行
* @param newCol int,目的地所在列
* @return boolean,true-移动成功,false-移动失败
private synchronized boolean moveTo(int newRow, int newCol) {
if (!isMoveAble(newRow, newCol) || !moving) {
display();
canvas.repaint();
* 当前块能否变成newStyle所指定的块样式,主要是考虑 边界以及被其他块挡住,不能移动的情况
* @param newSytle int,希望改变的块样式,对应STYLES的28个值中的一个
* @return boolean,true-能改变,false-不能改变
private boolean isTurnAble(int newStyle) {
int key = 0x8000;
for (int i = 0; i & boxes. i++) {
for (int j = 0; j & boxes[i]. j++) {
if ((newStyle & key) != 0) {
ErsBox box = canvas.getBox(i + y, j + x);
if (box == null || (box.isColorBox())) {
display();
key &&= 1;
display();
* 将当前块变成newStyle所指定的块样式
* @param newStyle int,希望改变的块样式,对应STYLES的28个值中的一个
* @return true-改变成功,false-改变失败
private boolean turnTo(int newStyle) {
if (!isTurnAble(newStyle) || !moving) {
int key = 0x8000;
for (int i = 0; i & boxes. i++) {
for (int j = 0; j & boxes[i]. j++) {
boolean isColor = ((newStyle & key) != 0);
boxes[i][j].setColor(isColor);
key &&= 1;
style = newS
display();
canvas.repaint();
package RussiaBlocksG
* 程序入口函数
* @param args String[],附带的命令行参数
public class Main {
public static void main(String[] args) {
new RussiaBlocksGame("俄罗斯方块:杨宇杰");
用Java写俄罗斯方块
Java Socket通信实现带联机功能的俄罗斯方块
第一个Java小程序
java俄罗斯方块
没有更多推荐了,

我要回帖

更多关于 俄罗斯方块消除游戏 的文章

 

随机推荐