6) 用户的感受就是, 方块动了.
package 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) {
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 moveLeft(){
col--;
}
public void moveRight(){
col++;
}
}
Tetromino.java
Tetromino
package Tetris;
import java.util.Arrays;
import java.util.Random;
/**
* 4格方块类
*
*/
public abstract class Tetromino {
/** 4个格子,留给子类使用的属性 protected*/
protected Cell[] cells = new Cell[4];
/** 随机参数7种方块之一 */
public static Tetromino randomOne(){
Random random = new Random();
int type = random.nextInt(7);
switch (type) {
case 0: return new T();
case 1: return new S();
case 2: return new Z();
case 3: return new I();
case 4: return new L();
case 5: return new J();
case 6: return new O();
}
return null;
}
public void softDrop(){
for (int i = 0; i < cells.length; i++) {
Cell cell = cells[i];
cell.drop();
}
}
public void moveLeft(){
for (int i = 0; i < cells.length; i++) {
Cell cell = cells[i];
cell.moveLeft();
}
}
public void moveRight(){
for (int i = 0; i < cells.length; i++) {
Cell cell = cells[i];
cell.moveRight();
}
}
@Override
public String toString() {
return Arrays.toString(cells);
}
/** 存储旋转状态的类,在Tetromino类中添加 */
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) {
this.row0=row0;this.col0=col0;
this.row1 = row1;this.col1 = col1;
this.row2 = row2;this.col2 = col2;
this.row3 = row3;this.col3 = col3;
}
}
//在Tetromino 类上添加向右转的方法
private int index = 10000;
//s0={row0,col0,row1,col1,row2,col2,row3,col3}
protected State[] states;//在子类构造器中初始化 //{s0,s1,s2,s3};
public void rotateRight() {
//System.out.println(this);
//输入1:cells 当前方块的数据
//输入2:sN : s1 s2 s3 s0 s1 s2 s3 ...
//输出 cells 旋转以后的方块数据
//算法:cells[0]+sN -> cells
//如何得到序列:1 2 3 0 1 2 3 0 1 2 3 0
index ++;//10005
//index%4 = ?;//1 2 3 0 1 2 3 0
//states[index%4]=?//s1 s2 s3 s0 s1 s2 s3...
State s = states[index%states.length];
//s = s1
Cell o = cells[0];//找到轴 t0[0]
int row = o.getRow();
int col = o.getCol();
cells[1].setRow(row + s.row1);//轴的row+s1[row1]=t1.row
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);
//System.out.println(this);
}
public void rotateLeft() {
index --;//10005
State s = states[index%states.length];
Cell o = cells[0];//找到轴 t0[0]
int row = o.getRow();
int col = o.getCol();
cells[1].setRow(row + s.row1);//轴的row+s1[row1]=t1.row
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);
}
}
/** T 型方块,包内类 */
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[]{
new State(0,0, 0,-1, 0,1, 1,0), //s0
new State(0,0, -1,0, 1,0, 0,-1),//s1
new State(0,0, 0,1, 0,-1, -1,0),//s2
new State(0,0, 1,0, -1,0, 0,1)//s3
};
}
}
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[] {
new State(0, 0, 0, 1, 1, -1, 1, 0),
new State(0, 0, -1, 0, 1, 1, 0, 1)};
}
}
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[] {
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)};
}
}
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[] {
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)};
}
}
class Z extends Tetromino{
public Z() {
cells[0] = new Cell(1,4,Tetris.Z);
cells[1] = new Cell(1,5,Tetris.Z);
cells[2] = new Cell(0,3,Tetris.Z);
cells[3] = new Cell(0,4,Tetris.Z);
//====
states = new State[] {
new State(0, 0, -1, -1, -1, 0, 0, 1),
new State(0, 0, -1, 1, 0, 1, 1, 0)};
}
}
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[] { new State(0, 0, 0, 1, 1, 0, 1, 1),
new State(0, 0, 0, 1, 1, 0, 1, 1) };
}
}
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[] {
new State(0, 0, 0, -1, 0, 1, 0, 2),
new State(0, 0, -1, 0, 1, 0, 2, 0)};
}
}
package Tetris;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.KeyListener;
import java.awt.image.BufferedImage;
import java.util.Arrays;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**
* 俄罗斯方块
*
*/
public class Tetris extends JPanel {
/** 游戏的状态 */
private int state;
/** 游戏正在玩状态 */
public static final int PLAYING = 0;
/** 游戏暂停状态 */
public static final int PAUSE = 1;
/** 游戏结束状态 */
public static final int GAME_OVER = 2;
/** 游戏状态提示信息 */
private static final String[] STATE=
{"[P]Pause", "[C]Continue", "[S]Restart"};
/** 下落速度控制 */
int index = 0;
/** speed 的值越小下落速度越快 */
int speed = 8;
/** 分数 */
private int score;
/** 行数, 销毁的总行数 */
private int lines;
public static final int ROWS = 20;
public static final int COLS = 10;
/** 方块墙 */
private Cell[][] wall=new Cell[ROWS][COLS];
/** 正在下落的方块 */
private Tetromino tetromino;
/** 下一个方块 */
private Tetromino nextOne;
/** 在Tetris 中添加背景图属性 */
private static BufferedImage background;
public static BufferedImage gameOverImage;
public static BufferedImage T;
public static BufferedImage S;
public static BufferedImage Z;
public static BufferedImage J;
public static BufferedImage L;
public static BufferedImage I;
public static BufferedImage O;
/** 读取图片文件到内存对象 */
//将图片复制到 com.tarena.tetris包中
static {
try{
background=ImageIO.read(
Tetris.class.getResource(
"tetris.png"));
gameOverImage=ImageIO.read(
Tetris.class.getResource(
"game-over.png"));
T=ImageIO.read(Tetris.class
.getResource("T.png"));
S=ImageIO.read(Tetris.class
.getResource("S.png"));
Z=ImageIO.read(Tetris.class
.getResource("Z.png"));
J=ImageIO.read(Tetris.class
.getResource("J.png"));
L=ImageIO.read(Tetris.class
.getResource("L.png"));
O=ImageIO.read(Tetris.class
.getResource("O.png"));
I=ImageIO.read(Tetris.class
.getResource("I.png"));
}catch(Exception e){
e.printStackTrace();
}
}
/** 利用重写方法修改父类JPanel */
//paint:涂绘, Graphics:图,画笔
public void paint(Graphics g){
//draw: 绘
g.drawImage(background, 0, 0, null);
//g.drawString("Hello", 50, 50);
g.translate(15, 15);
paintWall(g);
paintTetromino(g);
paintNextOne(g);
paintScore(g);//绘制分数
g.translate(-15, -15);
paintState(g);//绘制游戏状态
}
//绘制状态
private void paintState(Graphics g) {
//如果state是 0 显示 Pause
//如果state是 1 显示 Continue
//如果state是 2 显示 Restart
g.drawString(STATE[state], 309, 287);
if(state == GAME_OVER){
g.drawImage(gameOverImage,0,0,null);
}
}
//绘制分数
private void paintScore(Graphics g){
int x = 293;
int y = 162;
Font font = new Font(
Font.SANS_SERIF, Font.BOLD, 30);
g.setFont(font);
g.setColor(new Color(0x667799));
g.drawString("SCORE:"+score, x, y);
y+=56;
g.drawString("LINES:"+lines, x, y);
}
public void paintNextOne(Graphics g){
Cell[] cells = nextOne.cells;
for(int i=0;i=1; i--){
System.arraycopy(wall[i-1], 0,
wall[i], 0, COLS);
}
Arrays.fill(wall[0], null);
}
/** 将方块着陆到墙上 */
private void landIntoWall() {
Cell[] cells = tetromino.cells;
for(int i=0; i=ROWS) ||
(col<0||col>=COLS)){
return true;
}
}
return false;
}
//检查当前下落的方块,是否与墙砖重合,true重合
private boolean concide(){
Cell[] cells = tetromino.cells;
//for (int i = 0; i < cells.length; i++) {
// Cell cell = cells[i];
for(Cell cell: cells){
int row = cell.getRow();
int col = cell.getCol();
if(wall[row][col]!=null){
return true;
}
}
return false;
}
/** 在tetris 类中增加旋转流程控制方法 */
public void rotateRightAction(){
//rotate:原地转
tetromino.rotateRight();
if(outOfBounds() || concide()){
tetromino.rotateLeft();
}
}
public void rotateLeftAction(){
//rotate:原地转
tetromino.rotateLeft();
if(outOfBounds() || concide()){
tetromino.rotateRight();
}
}
public static void main(String[] args) {
//Frame 框,相框,代表窗口框
JFrame frame = new JFrame();
//panel 代表面板
Tetris panel = new Tetris();
//Background 背景
panel.setBackground(Color.YELLOW);
//窗口中添加面板
frame.add(panel);
frame.setUndecorated(true);//去掉窗口边框
frame.setSize(535, 580);
//居中
frame.setLocationRelativeTo(null);
//点击X时候同时关闭程序
frame.setDefaultCloseOperation(
JFrame.EXIT_ON_CLOSE);
//显示窗口框
frame.setVisible(true);
//尽快的调用 paint()方法绘制显示界面
//显示窗口以后,执行 启动方法action
panel.action();
}
}