【无标题】

俄罗斯方块(java)

1、俄罗斯方块简介
俄罗斯方块》(Tetris, 俄文:Тетрис)是一款由俄罗斯人阿列克谢·帕基特诺夫于1984年6月发明的
休闲游戏。
该游戏曾经被多家公司代理过。经过多轮诉讼后,该游戏的代理权最终被任天堂获得。 [1] 任天堂对于
俄罗斯方块来说意义重大,因为将它与GB搭配在一起后,获得了巨大的成功。 [1]
《俄罗斯方块》的基本规则是移动、旋转和摆放游戏自动输出的各种方块,使之排列成完整的一行或多
行并且消除得分。

上图是游戏制作过程中我截的一张图片,从上图中,我们可以把游戏分为多个区域:
1)左侧主游戏界面区域;
2)右侧游戏信息区域。
其中,主游戏区域主要就是我们进行游戏操作的地方;右侧游戏信息区域,可以设置下一个要下落的方
块,对应关卡,对应分数,以及游戏时长等等(都可以自行定义)。
根据俄罗斯方块的规则,我们知道,一个四格方块,是可以左右和往下移动的,并且还能变换形状。
然后我们在来看一张图片:
在这里插入图片描述

从上图我们可以看出来,每个方块都由四个小方格通过不同的排列组成,并且,我们可以把游戏主场景
区想象成用二维数组来表示的区域,事实上,确实是用二维数组来制作游戏主区域。
在这里,我们暂且把这个区域称为------墙(Wall)
把每个小方格称为------单元格(Cell)
每个不同的形状其实就是4个单元格按不同顺序组合而来,所以,我们可以用不同的坐标来表示不同的
形状。
我们可以根据四格方块的不同形状,给他们一个名字:I,T,L,J,S,Z,O
所以,在这里我们用面向对象的思想,分别定义Cell类,和七个四格方块类。

JavaBean实现
单元格类

根据java面向对象思想,以及前面分析的结果,最基本单元格作为一个单元格类,有行、列、背景图
片,以及左移、右移、下移方法。

import java.awt.image.BufferedImage;
/**
* 单元格类
*/
public class Cell {
// 属性
private int row; // 行 0,
private int col; // 列 0
private BufferedImage image; // 背景图片 null
public Cell() {
}
public Cell(int row, int col, BufferedImage image) {
this.row = row;
this.col = col;
this.image = image;
}
// 方法
/**
* 单元格左移一列
*/
public void left(){
col--;
}
/**
* 单元格右移一列
*/
public void right(){
col++;
}

/**
* 单元格下移一行
* */
public void drop(){
row++;
}
// 普通属性的get、set方法
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public int getCol() {
return col;
}
public void setCol(int col) {
this.col = col;
}
public BufferedImage getImage() {
return image;
}

public void setImage(BufferedImage image) {
this.image = image;
	}
}

//方块类
import java.util.Random;
public class TetrisModel {
// 单元格数组,存放4个单元格,组成俄罗斯方块
public Cell[] cells =new Cell[4];
/**
* 方块左移
*/
public void moveLeft(){
for (Cell cell : cells) {
cell.left();
	}
}
/**
* 方块右移
*/
public void moveRight(){
for (Cell cell : cells) {
cell.right();
	}
}
/**
* 方块下移
*/
public void moveDrop(){
for (Cell cell : cells) {
cell.drop();
	}
}
/**
* 方块旋转
*/
public void moveRote(){
// TODO 后续实现方块旋转逻辑
	}
}

方块类随机生成

外,在方块类TetrisModel中,需要定制一个随机生成方块类的方法。该方法使用多态的方式实现,
因为可能随机生成任意7种之一的方块,所以结合switch控制语句,返回不同类型的方块。
因此,在TetrisModel中添加一个静态方法,生成随机方块类对象。

/**
* 随机生成方块对象
* @return
*/
		public static TetrisModel randomOne() {
		TetrisModel t =new TetrisModel();
		Random random = new Random();
		int num = random.nextInt(7); // [0,6]
			switch (num) {
				case 0:
				t = new I();
				break;
				case 1:
				t = new J();
				break;
				case 2:
				t = new L();
				break;
				case 3:
				t= new O();
				break;
				case 4:
				t = new S();
				break;
				case 5:
				t = new T();
				break;
				case 6:
				t = new Z();
				break;
			}
// 返回随机生成的俄罗斯方块对象
		return t;
	}
	//I方块对象
	
/**
* I形俄罗斯方块
*/
public class I extends TetrisModel{
/**
* 对默认构造方法进行改造,进行属性变量的初始化
* 初始化方块中每一个单元格的位置,还有背景图片
*/
public I(){
//把数组的一个单元格作为后续选择的中心轴
cells[0]=new Cell(0,4, SourceUtil.iImage);
cells[1]=new Cell(0,3,SourceUtil.iImage);
cells[2]=new Cell(0,5,SourceUtil.iImage);
cells[3]=new Cell(0,6,SourceUtil.iImage);
		}
	}	

静态工具类
在这里插入图片描述

		import javax.imageio.ImageIO;
		import java.awt.image.BufferedImage;
		import java.io.IOException;
		/**
		* 静态资源加载工具类
		*/
		public class SourceUtil {
		/**
		* 静态图片资源
		*/
		public static BufferedImage iImage;
		public static BufferedImage jImage;
		public static BufferedImage lImage;
		public static BufferedImage oImage;
		public static BufferedImage sImage;
		public static BufferedImage tImage;
		public static BufferedImage zImage;
		public static BufferedImage backgroundImage;
		public static BufferedImage tetrisLogoImage;
		/**
		* 静态代码块,加载一次静态资源
		*/
		static {
		/**
		* ImageIO.read()方法可以读取项目下的静态资源文件
		*/
			try {
			iImage =
			ImageIO.read(SourceUtil.class.getResource("../image/I.png"));
			jImage =ImageIO.read(SourceUtil.class.getResource("../image/J.png"));
			lImage =ImageIO.read(SourceUtil.class.getResource("../image/L.png"));
			oImage =ImageIO.read(SourceUtil.class.getResource("../image/O.png"));
			sImage =ImageIO.read(SourceUtil.class.getResource("../image/S.png"));
			tImage =ImageIO.read(SourceUtil.class.getResource("../image/T.png"));
			zImage =ImageIO.read(SourceUtil.class.getResource("../image/Z.png"));
			backgroundImage =
			ImageIO.read(SourceUtil.class.getResource("../image/background.png"));
			tetrisLogoImage =
			ImageIO.read(SourceUtil.class.getResource("../image/tetrisLogo.png"));
			} catch (IOException e) {
			e.printStackTrace();
					}
				}
			}
游戏启动类
			import javax.imageio.ImageIO;
			import javax.swing.*;
			import java.awt.image.BufferedImage;
			import java.io.IOException;
			/**
			* 俄罗斯方块游戏入口
			*/
			public class TetrisMain {
			public static void main(String[] args) throws IOException {
			// 1、游戏窗口界面设置
			// 创建游戏窗口界面
			JFrame jFrame = new JFrame("经典俄罗斯方块");
			// 游戏窗口加入游戏画布
			TetrisPanel tetrisPanel = new TetrisPanel();
			jFrame.add(tetrisPanel);
			// 读取并设置游戏窗口左侧logo图标
			BufferedImage logoImage =
			ImageIO.read(TetrisMain.class.getResource("../image/tetrisLogo.png"));
			jFrame.setIconImage(logoImage);
			// 设置游戏窗口大小
			jFrame.setSize(535, 595);
			// 设置游戏窗口居中显示
		jFrame.setLocationRelativeTo(null);
		// 设置关闭窗口会默认退出程序
		jFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 
		jFrame.setResizable(false); // 设置窗口尺寸不可拉伸改变
		jFrame.setVisible(true); // 设置窗口显示可见
		// 2、游戏功能启动
		tetrisPanel.start();
			}
		}

游戏主面板区域

			import com.hopu.domain.Cell;
			import com.hopu.domain.TetrisModel;
			import com.hopu.util.SourceUtil;
			import javax.swing.*;
			import java.awt.*;
			/**
			* 整个游戏区域的面板画布类
			*/
			public class TetrisPanel extends JPanel {
			// 设置20行,10列的墙体表格数组
			public Cell[][] wall =new Cell[20][10];
			// 设置单元格对象的固定宽高
			public static final int CELL_SIZE=26;
			// 当前正在下落的方块
			public TetrisModel currentOne = TetrisModel.randomOne();
			// 下一个准备下落的方块
			public TetrisModel nextOne = TetrisModel.randomOne();
			/**
			* 重写父类画图方法
			* @param g 代表画笔
			*/
			@Override
			public void paint(Graphics g) {
			// 绘制游戏区域背景图
			g.drawImage(SourceUtil.backgroundImage,0,0,null);
			// 后面墙体右下方法稍微偏移一点
			g.translate(15,15);
			// 绘制主游戏区域的背景墙格子
			paintWall(g);
			// 绘制下一个要下落的方块
			paintCurrentOne(g);
			// 绘制当前下落的方块
			paintNextOne(g);
			}
			/**
			* 绘制当前下落的方块
			* @param g
			*/
			private void paintNextOne(Graphics g) {
			Cell[] cells = nextOne.cells;
			for (Cell cell : cells) {
			int x = cell.getCol() * CELL_SIZE +265;
			int y = cell.getRow() * CELL_SIZE +25;
			// 在对应位置绘制单元格对象
			g.drawImage(cell.getImage(),x,y,null);
				}
			}
			```/**
			* 绘制当前下落的方块
			*/
			private void paintCurrentOne(Graphics g) {
			// 获取到当前方块的每一个单元格数组对象
			Cell[] cells = currentOne.cells;
			for (Cell cell : cells) {
			int x = cell.getCol() * CELL_SIZE;
			int y = cell.getRow() * CELL_SIZE;
			// 在对应位置绘制单元格对象
			g.drawImage(cell.getImage(),x,y,null);
				}
			}
						/**
			* 自定义一个私有的绘制墙体格子方法
			* 本质:在背景下绘制20行,10列的单元格对象,然后对其中每一个单元格对象进行定位和图片
			* @param g
			*/
			private void paintWall(Graphics g) {
			// 外层循环循环行
			for (int i = 0; i < 20; i++) {
			// 内层循环循环列
			for (int j = 0; j < 10; j++) {
			// 通过行列索引,获取每一个单元格对象
			Cell cell = wall[i][j];
			// 开始初始化单元格对象
			// drawRect()方法可以绘制矩形
			int x = j*CELL_SIZE;
			int y = i*CELL_SIZE;
			if(cell ==null){
			g.drawRect(x,y,CELL_SIZE,CELL_SIZE);
			}else {
			// 代表当前单元格已经被其他形状的俄罗斯方块占用
			g.drawImage(cell.getImage(),x,y,null);
						}
		     		}
	     		}
			}
      }
	

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值