俄罗斯方块(源码亲测编译正常)

项目架构:

在这里插入图片描述
主程 类Tetris

package com;

import java.awt.Color;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Arrays;
import java.util.Timer;
import java.util.TimerTask;

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

public class Tetris extends JPanel {
	private int state;
	public static final int RUNNING = 0;
	public final int Pause = 1;
	final static int GAME_OVER = 2;

	public static final int ROWS = 20;// 背景墙的行数
	public static final int COLS = 10;// 背景墙的行数
	private Cell[][] wallCells;// 背景墙
	private Tetromino nextOne;
	private int score=0;// 分数
	private int line;
	private int lines;// 销毁的分数
	private Tetromino tetromino;// 正在下落的四格方块

	// 背景图片
	private static BufferedImage backgroundlBufferedImage;
	private static BufferedImage gameoverBufferedImage;
	private static BufferedImage pauseBufferedImage;
	public static BufferedImage TBufferedImage;
	public static BufferedImage SBufferedImage;
	public static BufferedImage IBufferedImage;
	public static BufferedImage LBufferedImage;
	public static BufferedImage JBufferedImage;
	public static BufferedImage OBufferedImage;
	public static BufferedImage ZBufferedImage;

	public static final int Rows = 20;// 背景墙的行数
	public static final int Lines = 10;// 背景墙的行数
	// 在Tetris类中增加定时器
	private Timer timer;
	// 速度
	private int speed;
	// 难度级别
	private int level;
	// 下落计数当index%speed==0时候下落一次
	private int index;
	
	// 使用静态代码块加载静态的图片
	static {
		// Tetris.class的同一个包中找“tetris.png”
		try {
			backgroundlBufferedImage = ImageIO.read(Tetris.class
					.getResource("tetris.png"));
			gameoverBufferedImage = ImageIO.read(Tetris.class
					.getResource("game-over.png"));
			pauseBufferedImage = ImageIO.read(Tetris.class
					.getResource("pause.png"));
			TBufferedImage = ImageIO.read(Tetris.class.getResource("T.png"));
			SBufferedImage = ImageIO.read(Tetris.class.getResource("S.png"));
			ZBufferedImage = ImageIO.read(Tetris.class.getResource("Z.png"));
			JBufferedImage = ImageIO.read(Tetris.class.getResource("J.png"));
			LBufferedImage = ImageIO.read(Tetris.class.getResource("L.png"));
			OBufferedImage = ImageIO.read(Tetris.class.getResource("O.png"));

		} catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
	}

//	JPanel paint() paint画重写paint()修改原有的绘制方法
	
	
	public static void main(String[] args) {
		JFrame frame = new JFrame();
		// 在加载Tetris类的时候,会执行静态代码块
		// 静态代码快,装载了图片素材。为图片对象
		Tetris tetris = new Tetris();
		// 将面板的颜色设置蔚蓝色,用于测试u
//		tetris.setBackground(new Color(0x0000ff));
		frame.add(tetris);
		frame.setSize(500, 524);
		frame.setLocationRelativeTo(null);
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setVisible(true);// 在显示窗口的时候,回尽快调用paint()方法绘制界面
		tetris.action();
	}

	// 在Tetris添加方法启动方法action()
	public void action() {
		wallCells = new Cell[ROWS][COLS];
		tetromino = Tetromino.randomOne();
		nextOne = Tetromino.randomOne();
		state = RUNNING;
		// 处理键盘按下事件,在按下按键时候执行下落方法
		KeyAdapter lAdapter = new KeyAdapter() {

			// key按键pressed按下了
			@Override
			public void keyPressed(KeyEvent arg0) {
				int key = arg0.getKeyCode();
				switch (state) {
				case GAME_OVER:
					processGameOverKey(key);

					break;
				case Pause:
					processGameOverKey(key);
					break;

				case RUNNING:
					break;
				}
				repaint();
			}

		};
		// 下落流程,监听键盘事件
		// 如果按下箭头按下->执行下落算法tetromino.softDrop()->尽快调用paint()->方法会根据当前的数据
		// 重新绘制界面->看到移动以后的方块了
		// 邦定事件到当前面板
		this.requestFocus();
		this.addKeyListener(lAdapter);
		// 在Action中添加定时计划任务
		timer = new Timer();
		timer.schedule(new TimerTask() {

			@Override
			public void run() {
				speed = 40 - (line / 100);
				speed = speed < 1 ? 1 : speed;
				level = 41 - speed;
				if (state == RUNNING && index % speed == 0) {
					softDropAction();
				}
				index++;
				repaint();
			}
		}, 10, 10);

	}

	protected void softDropAction() {
		if (canDrop()) {
			tetromino.softDrop();
		} else {
			landIntoWall();
			destroyLines();
			if (isGameOver()) {
				state = GAME_OVER;
			} else {
				tetromino = nextOne;
				nextOne = Tetromino.randomOne();
			}
		}

	}
//检查游戏是否结束
	private boolean isGameOver() {
		//如果下一个方块没有出场位置了,则游戏结束
//		就是:下一个出场方块每个格子行列对应的
//		墙上位置,如果有格子,就游戏结束
		Cell[] cells = nextOne.cells;
		for (Cell cell : cells) {
			int row = cell.getRow();
			int col = cell.getCol();
			if (wallCells[row][col] != null) {
				return true;
			}
		}
		return false;
	}
private static int[] scoreTable = {0,1,10,50,100};
	private void destroyLines() {
		int lines = 0;
		for (int row = 0; row < wallCells.length; row++) {
			if (fullCells(row)) {
				deleteRow(row);
				lines++;
			}
		}
		this.score += scoreTable[lines];
		this.lines += lines;
	}

	private void deleteRow(int row) {
		for (int i = row; i >= 1; i++) {
			System.arraycopy(wallCells[i - 1], 0, wallCells[i], 0, COLS);
		}
		Arrays.fill(wallCells[0],null);
	}

	private boolean fullCells(int row) {
		Cell[] lineCells = wallCells[row];
		for (Cell cell : lineCells) {
			if (cell == null) {// 如果有null返回false,否则返回true
				return false;
			}
		}
		return true;
	}

	private void landIntoWall() {
		Cell[] cellls = tetromino.cells;
		for (int i = 0; i < cellls.length; i++) {
			Cell cell = cellls[i];
			int row = cell.getRow();
			int col = cell.getCol();
			wallCells[row][col] = cell;
		}
	}
//检查当前的方块是否能够下落,返回true
	private boolean canDrop() {
		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 (Cell cell : cells) {
			int row = cell.getRow()+1;
			int col = cell.getCol();
			if (row >= 0  && row<ROWS&&col>=0&&col<=COLS&& wallCells[row][col] != null) {
				return false;
			}
			
		}
		return true;
	}

//	硬下落流程,下落到不能下落为止,邦定到空格(VK_SPACE)事件上
	public void hardDropAction() {
		while (canDrop()) {
			tetromino.softDrop();
		}
		landIntoWall();
		destroyLines();
		if (isGameOver()) {
			state = GAME_OVER;
		}else {
			tetromino = nextOne;
			nextOne = Tetromino.randomOne();
		}

	}
//	在Tetris类中添加旋转流程控制方法
	public void rotateRightAction() {
		tetromino.rotateRight();
		if (outOfBounds() || coincide()) {
			tetromino.rotateLeft();
		}
	}
//	检查当前正在下落的方块是否出界了
	
	private boolean outOfBounds() {
		Cell[] cells = tetromino.cells;
		for (int i = 0; i < cells.length; i++) {
			Cell cell = cells[i];
			int col = cell.getCol();
			if (col<0 ||  col >=COLS) {
				return true;
			}
			
		}
	return false;
}
//检查正在下落的方块是否与墙上的重叠
	
	private boolean coincide() {
	Cell[] cells = tetromino.cells;
	for (int i = 0; i < cells.length; i++) {
		Cell  cell = cells[i];
		int row = cell.getRow();
		int col = cell.getCol();
		//如果墙的row,col位置上有格子,就重叠了
		if (row>=0 && row<ROWS && col>0&& col<COLS&&wallCells !=null) {
			return true;
		}
	}
		return false;
	}
//在Tetris 类上添加方法,向右移动的流程控制
	public void moveRightAction() {
		//尝试向右移动,如果超过了边界就向左移动,修正回来
		tetromino.moveright();
		if (outOfBounds() || coincide()) {
			tetromino.moveLeft();
		}
	}
	
	protected void processGameOverKey(int key) {
		switch (key) {
		case KeyEvent.VK_Q:
			System.exit(0);

			break;
		case KeyEvent.VK_C:
			index = 0;
			state = RUNNING;

			break;

		default:
			break;
		}
	}
}

格子类

package com;

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) {
		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;
	}
	public void drop() {
		row++;
	}
	public void moveRight() {
		col--;
	}
	public void moveLeft() {
		row++;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return row+","+col;
	}
}

方块类

package com;

import java.lang.Thread.State;
import java.util.Arrays;
import java.util.Random;

import com.squareblock.J;
import com.squareblock.L;
import com.squareblock.I;
import com.squareblock.O;
import com.squareblock.S;
import com.squareblock.T;
import com.squareblock.Z;

/**
 * @author ASUS
 *4格方格
 */
public class Tetromino {
	protected Cell[] cells = new Cell[4];
	private int index;
//	旋转方块
	protected State[] states;
	
	
//	内部类
	protected class State{
		int row0,ro10,row1,col1,row2,col2,row3,col3;

		public State(int row0, int ro10, int row1, int col1, int row2,
				int col2, int row3, int col3) {
			super();
			this.row0 = row0;
			this.ro10 = ro10;
			this.row1 = row1;
			this.col1 = col1;
			this.row2 = row2;
			this.col2 = col2;
			this.row3 = row3;
			this.col3 = col3;
		}

		
		
	}
//工厂方法,随机生成4格方块
	
	public static Tetromino randomOne() {
		Random  random = new Random();
		int type = random.nextInt(7);
		switch (type) {
		case 0:
			return new O();
		case 1:
			return new S();
		case 2:
			return new Z();
		case 3:
			return new J();
		case 4:
			return new L();
		case 5:
			return new I();
		case 6:
			return new T();
		default:
			break;
		}
		return null;
	}

	public void softDrop() {
		for (int i = 0; i < cells.length; i++) {
			cells[i].drop();
		}
	}
//向右转
	public void rotateRight() {
//		取得变换前的下个数据状态states[n]
//		取得当前轴的row.col
//	旋转以后的数据=(row,col)+states[n]
		index++;
		State s = states[index % states.length];
		Cell o = cells[0];
		int row = o.getRow();
		int col  = o.getCol();
		cells[1].setRow(row+s.row1);
		cells[1].setCol(col+s.col1);
		cells[2].setRow(row+s.row2);
		cells[2].setCol(col+s.col2);
		cells[3].setRow(row+s.row3);
		cells[3].setCol(col+s.col3);
	}
	
	public void rotateLeft() {
		index--;
		State s = states[index % states.length];
		Cell o = cells[0];
		int row = o.getRow();
		int col = o.getCol();
		cells[1].setRow(row+s.row1);
		cells[1].setCol(col+s.col1);
		cells[2].setRow(row+s.row2);
		cells[2].setCol(col+s.col2);
		cells[3].setRow(row+s.row3);
		cells[3].setCol(col+s.col3);
		
	}

	public void moveright() {
		for (int i = 0; i < cells.length; i++) {
				cells[i].moveRight();
		}
	}

	public void moveLeft() {
		for (int i = 0; i < cells.length; i++) {
			cells[i].moveLeft();
		}
	}
	@Override
	public String toString() {
		return Arrays.toString(cells);
	}
}

七种方块: 
方块I:

package com.squareblock;

import com.Cell;
import com.Tetris;
import com.Tetromino;

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

方块J:
package com.squareblock;

import com.Cell;
import com.Tetris;
import com.Tetromino;

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

方块L:
package com.squareblock;

import com.Cell;
import com.Tetris;
import com.Tetromino;

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

方块O :

package com.squareblock;

import com.Cell;
import com.Tetris;
import com.Tetromino;

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

方块S
package com.squareblock;

import com.Cell;
import com.Tetris;
import com.Tetromino;

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

方块 T
package com.squareblock;

import com.Cell;
import com.Tetris;
import com.Tetromino;

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

方块Z:

package com.squareblock;

import com.Cell;
import com.Tetris;
import com.Tetromino;

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

///OVER

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值