俄罗斯方块笔记

匿名 (未验证) 提交于 2019-12-03 00:21:02

一.通过分析游戏界面,抽象出几种类型:

1.Cell(格子类)

2.Tetromino(四格方块类):七种组合的父类

根据父类,定义七种子类:T、I、O、J、L、S、Z

提供静态属性,加载静态资源


Cell

属性:row(行号),col(列号),Image(图片)


Tetromino

方法:

Tetris

方法:paint(Graphics g);//绘制方法

//绘制墙

piantCurrentOne(g);//绘制正在下落的四格方块

//绘制下一个四格方块


将七个子类封装到Tetromino,初始化四格方块的初始位置

以“L”型为例

初始位置:cell[0]=(0,4);




二.类的实现:

cell类:

package com.tetris;  import java.awt.image.BufferedImage; /*俄罗斯方块的最小单位:方格  * 特征(属性):  * row--行号  * col--列号  * image--对应的图片  *   * 行为(方法):  * left()  * right()  * down()  */ public class Cell { 	private int row; 	private int col; 	private BufferedImage image; 	public Cell () {} 	public Cell(int row, int col, BufferedImage image) { 		super(); 		this.row = row; 		this.col = col; 		this.image = image; 	} 	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; 	} 	@Override 	public String toString() { 		return "("+ row + ","+ col + ")"; 	} 	/**向左移动*/     public void left() {     	col--; 	}     /**向右移动*/     public void right() {     	col++;     }     /**向下移动*/     public void drop() {     	row++;     }

Tetromino类:

package com.tetris;  import java.util.Arrays;  /*  * 四格方块  * 属性:  * ------cells----四个方块  * 行为:  *      moveLeft()  *      moveRight()  *      softDrop()  */ public class Tetromino { 	protected Cell[] cells=new Cell[4]; 	public void moveLeft() { 		for(int i=0;i<cells.length;i++) { 			Cell cell=cells[i]; 			cell.left(); 		} 	} 	public void moveRight() { 		for(Cell c:cells) { 			c.right(); 			} 		} 	public void softDrop() { 			for(Cell c:cells) { 				c.drop(); 				} 		} 	@Override 	public String toString() { 		return "["+ Arrays.toString(cells) + "]"; 	} 	/**随机生成一个四格方块*/ 	public static Tetromino randomOne() { 		Tetromino t=null; 		int num=(int)(Math.random()*7); 		switch(num) { 		case 0:t=new T();break; 		case 1:t=new O();break; 		case 2:t=new I();break; 		case 3:t=new J();break; 		case 4:t=new L();break; 		case 5:t=new S();break; 		case 6:t=new Z();break; 		} 		return t; 		 	} 	 	 	 }

Tetris类:

        /**属性:正在下落的四格方块*/ 	private Tetromino currentOne=Tetromino.randomOne(); 	/**属性:将要下落的四格方块*/ 	private Tetromino nextOne=Tetromino.randomOne(); 	/**属性:墙 20行10列的表格  宽度为26*/ 	private Cell[][] wall=new Cell[20][10];

三.绘制俄罗斯方块图形

加载静态资源:

private static final int CELL_SIZE=26;     public static  BufferedImage T; 	public static  BufferedImage I; 	public static  BufferedImage O; 	public static  BufferedImage L; 	public static  BufferedImage S; 	public static  BufferedImage Z; 	public static  BufferedImage J; 	public static  BufferedImage Background; 	static { 		try { 			/*getResource(String url) 			 * url:加载图片的路径 			 * 相对位置是同包下 			 */ 			T=ImageIO.read(Tetris.class.getResource("T.png")); 			O=ImageIO.read(Tetris.class.getResource("O.png")); 			I=ImageIO.read(Tetris.class.getResource("I.png")); 			J=ImageIO.read(Tetris.class.getResource("J.png")); 			S=ImageIO.read(Tetris.class.getResource("S.png")); 			L=ImageIO.read(Tetris.class.getResource("L.png")); 			Z=ImageIO.read(Tetris.class.getResource("Z.png")); 			Background=ImageIO.read(Tetris.class.getResource("tetris.png")); 		}catch(Exception e) { 			e.printStackTrace(); 		} 	}

生成游戏界面:

public void paint(Graphics g) { 		//绘制背景 		/* 		 * g:画笔 		 * g.drawImage(image,x,y,null) 		 * image:绘制的图片 		 * x:开始绘制的横坐标 		 * y:开始绘制的纵坐标 		 */ 		g.drawImage(Background, 0, 0, null); 		//平移坐标轴 		g.translate(15, 15); 		//绘制墙 		paintWall(g); 		//绘制正在下落的四格方块 		piantCurrentOne(g); 		//绘制下一个四格方块 		paintNextOne(g); 		 	} 	 	 	 	 	 	public void paintNextOne(Graphics g) { 		//获取NextOne对象的四个元素 		Cell[] cells=nextOne.cells; 		for(Cell c:cells) { 			//获取行号和列号 			int row=c.getRow(); 			int col=c.getCol(); 			//横坐标 			int x=col*CELL_SIZE+260; 			//纵坐标 			int y=row*CELL_SIZE+26; 			g.drawImage(c.getImage(),x,y,null); 		} 	} 	 	 	/**绘制正在下落的四格方块 	 * 取出数组的元素 	 * 绘制元素的图片 	 * 横坐标x: 	 * 纵坐标y: 	 * */ 	public void piantCurrentOne(Graphics g){ 		Cell[] cells=currentOne.cells; 		for(Cell c:cells) { 			int x=c.getCol()*CELL_SIZE; 			int y=c.getRow()*CELL_SIZE; 			g.drawImage(c.getImage(),x,y,null); 		} 	} 	/** 	 * 墙是20行10列的表格 	 * 是个二维数组 	 * 应该使用双层循环 	 * 绘制正方形 	 * */ 	public void paintWall(Graphics a) { 		//外层循环控制行数 		for(int i=0;i<20;i++) { 			//内层循环控制列数 			for(int j=0;j<10;j++) { 				int x=j*CELL_SIZE; 				int y=i*CELL_SIZE; 				Cell cell=wall[i][j]; 				if(cell==null) { 					a.drawRect(x, y, CELL_SIZE, CELL_SIZE); 				}else { 					a.drawImage(cell.getImage(),x,y,null); 				} 			} 		} 	}

添加动态效果和接收键盘指令并响应的能力:

public void start()  { 		//开启键盘监听事件 		KeyListener l=new KeyAdapter() { 			/** 			 * keyPressed()是键盘按钮按下去调用的方法 			 */ 			public void keyPressed(KeyEvent e) { 				//获取一下按键的代号 				int code=e.getKeyCode(); 				switch(code) { 				case KeyEvent.VK_DOWN: 					softDropAction();break; 				case KeyEvent.VK_LEFT: 					moveLeftAction();break; 				case KeyEvent.VK_RIGHT: 					moveRightAction();break; 				} 				repaint(); 			}  		}; 		//面板添加监听事件对象 		this.addKeyListener(l); 		//面板对象设置成焦点 		this.requestFocus(); 		 		while(true) {			 			try { 				/** 				 * 当程序运行到此,会进入睡眠状态 				 * 睡眠时间为300毫秒 				 * 300毫秒后,会自动执行后续代码 				 */ 				Thread.sleep(300); 			} catch (InterruptedException e) {				 				e.printStackTrace(); 			} 			 			if(canDrop()) { 				currentOne.softDrop(); 			}else { 				landToWall(); 				//将下一个下落的四格方块赋值给正在下落的变量 				currentOne=nextOne; 				nextOne=Tetromino.randomOne(); 			} 			/** 			 * 下落之后,进行重新绘制,才会看到下落后的方块 			 * repaint方法 也是JPanel类中提供的 			 * 此方法中调用了paint方法 			 */ 			repaint(); 		} 	} 		 	 //使用向下键控制向下的行为 	public void softDropAction() { 		if(canDrop()) { 			currentOne.softDrop(); 		}else { 			landToWall(); 			currentOne=nextOne; 			nextOne=Tetromino.randomOne(); 		} 	}  	 //使用LEFT控制向左的行为 	public void moveLeftAction() { 		currentOne.moveLeft(); 		if(outOfBounds()||coincide()) { 			currentOne.moveRight(); 		} 	} 	//使用向右键控制向右的行为 	protected void moveRightAction() { 		currentOne.moveRight(); 		if(outOfBounds()||coincide()) { 			currentOne.moveLeft(); 		} 	} 	 	 		private boolean coincide() { 			Cell[] cells=currentOne.cells; 			for(Cell c:cells) { 				int row=c.getRow(); 				int col=c.getCol(); 				if(wall[row][col]!=null) { 					return true; 				} 			} 		return false; 	} 		private boolean outOfBounds() { 			Cell[] cells=currentOne.cells; 			for(Cell c:cells) { 				int col=c.getCol(); 				if(col<0||col>9) { 					return true; 				} 			} 		return false; 	}  		public boolean canDrop() { 		Cell[] cells=currentOne.cells; 		for(Cell c:cells) { 			//获取每个元素的行号 			/** 			 * 判断: 			 * 只要有一个元素的下一行有方块 			 * 或只要有一个元素到底就不能下落 			 */ 			int row=c.getRow(); 			int col=c.getCol(); 			 			if(row==19) { 				return false; 			} 			if(wall[row+1][col]!=null) { 				return false; 			} 			 		} 		return true; 	} 	/** 	 * 当不能下落时,将四格方块嵌入到墙中 	 * 也就是储存到二维数组中相应的位置上 	 */ 	public void landToWall() { 		Cell[] cells=currentOne.cells; 		for(Cell c:cells) { 			//获取最终的行号和列号 			int row=c.getRow(); 			int col=c.getCol(); 			wall[row][col]=c; 		} 	}











文章来源: 俄罗斯方块笔记
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!