一、用Java实现俄罗斯方块游戏:
1、效果图,如下图所示:

7种形态的第一种形态, 如下所示:分布是 :|、S、Z、J、O、L、T;
0 1 0 0 0 1 1 0 1 1 0 0 0 1 0 0 1 1 0 0 1 0 0 0 1 1 1 0
0 1 0 0 1 1 0 0 0 1 1 0 0 1 0 0 1 1 0 0 1 0 0 0 0 1 0 0
0 1 0 0 0 0 0 0 0 0 0 0 1 1 0 0 0 0 0 0 1 1 0 0 0 0 0 0
0 1 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
我在绘制图形的时候,让1的坐标绘制出来,0 不绘制;横数4位数,竖数4位数,16位数为一组形态;

1.1.需要新建窗口;
1.2.绘制游戏内容;
1.3.实现形状旋转功能;
1.4.实现形状的移动;(监听键盘事件)
1.5.实现图形自动降落;

2、首先创建java项目,web Project
3、创建项目成功后,添加一个class文件(文件名自定义命名),代码如下:
package com.gx.games; import java.awt.Color; import java.awt.Font; import
java.awt.Graphics; import java.awt.event.ActionEvent; import
java.awt.event.ActionListener; import java.awt.event.KeyEvent; import
java.awt.event.KeyListener; import java.util.Random; import
javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.Timer;
/** * 俄罗斯方块游戏主体类 * @author LXT * */ public class TetrisPanel extends JPanel
implements KeyListener{ TetrisPanel () { newBlock(); newMap();
drawWall();//调用画围墙方法 Timer timer = new Timer(1000, new TimeListener());
timer.start();//启动定时器 } Random random = new Random(); private int score = 0;
private int delLineNum = 0; //定义方块的初始坐标; private int x; private int y;
//shapes[0][1] private int blockType;//方块的类型 = random.nextInt(7) private int
turnState;//方块的旋转状态 = random.nextInt(4) private int preBlockType =
random.nextInt(7); private int preTurnState = random.nextInt(4); //定义方块的大小
private int blockSize = 10; //定义地图大小 private int mapSizeX = 17; private int
mapSizeY = 28; //定义地图 int[][] map = new int[mapSizeX][mapSizeY]; int i; int j;
//地图中的值 0:没有 1:绘制形状 2:绘制围墙 //定义形状 private final static int shapes[][][] = new
int[][][]{ // |型 { {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 0,
0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, {0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0,
0, 0, 0}, {0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0}, }, // S型 { {0, 1,
1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0,
0, 0, 0, 0}, {0, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 0, 0, 0, 1,
1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, }, // Z型 { {1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0,
0, 0, 0, 0, 0}, {0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 0, 0,
0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0,
0, 0}, }, // J型 { {0, 1, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0}, {1, 0, 0,
0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0,
0, 0, 0}, {1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0}, }, // O型 { {1, 1,
0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0}, {1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 0, 0, 1,
1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, }, // L型 { {1, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0,
0, 0, 0, 0, 0}, {1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {1, 1, 0, 0,
0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, {0, 0, 1, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0,
0, 0}, }, // T型 { {1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, {0, 1, 0,
0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, {0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0,
0, 0, 0}, {1, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0}, } }; /** * 产生新的形状
*/ public void newBlock(){ //当前形状用预览形状代替 blockType = preBlockType; turnState =
preTurnState; //第三个 preBlockType = random.nextInt(7); preTurnState =
random.nextInt(4); //初始化xy坐标(方块的出现位置) x = 6; y = 0; if (gameOver (x, y) == 0) {
newMap(); drawWall(); JOptionPane.showMessageDialog(null, "GAME OVER!"); } }
/** * 填充围墙 */ public void drawWall(){ for(i = 0; i < mapSizeX - 1; i++){
map[i][mapSizeY - 2] = 2;//绘制右边的围墙 } for(j = 0; j < mapSizeY - 1; j++){
map[0][j] = 2;//绘制左边的围墙 map[mapSizeX - 2][j] = 2;//绘制底下的围墙 } } /** * 初始化地图 */
public void newMap () { for (i = 0; i < mapSizeX - 1; i++){ for (j = 0; j <
mapSizeY - 1; j++){ map[i][j] = 0; } } } /** * 改变方向 */ public void turn () {
int tempTurnState = turnState; //产生新的方向代码 turnState = (turnState + 1) % 4; if
(check (x,y,blockType, turnState) == 0) { turnState = tempTurnState; }
repaint(); } //左移 public void left () { if (check (x - 1, y, blockType,
turnState) == 1) { x = x - 1; } repaint(); } //右移 public void right () { if
(check (x + 1, y, blockType, turnState) == 1) { x = x + 1; } repaint(); } //下降
public void down () { delLineNum = 0; if (check (x, y + 1, blockType,
turnState) == 1) { y = y + 1; delLine(); } if (check (x, y + 1, blockType,
turnState) == 0) { add(x, y, blockType, turnState); newBlock(); delLine(); }
//制订分数 switch (delLineNum) { case 1:score += 10; break; case 2:score += 50;
break; case 3:score += 100; break; case 4:score += 200; break; } repaint(); }
/** * 添加一个形状 * @param x * @param y * @param blockType * @param turnState */
public void add (int x, int y, int blockType, int turnState) { int j = 0; for
(int outer = 0; outer < 4; outer++) { for (int inner = 0; inner < 4; inner++) {
if (map[x + inner + 1][y + outer] == 0) { map[x + inner + 1][y + outer] =
shapes[blockType][turnState][j]; } j++; } } } //消行 public void delLine () { int
flag = 0; for(int y = 0; y < mapSizeY - 1; y++) { for(int x = 0; x < mapSizeX -
1; x++) { if(map[x][y] == 1) { flag = flag + 1; //判断是否填充满一行 if(flag == mapSizeX
- 3) { delLineNum++; for (int d = y; d > 0; d--) { for (int e = 0; e < mapSizeX
- 2; e++) { map[e][d] = map[e][d - 1]; } } } } } flag = 0; } } /** * 判断是不是游戏结束
* @param x * @param y * @return */ public int gameOver (int x , int y) { if
(check (x, y, blockType, turnState) == 0) { return 0; } return 1; } /** *
检查操作是否有效 * @param x * @param y * @param blockType * @param turnState * @return
*/ public int check (int x, int y, int blockType, int turnState) { for (int
outer = 0; outer < 4; outer++) { for (int inner = 0; inner < 4; inner++) {
boolean flag1 = shapes[blockType][turnState][outer * 4 + inner] == 1; boolean
flag2 = map[x + inner + 1][y + outer] == 1; boolean flag3 = map[x + inner +
1][y + outer] == 2; if ((flag1 && flag2) || (flag1 && flag3)) { return 0;//碰到一起
无效 } } } return 1;//有效 } /** * 真正绘制 */ @Override public void paintComponent
(Graphics g){ super.paintComponent(g);//调用paintComponent方法,绘制一些父类的东西
g.setColor(Color.BLACK); //画形状 for (j = 0; j < 16; j++){ if
(shapes[blockType][turnState][j] == 1){ int x1 = (j % 4 + x + 1) * blockSize;
int y1 = (j / 4 + y) * blockSize; g.fillRect(x1, y1, blockSize, blockSize); } }
//固定方块 for (j = 0; j < mapSizeY - 1; j++){ for (i = 0; i < mapSizeX - 1; i++){
//已固定的方块 if (map[i][j] == 1){ g.setColor(Color.BLACK);//设置一个颜色(黑色) g.fillRect(i
* blockSize, j * blockSize, blockSize, blockSize);//填充 } if(map[i][j] == 2){
g.drawRect(i * blockSize, j * blockSize, blockSize, blockSize);//画线 } } }
//画预览图 for (j = 0; j < 16; j++){ if (shapes[preBlockType][preTurnState][j] ==
1){ int x1 = (j % 4 + 20) * blockSize; int y1 = (j / 4 + 1) * blockSize;
g.fillRect(x1, y1, blockSize, blockSize); } } g.setColor(Color.BLUE);
g.setFont(new Font ("宋体", Font.BOLD, 16)); g.drawString("得分:" + score, 170,
80); g.drawString("软件IT学院", 170, 110); g.drawString("2016级1班", 170, 140);
g.drawString("默默雨[著]", 170, 170); g.drawString("[版权所有]", 170, 200);
g.drawString("代号:12580", 170, 230); } @Override public void keyTyped(KeyEvent
e) { // TODO Auto-generated method stub } @Override public void
keyPressed(KeyEvent e) { int KeyCode = e.getKeyCode(); switch (KeyCode) { case
KeyEvent.VK_DOWN: //执行下降 down(); break; case KeyEvent.VK_UP: //执行变形 turn();
break; case KeyEvent.VK_RIGHT: //右移 right(); break; case KeyEvent.VK_LEFT: //左移
left(); break; } } @Override public void keyReleased(KeyEvent e) { // TODO
Auto-generated method stub } /** * 定时器 自动下降 * @author LXT * */ class
TimeListener implements ActionListener { @Override public void
actionPerformed(ActionEvent e) { //repaint(); down(); } } }
4、然后在创建一个class文件(文件名自定义命名),代码如下:
package com.gx.games; import java.awt.event.ActionEvent; import
java.awt.event.ActionListener; import javax.swing.JFrame; import
javax.swing.JMenu; import javax.swing.JMenuBar; import javax.swing.JMenuItem;
import javax.swing.JOptionPane; public class LiuTetnis extends JFrame { public
LiuTetnis () { TetrisPanel panel = new TetrisPanel (); addKeyListener(panel);
add(panel); } public static void main(String[] args) { LiuTetnis frame = new
LiuTetnis (); frame.setLocationRelativeTo(null); // 居中
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//点击关闭按钮,退出程序
frame.setSize(270, 330);//设置窗体大小(高度和宽度) frame.setTitle("俄罗斯方块");//设置窗体标题 //菜单栏
JMenuBar menuBar = new JMenuBar(); JMenu help = new JMenu("帮助"); JMenuItem
about = help.add("关于"); menuBar.add(help); about.addActionListener(new
ActionListener() { @Override public void actionPerformed(ActionEvent e) {
JOptionPane.showMessageDialog(null, "【俄罗斯方块练习版】作者:软件学院-liu"); } });
frame.setJMenuBar(menuBar); //菜单栏 frame.setVisible(true);//让窗体显示出来
frame.setResizable(false);//不能调整窗口大小 } }
5、然后在main方法里面的任意地方点击鼠标右键选择“Run AS”,选择“Java Application”,进行启动即可。

友情链接
KaDraw流程图
API参考文档
OK工具箱
云服务器优惠
阿里云优惠券
腾讯云优惠券
华为云优惠券
站点信息
问题反馈
邮箱:[email protected]
QQ群:637538335
关注微信