Java游戏开发 —— 俄罗斯方块

article/2025/11/2 11:08:51

引言:

        俄罗斯方块的代码实现很简单,很有意思!

思路:

        1、创建主窗口,加载菜单及游戏面板。

        2、在游戏面板中初始化各种参数,并建立各种功能组件。

        3、利用paint()函数开始画方块。

        4、游戏结束,收尾,准备下一局。


本游戏用的是JDK1.8,编码UTF-8;

        共有5个类,Gobang.java是游戏入口类。GameFrame.java是主窗口类。GamePanel.java是游戏面板类。GameLogic.java是游戏逻辑类。先一口气把所有的代码贴上来再说。

1、Tetris.java 游戏入口类

package com.game.tetris;/*** 功能:俄罗斯方块<br>* 作者:我是小木鱼(Lag)<br>*/
public class Tetris 
{public static void main(String[] args){new GameFrame();}}

2、GameFrame.java 主窗口类。

package com.game.tetris;import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;/*** 功能:游戏窗口<br>* 作者:我是小木鱼(Lag)<br>*/
public class GameFrame extends JFrame implements ActionListener
{private static final long serialVersionUID = 1L;/** 游戏面板 */private GamePanel gamePanel;/*** 功能:构造函数<br>*/public GameFrame(){try{//菜单JMenuBar jmb_tetris = new JMenuBar();JMenu jm_game = new JMenu("游戏");JMenuItem jmi_game_new = jm_game.add("新游戏");jmi_game_new.addActionListener(this);jmi_game_new.setActionCommand("new");JMenuItem jmi_game_pause = jm_game.add("暂停");jmi_game_pause.addActionListener(this);jmi_game_pause.setActionCommand("pause");JMenuItem jmi_game_continue = jm_game.add("继续");jmi_game_continue.addActionListener(this);jmi_game_continue.setActionCommand("continue");jm_game.addSeparator();JMenuItem jmi_game_exit = jm_game.add("退出");jmi_game_exit.addActionListener(this);jmi_game_exit.setActionCommand("exit");jmb_tetris.add(jm_game);JMenu jm_help = new JMenu("帮助");JMenuItem jmi_help_about = jm_help.add("关于");jmi_help_about.addActionListener(this);jmi_help_about.setActionCommand("about");jmb_tetris.add(jm_help);this.setJMenuBar(jmb_tetris);//面板this.gamePanel = new GamePanel();this.add(this.gamePanel);//显示this.setTitle("俄罗斯方块");this.setSize(400,500);this.setResizable(false);this.setLocationRelativeTo(null);this.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);this.setVisible(true);}catch(Exception e){JOptionPane.showMessageDialog(this,"程序出现异常错误,即将退出!\r\n\r\n"+e.toString(),"提示",JOptionPane.ERROR_MESSAGE);System.exit(0);}}/*** 功能:事件监听<br>*/@Overridepublic void actionPerformed(ActionEvent e){String command = e.getActionCommand();if("new".equals(command)){this.gamePanel.newGame();}else if("pause".equals(command)){this.gamePanel.pauseGame();}else if("continue".equals(command)){this.gamePanel.continueGame();}else if("exit".equals(command)){System.exit(0);}else if("about".equals(command)){JOptionPane.showMessageDialog(this,"左右键移动,向上键旋转!\r\n\r\n我是小木鱼(Lag)\r\n\r\n","提示",JOptionPane.INFORMATION_MESSAGE);}}}

3、GamePanel.java 游戏面板类。

package com.game.tetris;import java.awt.Font;
import java.awt.Color;
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 javax.swing.JPanel;
import javax.swing.Timer;/*** 功能:游戏面板<br>* 作者:我是小木鱼(Lag)<br>*/
public class GamePanel extends JPanel implements KeyListener,ActionListener
{private static final long serialVersionUID = 1L;/** 游戏逻辑 */private GameLogic gameLogic;/** 游戏地图(共21行12列,该地图包含墙和固定死的方块信息) */private byte[][] map;/** 是否接收键盘信息(true-接收,false-不接收) */private boolean isAcceptKey = true;/** 定时器 */private Timer timer;/*** 功能:构造函数<br>*/public GamePanel(){//与主窗口大小保持一致(去掉菜单高度)this.setSize(400,440);//获得焦点(没焦点就不能截获键盘监听)this.setFocusable(true);//键盘监听this.addKeyListener(this);//游戏逻辑this.gameLogic = new GameLogic();//初始化游戏this.initGame();//定时器timer = new Timer(500,this);timer.start();}/*** 功能:初始化游戏<br>*/private void initGame(){//初始化游戏逻辑this.gameLogic.init();//得到地图this.map = this.gameLogic.getMap();//重画地图this.repaint();}/*** 功能:绘图<br>* 备注:给我地图剩下的你就不用管了。<br>*/@Overridepublic void paint(Graphics g){int blockSize = 20;		//默认方块大小int row = 0;int column = 0;//调用父类,让其做一些事前的工作,如刷新屏幕等super.paint(g);//画大地图中已经固定的方块和围墙//==================地图==================//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 7, 7, 0, 0, 0, 0, 0, 0, -1},	//{-1, 0, 0, 7, 7, 0, 0, 1, 1, 1, 1, -1},	//{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1}	//==================结束==================row = this.map.length;column = this.map[0].length;for(int i=0;i<row;i++){for(int j=0;j<column;j++){if(this.map[i][j] == -1)	//墙{g.setColor(Color.GRAY);g.fillRect(j * blockSize,i * blockSize,blockSize,blockSize);g.setColor(Color.WHITE);g.drawRect(j * blockSize,i * blockSize,blockSize,blockSize);}else if(this.map[i][j] > 0)	//方块{switch(this.map[i][j]){case 1:g.setColor(Color.RED);break;case 2:g.setColor(Color.ORANGE);break;case 3:g.setColor(Color.YELLOW);break;case 4:g.setColor(Color.GREEN);break;case 5:g.setColor(Color.BLUE);break;case 6:g.setColor(Color.PINK);break;case 7:g.setColor(Color.MAGENTA);break;}g.fillRect(j * blockSize,i * blockSize,blockSize,blockSize);g.setColor(Color.WHITE);g.drawRect(j * blockSize,i * blockSize,blockSize,blockSize);}}}//画当前方块byte[][] curShape = this.gameLogic.getShape();row = curShape.length;column = curShape[0].length;for(int i=0;i<row;i++){for(int j=0;j<column;j++){if(curShape[i][j] > 0)	//方块{switch(curShape[i][j]){case 1:g.setColor(Color.RED);break;case 2:g.setColor(Color.ORANGE);break;case 3:g.setColor(Color.YELLOW);break;case 4:g.setColor(Color.GREEN);break;case 5:g.setColor(Color.BLUE);break;case 6:g.setColor(Color.PINK);break;case 7:g.setColor(Color.MAGENTA);break;}g.fillRect((j + this.gameLogic.getShapeColumn()) * blockSize,(i + this.gameLogic.getShapeRow()) * blockSize,blockSize,blockSize);g.setColor(Color.WHITE);g.drawRect((j + this.gameLogic.getShapeColumn()) * blockSize,(i + this.gameLogic.getShapeRow()) * blockSize,blockSize,blockSize);}}}//画记分牌g.setColor(Color.BLACK);g.setFont(new Font("宋体",Font.PLAIN,12));g.drawString("当前分数: " + this.gameLogic.getScore(),this.map[0].length * blockSize + 20,30);//画下一个方块g.drawString("下一个方块是:",this.map.length * blockSize + 20,60);byte[][] nextShape = this.gameLogic.getNextShape();row = nextShape.length;column = nextShape[0].length;for(int i=0;i<row;i++){for(int j=0;j<column;j++){if(nextShape[i][j] > 0){switch(nextShape[i][j]){case 1:g.setColor(Color.RED);break;case 2:g.setColor(Color.ORANGE);break;case 3:g.setColor(Color.YELLOW);break;case 4:g.setColor(Color.GREEN);break;case 5:g.setColor(Color.BLUE);break;case 6:g.setColor(Color.PINK);break;case 7:g.setColor(Color.MAGENTA);break;}g.fillRect(this.map[0].length * blockSize + 36 + j * blockSize,100 + i * blockSize,blockSize,blockSize);g.setColor(Color.WHITE);g.drawRect(this.map[0].length * blockSize + 36 + j * blockSize,100 + i * blockSize,blockSize,blockSize);}}}}/*** 功能:方块移动<br>*/private void move(int keyCode){if(!this.isAcceptKey){return;}//开始移动if(!this.gameLogic.move(keyCode)){return;}//得到移动后的新地图this.map = this.gameLogic.getMap();//重绘界面this.repaint();//判断是否Gave Overif(this.gameLogic.gameOver()){//屏蔽键盘信息this.isAcceptKey = false;return;}}/*** 功能:开始新游戏<br>*/public void newGame(){this.isAcceptKey = true;this.initGame();timer.start();}/*** 功能:暂停游戏<br>*/public void pauseGame(){this.isAcceptKey = false;timer.stop();}/*** 功能:继续游戏<br>*/public void continueGame(){this.isAcceptKey = true;timer.start();}/*** 功能:键盘监听<br>*/@Overridepublic void keyPressed(KeyEvent e){int keyCode = e.getKeyCode();if(keyCode == KeyEvent.VK_UP || keyCode == KeyEvent.VK_DOWN || keyCode == KeyEvent.VK_LEFT || keyCode == KeyEvent.VK_RIGHT){this.move(keyCode);}}@Overridepublic void keyTyped(KeyEvent e){}@Overridepublic void keyReleased(KeyEvent e){}/*** 功能:事件监听<br>*/@Overridepublic void actionPerformed(ActionEvent e) {if(e.getSource() == this.timer)		//定时器{this.move(KeyEvent.VK_DOWN);}}}

4、GameLogic.java 游戏逻辑类。

package com.game.tetris;import java.awt.event.KeyEvent;
import javax.swing.JOptionPane;/*** 功能:游戏逻辑<br>* 作者:我是小木鱼(Lag)<br>*/
public class GameLogic
{/** 大地图(共21行12列,该地图包含墙和后加入固定死的方块信息) */private byte[][] map;/** 方块类型(共7种) */private int blockType = 0;/** 方块状态(共4种) */private int turnState = 0;/** 当前方块图形(1-长条形方块,2-Z形方块,3-倒Z字形方块,4-J形方块,5-L字形,6-T字形方块,7-田字形方块) */private byte[][] shape;/** 当前方块图形(4×4矩阵)左上角所在行 */private int shapeRow;/** 当前方块图形(4×4矩阵)左上角所在列 */private int shapeColumn;/** 下一个方块类型 */private int nextBlockType = -1;/** 下一个方块状态 */private int nextTurnState = -1;/** 下一个方块图形 */private byte[][] nextShape;/** 得分 */private int score = 0;/*** 功能:构造函数<br>*/public GameLogic(){}/*** 功能:初始化<br>*/public void init(){//得到大地图this.map = GameMap.getMap();//随机生成新方块this.newBlock();}/*** 功能:随机生成新方块<br>*/private void newBlock(){//如果当前没有下一方块(即游戏刚开局,还未生成当前方块和下一方块)if(this.nextBlockType == -1 && this.nextTurnState == -1){this.blockType = (int)(Math.random() * 7);		//随机生成7种形状中的一种this.turnState = (int)(Math.random() * 4);		//随机生成4种旋转中的一种this.nextBlockType = (int)(Math.random() * 7);this.nextTurnState = (int)(Math.random() * 4);}else{this.blockType = this.nextBlockType;this.turnState = this.nextTurnState;this.nextBlockType = (int)(Math.random() * 7);this.nextTurnState = (int)(Math.random() * 4);}//获得当前方块,并设置初始位置(方块(4×4矩阵)最左上角方格初始行列位置即最顶端水平居中)this.shape = GameMap.getShape(this.blockType,this.turnState);this.shapeRow = 0;this.shapeColumn = 5;//获得下一个方块this.nextShape = GameMap.getShape(this.nextBlockType,this.nextTurnState);}/*** 功能:将方块信息添加到地图数组信息中<br>* 备注:方块信息是已经固定死了的<br>*/private void add(){//添加当前方块位置状态int rowCount = this.shape.length;int columnCount = this.shape[0].length;for(int i=this.shapeRow;i<this.shapeRow+rowCount;i++){for(int j=this.shapeColumn;j<this.shapeColumn+columnCount;j++){if(this.shape[i - this.shapeRow][j - this.shapeColumn] > 0){this.map[i][j] = this.shape[i - this.shapeRow][j - this.shapeColumn];}}}}/*** 功能:销毁满行的部分<br>* 原理:一行一行对地图信息进行扫描,如果一行的每个元素值均大于0,说明满行,销毁该行,该行上面的方块依次下落一行。<br>*/private void deleteLine(){int count = 0;int mapRowCount = this.map.length;int mapColumnCount = this.map[0].length;for(int i=0;i<mapRowCount - 1;i++)		//20行{for(int j=1;j<mapColumnCount - 1;j++)	//10列{if(this.map[i][j] > 0){count++;if(count == (mapColumnCount - 2))	//满行了,可以销毁该行{for(int m=i;m>0;m--)			//从当前行往回计算{for(int n=1;n<mapColumnCount - 1;n++){this.map[m][n] = this.map[m-1][n];}}this.score += 10;}}}count = 0;	//开始下一行计数}}/*** 功能:判断当前方块的位置是否合法<br>* 参数:_row -> 图形左上角所在行 <br>* 参数:_column -> 图形左上角所在列 <br>* 参数:_shape -> 移动变化的图形 <br>* 返回:0-不合法(可能与围墙或其他固定的方块位置重叠),1-合法<br>*/private int blow(int _row,int _column,byte[][] _shape){int rowCount = _shape.length;int columnCount = _shape[0].length;//方块所在的行列与墙或其他方块的行列都大于0或-1for(int i=0;i<rowCount;i++){for(int j=0;j<columnCount;j++){if(_shape[i][j] > 0)	//对该图形进行循环,找出大于零的数,即是方块{//判断墙if(this.map[_row + i][_column + j] == -1){return 0;}//判断固定方块if(this.map[_row + i][_column + j] > 0){return 0;}}}}return 1;}/*** 功能:方块移动<br>* 返回:true -> 可以移动旋转,需要刷新地图,false ->不可以,也不需要刷新地图<br>*/public boolean move(int keyCode){if(keyCode == KeyEvent.VK_UP)			//向上旋转{//得到逆时针要变的旋转变形int tempTurnState = (this.turnState + 1) % this.shape.length;byte[][] turnShape = GameMap.getShape(this.blockType,tempTurnState);if(blow(this.shapeRow,this.shapeColumn,turnShape) == 1){this.shape = turnShape;this.turnState = tempTurnState;}else{return false;}}else if(keyCode == KeyEvent.VK_DOWN)		//向下移动{if(blow(this.shapeRow + 1,this.shapeColumn,this.shape) == 1){this.shapeRow++;}else{this.add();this.deleteLine();this.newBlock();}}else if(keyCode == KeyEvent.VK_LEFT)		//向左移动{if(blow(this.shapeRow,this.shapeColumn - 1,this.shape) == 1)	//可以向左移{this.shapeColumn--;}else{return false;}}else if(keyCode == KeyEvent.VK_RIGHT)		//向右移动{if(blow(this.shapeRow,this.shapeColumn + 1,this.shape) == 1)	//可以向右移{this.shapeColumn++;}else{return false;}}return true;}/*** 功能:判断游戏是否结束<br>* 参数:true -> 已结束<br>* 参数:false -> 未结束<br>*/public boolean gameOver(){if(blow(this.shapeRow,this.shapeColumn,this.shape) == 0)	//如果碰到围墙或固定方块,游戏结束。{this.score = 0;JOptionPane.showMessageDialog(null,"大虾,请重新来过吧!","提示",JOptionPane.ERROR_MESSAGE);return true;}else{return false;}}/*** 功能:返回大地图(共21行12列,该地图包含墙和固定死的方块信息)<br>*/public byte[][] getMap(){return map;}/*** 功能:返回当前方块图形<br>*/public byte[][] getShape(){return shape;}/*** 功能:返回当前方块图形(4×4矩阵)左上角所在行<br>*/public int getShapeRow(){return shapeRow;}/*** 功能:返回当前方块图形(4×4矩阵)左上角所在列<br>*/public int getShapeColumn() {return shapeColumn;}/*** 功能:返回下一个随机方块<br>*/public byte[][] getNextShape(){return nextShape;}/*** 功能:返回分数 <br>*/public int getScore() {return score;}}

5、GameMap.java 游戏地图类。

package com.game.tetris;/*** 功能:游戏地图<br>* 作者:我是小木鱼(Lag)<br>*/
public class GameMap 
{/** 游戏大地图(存储方块[1~7]和围墙[-1]及空块[0]的信息,共21行12列252个小方格) */private static byte[][] map = {{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1},	{-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1, -1}	};/** 方块图形(存储七种形状及其四种旋转变形<逆时针旋转90度>,每种旋转变形用包含4×4的数组表示具体图形<盯住大于零的数字猛看,就能看到图形了>) */private static byte shape[][][][] = new byte[][][][]{//长条形方块{//旋转变形一{{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}}},//Z形方块{//旋转变形一{{2, 2, 0, 0},{0, 2, 2, 0},{0, 0, 0, 0},{0, 0, 0, 0}},//旋转变形二{{0, 2, 0, 0},{2, 2, 0, 0},{2, 0, 0, 0},{0, 0, 0, 0}},//旋转变形三{{2, 2, 0, 0},{0, 2, 2, 0},{0, 0, 0, 0},{0, 0, 0, 0}},//旋转变形四{{0, 2, 0, 0},{2, 2, 0, 0},{2, 0, 0, 0},{0, 0, 0, 0}}},//倒Z字形方块{//旋转变形一{{0, 3, 3, 0},{3, 3, 0, 0},{0, 0, 0, 0},{0, 0, 0, 0}},//旋转变形二{{3, 0, 0, 0},{3, 3, 0, 0},{0, 3, 0, 0},{0, 0, 0, 0}},//旋转变形三{{0, 3, 3, 0},{3, 3, 0, 0},{0, 0, 0, 0},{0, 0, 0, 0}},//旋转变形四{{3, 0, 0, 0},{3, 3, 0, 0},{0, 3, 0, 0},{0, 0, 0, 0}}},//J形方块{//旋转变形一{{0, 4, 0, 0},{0, 4, 0, 0},{4, 4, 0, 0},{0, 0, 0, 0}},//旋转变形二{{4, 4, 4, 0},{0, 0, 4, 0},{0, 0, 0, 0},{0, 0, 0, 0}},//旋转变形三{{4, 4, 0, 0},{4, 0, 0, 0},{4, 0, 0, 0},{0, 0, 0, 0}},//旋转变形四{{4, 0, 0, 0},{4, 4, 4, 0},{0, 0, 0, 0},{0, 0, 0, 0}}},//L字形{//旋转变形一{{5, 0, 0, 0},{5, 0, 0, 0},{5, 5, 0, 0},{0, 0, 0, 0}},//旋转变形二{{0, 0, 5, 0},{5, 5, 5, 0},{0, 0, 0, 0},{0, 0, 0, 0}},//旋转变形三{{5, 5, 0, 0},{0, 5, 0, 0},{0, 5, 0, 0},{0, 0, 0, 0}},//旋转变形四{{5, 5, 5, 0},{5, 0, 0, 0},{0, 0, 0, 0},{0, 0, 0, 0}}},//T字形方块{//旋转变形一{{0, 6, 0, 0},{6, 6, 6, 0},{0, 0, 0, 0},{0, 0, 0, 0}},//旋转变形二{{0, 6, 0, 0},{6, 6, 0, 0},{0, 6, 0, 0},{0, 0, 0, 0}},//旋转变形三{{6, 6, 6, 0},{0, 6, 0, 0},{0, 0, 0, 0},{0, 0, 0, 0}},//旋转变形四{{6, 0, 0, 0},{6, 6, 0, 0},{6, 0, 0, 0},{0, 0, 0, 0}}},//田字形方块{//旋转变形一{{7, 7, 0, 0},{7, 7, 0, 0},{0, 0, 0, 0},{0, 0, 0, 0}},//旋转变形二{{7, 7, 0, 0},{7, 7, 0, 0},{0, 0, 0, 0},{0, 0, 0, 0}},//旋转变形三{{7, 7, 0, 0},{7, 7, 0, 0},{0, 0, 0, 0},{0, 0, 0, 0}},//旋转变形四{{7, 7, 0, 0},{7, 7, 0, 0},{0, 0, 0, 0},{0, 0, 0, 0}}}};/*** 功能:返回大地图<br>* 备注:由于原始地图数据不允许修改,因此只返回复制后的地图赝品<br>*/public static byte[][] getMap(){//由于数组是个对象,而原始地图是不允许被修改的,所以不能直接赋值(引用地址),得复制一个新的地图让游戏随便修改。int row = map.length;int column = map[0].length;byte[][] copyMap = new byte[row][column];for(int i=0;i<row;i++){for(int j=0;j<column;j++){copyMap[i][j] = map[i][j];}}return copyMap;}/*** 功能:返回方块图形<br>* 参数:int _blockType -> 方块类型<br>* 参数:int _turnState -> 旋转状态<br>* 备注:由于原始方块图形数据不允许修改,因此只返回复制后的方块图形赝品<br>*/public static byte[][] getShape(int _blockType,int _turnState){byte[][] temp = shape[_blockType][_turnState];//开始复制int row = temp.length;int column = temp[0].length;byte[][] shapeMap = new byte[row][column];for(int i=0;i<row;i++){for(int j=0;j<column;j++){shapeMap[i][j] = temp[i][j];}}return shapeMap;}}

详解: 

待续...

运行: 

        做一个DOS批处理文件,tetris.bat,内容如下:

@echo off
start javaw com.game.tetris.Tetris

  下载: 

        百度网盘链接:https://pan.baidu.com/s/1g1h9Zn1KmIoMWCMGLV1nCA 提取码:h5m2

感言: 


http://chatgpt.dhexx.cn/article/jOKstXpZ.shtml

相关文章

Java俄罗斯方块,老程序员花了一个周末,连接中学年代!

Java俄罗斯方块&#xff0c;老程序员花了一个周末&#xff0c;连接中学年代&#xff01; 热门专栏推荐 【1】Java小游戏&#xff08;俄罗斯方块、飞机大战、植物大战僵尸等&#xff09; 【2】JavaWeb项目实战&#xff08;图书管理、在线考试、宿舍管理等&#xff09; 【3】Jav…

软件设计实战:基于Java的俄罗斯方块游戏【完整版】

个人简介 &#x1f468;&#x1f3fb;‍&#x1f4bb;个人主页&#xff1a;陈橘又青 &#x1f3c3;&#x1f3fb;‍♂️博客记录心情&#xff0c;代码编写人生。 &#x1f31f;如果文章对你有用&#xff0c;麻烦关注点赞收藏走一波&#xff0c;感谢支持&#xff01; &#x1f3…

Java实现游戏开发《俄罗斯方块》

一、用Java实现俄罗斯方块游戏&#xff1a; 1、效果图&#xff0c;如下图所示&#xff1a; 7种形态的第一种形态, 如下所示&#xff1a;分布是 &#xff1a;|、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…

俄罗斯方块游戏的设计与实现(Java+Swing+Eclipse)

目录 基于Java的俄罗斯方块游戏的设计与实现 I 摘 要 I Based on the design and implementation of Java game Tetris II Abstract II 1 绪论 1 1.1程序开发背景及意义 1 1.2开发技术概述 2 1.3俄罗斯方块游戏的研究现状 2 1.3.1 国内外研究现状 2 1.3.2 文献综述 3 2相关技术…

【Java小游戏】俄罗斯方块

文章目录 规则准备工作编写小方块类编写四方格父类创建7种不同的形状编写俄罗斯方块主类初始化7种形状 随机生成四方格创建游戏场景绘制游戏绘制游戏背景绘制游戏主区域绘制正在下落的四方格绘制下一个下落的四方格绘制游戏得分绘制游戏状态 编写游戏逻辑判断方块是否出界判断方…

Java实现俄罗斯方块小游戏。(附完整源代码)

大家好&#xff0c;我是百思不得小赵。 创作时间&#xff1a;2022 年 5 月 12 日 博客主页&#xff1a; &#x1f50d;点此进入博客主页 —— 新时代的农民工 &#x1f64a; —— 换一种思维逻辑去看待这个世界 &#x1f440; 今天是加入CSDN的第1167天。觉得有帮助麻烦&#x…

Java实现俄罗斯方块游戏(简单版)

游戏页面效果如下&#xff1a; 俄罗斯方块游戏本身的逻辑&#xff1a; 俄罗斯方块游戏的逻辑是比较简单的。它就类似于堆砌房子一样&#xff0c;各种各样的方地形状是不同的。但是&#xff0c;俄罗斯方块游戏的界面被等均的分为若干行和若干列&#xff0c;因此方块的本质就是占…

vs2019功能介绍_MFC界面库BCGControlBar v30.0新功能详解:支持VS 2019

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v30.0正式发布&#xff01;新版本添加了对Visual Studio 2019的支持等。接下来几篇文章将对这个版本的新功能一一进行介绍&#xff0c;让您对BCG这个控件有一个全新的认…

MFC界面库BCGControlBar v32.0 - 网格、报表控件升级

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v32.0正式发布&#xff01;新版本支持Windows 11、增强功能区简化模式、改进控件外观等&#xff0c;以及其他新功能和改进。需要最新版的可以点击这里【BCG下载】 BCGC…

MFC扩展库BCGControlBar :网格和报告控件

BCGControlBar ("Business Components Gallery ControlBar")是MFC扩展库&#xff0c;使您可以创建具有完全自定义选项&#xff08;功能区、可自定义工具栏、菜单等&#xff09;以及一组专业设计的丰富Microsoft Office和Microsoft Visual Studio的应用程序 GUI控件&a…

MFC界面库之BCGControlers使用

觉得默认的MFC实在是太丑了,想要用一下扩展的界面库.网上查了些资料.不过在这里我还是小结一下使用的过程吧! 1.当然是安装文件了,在上一步不用多勾选,直接按照默认的就可以了...但是要注意一定要以管理员身份运行BCGCBProBuildWizard.exe否则没有办法通过...... 2.配置lib文件…

MFC界面控件BCGControlBar v33.3 - 编辑控件功能升级

BCGControlBar库拥有500多个经过全面设计、测试和充分记录的MFC扩展类。 我们的组件可以轻松地集成到您的应用程序中&#xff0c;并为您节省数百个开发和调试时间。 BCGControlBar专业版和BCGSuite for MFC v33.3已正式发布了&#xff0c;该版本包含了增强的Ribbon自定义、新的…

MFC界面美化

排列整齐 基于MFC编写GUI代码时&#xff0c;界面美化最基本的部分就是排列整齐&#xff0c;如果是用Visual Studio 2015 IDE 开发&#xff0c;那就十分方便了&#xff0c;在快捷功能框即有相关按钮&#xff0c;这和Qt的控件调整有些类似&#xff0c;可以有效减少我们在布局上耗…

MFC界面库BCGControlBar v30.0新功能详解:支持VS 2019

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v30.0正式发布&#xff01;新版本添加了对Visual Studio 2019的支持等。接下来几篇文章将对这个版本的新功能一一进行介绍&#xff0c;让您对BCG这个控件有一个全新的认…

VS2017 MFC使用Skin++界面库实例(最简单的方法为自己的MFC程序换肤)

MFC的界面太丑了&#xff0c;又不想学界面设计&#xff0c;找了好多资源&#xff0c;要么各种各样的错误对于我这样的小白来说很难解决&#xff0c;要么就是使用起来太复杂&#xff0c;暂时也没有太多时间去研究&#xff0c;后来终于找到了VS2017也能用&#xff0c;简单方便的S…

MFC界面库BCGControlBar v33.0 - 全新升级Ribbon Bar、工具栏等

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v33.0正式发布&#xff01;此版本包括对每个显示器 DPI 感知的支持、改进的信息框和桌面警报控件、主题编辑框气球工具提示和其他新功能和改进。需要最新版的可以点击这…

MFC界面库BCGControlBar的介绍

英文原文&#xff1a; http://www.bcgsoft.com/bcgcontrolbarpro.htm BCGControlBar是MFC的一个扩展库其英文全称是"Business Components Gallery ControlBar"&#xff0c;它允许你去创建像完全自定义的像Microsoft Office 2000/XP/2003/2007/2010/2013 and Visua…

MFC界面库BCGControlBar v32.2 - Ribbon Bar功能增强

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v32.2正式发布&#xff01;新版本改进的功能区和框架标题命令搜索、带有可选复选框的网格日期选择器、带有标签的功能区滑块等&#xff0c;需要最新版的可以点击这里【B…

MFC界面库BCGControlBar v32.0 - 支持Windows 11

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v32.0正式发布&#xff01;新版本支持Windows 11、增强功能区简化模式、改进控件外观等&#xff0c;以及其他新功能和改进。需要最新版的可以点击这里【BCG下载】 BCGC…

MFC界面库BCGControlBar v33.0 - Docking Pane、仪表盘组件升级

亲爱的BCGSoft用户&#xff0c;我们非常高兴地宣布BCGControlBar Professional for MFC和BCGSuite for MFC v33.0正式发布&#xff01;此版本包括对每个显示器 DPI 感知的支持、改进的信息框和桌面警报控件、主题编辑框气球工具提示和其他新功能和改进。需要最新版的可以点击这…