俄罗斯方块的java实现:

cell类

package com.chen.Tetris;

import java.awt.image.BufferedImage;

/**
 *格子类
 */
public class Cell {
	private int row;//行
	private int col;//列
	private BufferedImage image;//图片
	
	/**构造器,初始化格子类的位置*/
	public Cell(int row,int col,BufferedImage image){
		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;
	}
	//格子向右移
	public void moveRigth(){
		col++;
	}
	//格子向左移
	public void moveLeft(){
		col--;
	}
	//格子下落
	public void moveDown() {
		row++;
	}
	//格子上移
	public void moveUp(){
		row--;
	}
}

Tetromino类

<span style="font-size:18px;"><strong>package com.chen.Tetris;

import java.util.Random;

/**
 *方块类,每个方块类有四个格子,分别表示(T,L,J,Z,I,O,S)方块的类型
 */
public abstract class Tetromino {
	Cell[] cells = new Cell[4];
	
	/**定义一个存储状态的变量*/
	protected State[] states ;
	/**定义一个旋转序号*/
	protected int index = 10;
	
	/**
	 * 创建一个内部类,用来实现存储旋转的状态
	 */
	protected class State{
		int row0,col0,row1,col1,row2,col2,row3,col3;

		public State(int row0, int col0, int row1, int col1, int row2,
				int col2, int row3, int col3) {
			super();
			this.row0 = row0;
			this.col0 = col0;
			this.row1 = row1;
			this.col1 = col1;
			this.row2 = row2;
			this.col2 = col2;
			this.row3 = row3;
			this.col3 = col3;
		}
		
		
	}
	
	
	/**方块向右移*/
	public void moveRigth(){
		for(int i=0; i<cells.length; i++)
			cells[i].moveRigth();
	}
	
	/**方块向左移*/
	public void moveLeft(){
		for(int i=0; i<cells.length; i++){
			cells[i].moveLeft();
		}
	}
	
	/**随机生成一个方块*/
	public static Tetromino randomOne(){
		Random random = new Random();
		int key = random.nextInt(7);
		switch (key) {
		case 1:return new T();
		case 2:return new L();
		case 3:return new J();
		case 4:return new Z();
		case 5:return new I();
		case 6:return new O();
		case 0:return new S();
		default :return null;
		}
	}
	/**向下移动*/
	public void moveDown() {
		for(int i=0; i<cells.length; i++){
			cells[i].moveDown();
		}
	}
	public void rotateRigth(){
		index ++;
		int n = index % states.length;
		State  aState = states[n];
		Cell o = cells[0];
		int row = o.getRow();
		int col = o.getCol();
		cells[1].setRow(row+aState.row1);
		cells[1].setCol(col+aState.col1);
		cells[2].setRow(row+aState.row2);
		cells[2].setCol(col+aState.col2);
		cells[3].setRow(row+aState.row3);
		cells[3].setCol(col+aState.col3);
		
	}
	public void rotateLeft(){
		index--;
		int n = index % states.length;//求出下一步旋转的状态
		Cell o = cells[0];//把第0个方格取出来作为轴
		int row = o.getRow();
		int col = o.getCol();//取出轴的坐标
		State aState = states[n];//取出状态数
		cells[1].setRow(row+aState.row1);
		cells[1].setCol(col+aState.col1);
		cells[2].setRow(row+aState.row2);
		cells[2].setCol(col+aState.col2);
		cells[3].setRow(row+aState.row3);
		cells[3].setCol(col+aState.col3);

	
}
}
class I extends Tetromino{
	public I(){
		cells[0] = new Cell(0, 4, Tetris.I);
		cells[1] = new Cell(0, 3, Tetris.I);
		cells[2] = new Cell(0, 5, Tetris.I);
		cells[3] = new Cell(0, 6, Tetris.I);
		states = new State[2];
		states[0] = new State(0,0,0,-1,0,1,0,2);
		states[1] = new State(0,0,-1,0,1,0,2,0);
	}
}

class L extends Tetromino{
	public L(){
		cells[0] = new Cell(0, 4, Tetris.L);
		cells[1] = new Cell(0, 3, Tetris.L);
		cells[2] = new Cell(0, 5, Tetris.L);
		cells[3] = new Cell(1, 3, Tetris.L);
		states = new State[4];
		states[0] = new State(0,0,0,1,0,-1,-1,1);
		states[1] = new State(0,0,1,0,-1,0,1,1);
		states[2] = new State(0,0,0,-1,0,1,1,-1);
		states[3] = new State(0,0,-1,0,1,0,-1,-1);
	}
}

class S extends Tetromino{
	public S(){
		cells[0] = new Cell(0, 4, Tetris.S);
		cells[1] = new Cell(0, 5, Tetris.S);
		cells[2] = new Cell(1, 3, Tetris.S);
		cells[3] = new Cell(1, 4, Tetris.S);
		states = new State[2];
		states[0] = new State(0,0,0,-1,-1,0,-1,1);
		states[1] = new State(0,0,-1,0,0,1,1,1);
	}
}

class T extends Tetromino{
	public T(){
		cells[0] = new Cell(0, 4, Tetris.T);
		cells[1] = new Cell(0, 3, Tetris.T);
		cells[2] = new Cell(0, 5, Tetris.T);
		cells[3] = new Cell(1, 4, Tetris.T);
		states = new State[4];
		states[0] = new State(0,0,0,-1,0,1,1,0);
		states[1] = new State(0,0,-1,0,1,0,0,-1);
		states[2] = new State(0,0,0,1,0,-1,-1,0);
		states[3] = new State(0,0,1,0,-1,0,0,1);
	}
}

class Z extends Tetromino{
	public Z(){
		cells[0] = new Cell(1, 4, Tetris.Z);
		cells[1] = new Cell(0, 3, Tetris.Z);
		cells[2] = new Cell(0, 4, Tetris.Z);
		cells[3] = new Cell(1, 5, Tetris.Z);
		states = new State[2];
		states[0] = new State(0,0,-1,-1,-1,0,0,1);
		states[1] = new State(0,0,-1,1,0,1,1,0);
	}
}

class J extends Tetromino{
	public J(){
		cells[0] = new Cell(0, 4, Tetris.J);
		cells[1] = new Cell(0, 3, Tetris.J);
		cells[2] = new Cell(0, 5, Tetris.J);
		cells[3] = new Cell(1, 5, Tetris.J);
		states = new State[4];
		states[0] = new State(0,0,0,-1,0,1,1,1);
		states[1] = new State(0,0,-1,0,1,0,1,-1);
		states[2] = new State(0,0,0,1,0,-1,-1,-1);
		states[3] = new State(0,0,1,0,-1,0,-1,1);
	}
}

class O extends Tetromino{
	public O(){
		cells[0] = new Cell(0, 4, Tetris.O);
		cells[1] = new Cell(0, 5, Tetris.O);
		cells[2] = new Cell(1, 4, Tetris.O);
		cells[3] = new Cell(1, 5, Tetris.O);
		states = new State[2];
		states[0] = new State(0,0,0,1,1,0,1,1);
		states[1] = new State(0,0,0,1,1,0,1,1);
	}
}
<pre name="code" class="java">package com.chen.Tetris;

import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.net.Inet4Address;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;

import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.RepaintManager;


/**
 * 俄罗斯方块游戏的主窗口类
 */
public class Tetris extends JPanel{
	/**得分*/
	private int score;
	private static int[] scores = {0,5,10,20,40};
	
	/**销毁的行数*/
	private int lines;
	
	/**正在下落的方块*/
	private Tetromino tetromino;
	
	/**下一个准备下落的方块*/
	private Tetromino tetrominoNxet;
	
	/**墙*/
	private Cell[][] walls;
	
	/**定义定时器的参数*/
	private int index ;
	private int speed ;
	private int level;
	
	private static final int ROWS = 20;
	private static final int COLS = 10;
	private static final int CELL_SIZE = 26;
	
	/**添加游戏状态的参数*/
	private int state;
	private static final int RUNNING = 0;
	private static final int PAUSE = 1;
	private static final int GAMEOVER = 2;
	
	
	/**初始化数据*/
	public Tetris(){
		lines = 0;
		score = 0;
		state = 0;
		walls = new Cell[ROWS][COLS];
	}
	
	/***
	 * 创建静态代码块,将磁盘里面的图片,读取到内存中成为静态对象
	 */
	private static BufferedImage tetris;
	public static BufferedImage I;
	public static BufferedImage S;
	public static BufferedImage T;
	public static BufferedImage Z;
	public static BufferedImage L;
	public static BufferedImage J;
	public static BufferedImage O;
	private static BufferedImage game_over;
	private static BufferedImage pause;
	static{
		try{
		tetris = ImageIO.read(Tetris.class.getResource("tetris.png"));
		T = ImageIO.read(Tetris.class.getResource("T.png"));
		S = ImageIO.read(Tetris.class.getResource("S.png"));
		I = ImageIO.read(Tetris.class.getResource("I.png"));
		Z = ImageIO.read(Tetris.class.getResource("Z.png"));
		L = ImageIO.read(Tetris.class.getResource("L.png"));
		J = ImageIO.read(Tetris.class.getResource("J.png"));
		O = ImageIO.read(Tetris.class.getResource("O.png"));
		game_over = ImageIO.read(Tetris.class.getResource("game-over.png"));
		pause = ImageIO.read(Tetris.class.getResource("pause.png"));
		}catch(Exception e ){
			
		}
	}
	/**重写paint方法*/
	public void paint(Graphics g){
		g.drawImage(tetris, 0, 0, null);
		g.translate(15, 15);
		printWall(g);
		printTetromino(g);
		printTetrominoNext(g);
		printScore(g);
		printState(g);
		
	}
	/**绘制游戏当前状态*/
	private void printState(Graphics g){
		switch (state) {
		case GAMEOVER:
			g.drawImage(game_over, -15, -15, null);
			break;
		case PAUSE:
			g.drawImage(pause, -15, -15,null);
			break;
		}
	}
	/**绘制墙*/
	public void printWall(Graphics g){
		for(int row = 0;row < ROWS;row++){
			for(int col = 0;col < COLS;col++){
				if(walls[row][col] == null){
					g.drawRect(col*26, row*26, 26, 26);
				}else {
					g.drawImage(walls[row][col].getImage(), col*26, row*26,null );
				}
			}
		}
	}
	
	/**打印正在下落的方块*/
	private void printTetromino(Graphics g){
		Cell[] cells = tetromino.cells;
		for(int i = 0 ;i<cells.length;i++){
			int x =cells[i].getCol()*26;
			int y = cells[i].getRow()*26;
			BufferedImage image = cells[i].getImage();
			g.drawImage(image, x, y, null);
		}
	}
	/**打印下一个要下落的方块*/
	private void printTetrominoNext(Graphics g){
		Cell[] cells = tetrominoNxet.cells;
		for(int i= 0 ;i<cells.length;i++){
			Cell cell = cells[i];
			int x = (cell.getCol()+10)*CELL_SIZE;
			int y = (cell.getRow()+1)*CELL_SIZE;
			g.drawImage(cell.getImage(), x, y, null);
		}
	}
	 /**打印分数和销毁的行数*/
	private void printScore(Graphics g){
		int x =297, y = 160; 
		Font font = new Font(Font.SANS_SERIF, Font.BOLD, 30);
		g.setFont(font);
		g.setColor(new Color(0x667799));
		g.drawString("SCORE:"+score, x+2, y+2);
		y += 56;
		g.drawString("LINES:"+lines, x+2, y+2);
		y += 56;
		g.drawString("LEVEL:"+level, x+2, y+2);
		
		x = 297; y = 160;
		g.drawString("SCORE:"+score, x, y);
		y += 56;
		g.drawString("LINES:"+lines, x, y);
		y += 56;
		g.drawString("LEVEL:"+level, x, y);
		
	}
	
	/**创建键盘接受监听器,监听从键盘的操作, 匿名内部类*/
	KeyListener listener = new KeyListener() {
		
		@Override
		/**输入某个键的时候,执行该方法*/
		public void keyTyped(KeyEvent e) {
		
		}
		
		@Override
		/**按键按下起来后,执行该方法*/
		public void keyReleased(KeyEvent e) {
			
		}
		@Override
		/**按键一按下就执行该方法*/
		public void keyPressed(KeyEvent e) {
			int key = e.getKeyCode();
			switch(state){
			case PAUSE:
				pauseAction(key);
				break;
			case GAMEOVER:
				game_overAction(key);
				break;
			case RUNNING:
				runningAction(key);
				break;
			}
			
			repaint();//执行完该方法以后,立刻调用paint方法,重新打印			
		}	
	};
	/**pause状态时*/
	public void pauseAction(int key){
		switch(key){
		case KeyEvent.VK_Q :
			System.exit(0);
			break;
		case KeyEvent.VK_P :
			state = RUNNING;
			index = 0;
			break;
		}
		
	}
	
	/**game_over状态时*/
	public void game_overAction(int key){
		switch(key){
		case KeyEvent.VK_Q :
			System.exit(0);
			break;
		case KeyEvent.VK_S:
			restartGame();
			break;
		}
	}
	/**running状态时*/
	private void runningAction(int key){
		switch(key){
		case KeyEvent.VK_Q :
			System.exit(0);
			break;
		case KeyEvent.VK_P :
			state = PAUSE;
			break;
		case KeyEvent.VK_RIGHT :
			moveRigthAction();
			break;
		case KeyEvent.VK_LEFT:
			moveLeftAction();
			break;
		case KeyEvent.VK_DOWN:
			moveDownAction();
			break;
		case KeyEvent.VK_SPACE:
			hardDownAction();
			break;
		case KeyEvent.VK_UP:
			roateRigthAction();
			break;
		}
	}
	
	/**重新开始游戏*/
	private void restartGame(){
		this.score = 0;
		this.index = 0;
		this.lines = 0;
		this.walls = new Cell[ROWS][COLS];
		this.tetromino = Tetromino.randomOne();
		this.tetrominoNxet = Tetromino.randomOne();
		this.state = RUNNING;
	}
	//添加定时器,匿名内部类
	TimerTask timerTask = new TimerTask() {
		@Override
		public void run() {
			index ++;
			level = (score/500+1);
			speed = 41 - level;
			if(index % speed ==0 && state == RUNNING)
			moveDownAction();
			repaint();
		}
		
		
	};
	
	/**启动方法*/
	public void action(){
		tetromino = Tetromino.randomOne();
		tetrominoNxet = Tetromino.randomOne();
		//在当前面板上将监听器注册进去
		addKeyListener(listener);
		//为当前面板获取输入焦点,以便获取键盘输入的信息
		setFocusable(true);
		//等待键盘输入信息
		requestFocus();
		
		Timer timer = new Timer();
 		timer.schedule(timerTask, 0,10);
		
		
	}
	/**当前方块向右移动的方法
	 * 算法描述:先将方块向右移,如果有重合或者越界,则返回即再向左移
	 * */
	private void moveRigthAction(){
		tetromino.moveRigth();
		if(outOfBound() || coincidence())
			tetromino.moveLeft();
		
	}
	/**当前放开向左移的方法*/
	private void moveLeftAction(){
		tetromino.moveLeft();
		if (outOfBound() || coincidence()) {
			tetromino.moveRigth();
		}
	}
	
	/**outOfBound判断是否出界
	 * 算法描述:取出当前方块的每一个格子,与边界参数进行比较
	 * true代表已越界
	 */
	public boolean outOfBound(){
		Cell[] cells = tetromino.cells;
		for(int i=0; i<cells.length; i++){
			Cell cell = cells[i];
			int row = cell.getRow();
			int col = cell.getCol();
			if(col<0 || col>=COLS || row<0 || row>=ROWS)
				return true;
		}
		return false;
	}
	/**判断与其它格子是不是有重合的地方,如有重合则不能移动
	 * 算法描述:取出当前方块中的每一个格子,然后将它的位置与墙
	 * 的位置进行比较。true代表返回有重合
	 * */
	public boolean coincidence(){
		Cell[] cells = tetromino.cells;
		for(int i=0; i<cells.length; i++){
			Cell cell = cells[i];
			int row = cell.getRow();
			int col = cell.getCol();
			if(walls[row][col] != null)
				return true;
		}
		return false;
	}
	/**方块软下落的方法
	 * 1、先判断方块是否能下落,能下落即下落
	 * 2.如果不能下落,则将当前方块打进墙里面,然后再销毁行数
	 * 3.销毁完行数之后再判断游戏是否接束,如果没有结束则替换
	 * 	掉当前方块和下一个下落的方块
	 * */
	public void moveDownAction(){
		if(isCanDown())
			tetromino.moveDown();
		else {
			putInToWall();
			int line = dropLine();
			lines += line;
			score += scores[line];
			if(isGameOver())
				state = GAMEOVER ;
			else {
				tetromino = tetrominoNxet;
				tetrominoNxet = Tetromino.randomOne();
			}
		}
	}
	/**方块硬下落的方法*/
	public void hardDownAction(){
		while(isCanDown())
			tetromino.moveDown();
		putInToWall();
		int line = dropLine();
		score += scores[line];
		lines += line;
		if(isGameOver())
			state = GAMEOVER;
		else {
			tetromino = tetrominoNxet;
			tetrominoNxet = Tetromino.randomOne();
		}
	}
	/**判断是否能下落 true代表能下落,算法描述,如果方块中有任何一个
	 格子超过界限或者下一个格子不为空的话,就不能下落*/
	private boolean isCanDown(){
		Cell[] cells = tetromino.cells;
		for(int i=0; i<cells.length; i++){
			Cell cell = cells[i];
			int row = cell.getRow();
			if(row==ROWS-1){return false;}
		}
		for (int i = 0; i < cells.length; i++) {
			Cell cell = cells[i];
			int row =cell.getRow();
			int col =cell.getCol();
			if(walls[row+1][col]!=null){return false;}
		}
		return true;
	}
	/**将方块打进墙里面*/
	private void putInToWall(){
		Cell[] cells = tetromino.cells;
		for(int i=0; i<cells.length; i++){
			Cell cell = cells[i];
			int row = cell.getRow();
			int col = cell.getCol();
			walls[row][col] = cell;
		}
	}
	/**销毁已满的行
	 * 算法描述:先判断该行是否为满,如满则消除,并lines+1;
	 */
	private int dropLine(){
		int line = 0;
		for(int row=0; row<ROWS; row++)
		if(isFull(row)){
			deleteLine(row);
			line++;
		}
		return line;
	}
	/**判断行是否满*/
	private boolean isFull(int row){
		Cell[] cells = walls[row];
		for(int i=0; i<cells.length; i++)
			if(cells[i] == null)
				return false;
		return true;
	}
	/**销毁已满的行,算法描述:利用数组复制将已满的行覆盖掉, 最后再将第一个清除*/
	private void deleteLine(int row){
		for(int i=row; i>=1; i--) {
			Cell[] src = walls[i-1];
			Cell[] des = walls[i];
			System.arraycopy(src, 0, des, 0, COLS);
		}
		Arrays.fill(walls[0], null);
	}
	/**判断游戏是否结束,算法描述,取出下一个要下落的方块,将方块的初始位置
	 与墙进行比较,不为空则到达了顶端,则游戏结束*/
	private boolean isGameOver(){
		Cell[] cells = tetrominoNxet.cells;
		for (int i = 0; i < cells.length; i++) {
			Cell cell = cells[i];
			int row = cell.getRow();
			int col = cell.getCol();
			if(walls[row][col] != null){
				return true;
			}
		}
		return false;
	}
	/**定义一个方块旋转的方法*/
	private void roateRigthAction(){
		if(tetromino == null)
			return ;
		tetromino.rotateRigth();
		if(outOfBound() || coincidence())
			tetromino.rotateLeft();
	}
	public static void main(String[] args){
		JFrame  frame = new JFrame();
		frame.setSize(535,585);
		Tetris tetris = new Tetris();
		frame.add(tetris);
		frame.setVisible(true);//窗口可见
		frame.setBackground(Color.BLUE);//设置背景颜色
		frame.setLocationRelativeTo(null);//把窗口移到屏幕中心
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);//点击关闭时会直接关闭窗口
		tetris.action();
		//待打印界面时,会自动调用paint的方法,然后再绘制出界面
	}
}