改进 1. 方块旋转修改

2. 实现没达到一个成绩等级进行加速并且保持速度直到下一次加速(使用两个定时器)

3. 实现两个人分别暂停

4. 界面优化

图片大家网上自己搜索一下

--------------------------------------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.p_w_picpath.BufferedImage;

import java.io.IOException;

import java.util.Arrays;

import java.util.Timer;

import java.util.TimerTask;

import javax.p_w_picpathio.ImageIO;

import javax.swing.JFrame;

import javax.swing.JPanel;

/**

* 俄罗斯方块的游戏执行类,继承于JPanel实现绘制

*

* @author soft01

*

*/

public class Tetris extends JPanel {

/** 版本号*/

private static final long serialVersionUID = 1L;

/** 玩家p1和玩家p2的分数,行数,游戏的墙,生成的方块,下一个方块

* 游戏结束和暂停提示,定时器*/

private int scores_p1;

private int lines_p1;

private int scores_p2;

private int lines_p2;

public Cell[][] walls_p1 = new Cell[20][10];

public Cell[][] walls_p2 = new Cell[20][10];

private Tetromino tetromino_p1;

private Tetromino tetromino_p2;

private Tetromino nextOne_p1;

private Tetromino nextOne_p2;

private boolean pause_p1;

private boolean pause_p2;

private boolean gameOver_p1;

private boolean gameOver_p2;

private Timer timer_p1;

private Timer timer_p2;

/** 行数*/

private static final int ROWS = 20;

/** 列数*/

private static final int COLS = 10;

/** 字体颜色,设置为与方块界面相同的颜色*/

public static final Color FONT_COLOR = new Color(0x667799);

/** 字体大小,设置为25号*/

public static final int FONT_SIZE = 25;

/** 格子的像素,26*/

public static final int CELL_SIZE = 26;

/** 方块下落时间间隔,通过设置定时器的间隔时间实现*/

public static final int INTEVAL = 600;

/** 用于加速的时间间隔值*/

public static final int INTEVALDOWN = 50;

/** 消除行数对应的分数,设置为1 3 9 27*/

public static final int[] SCORE_TABLE = {0, 1, 3, 9, 27};

/** 将程序需要的数据用常量表示,增加代码可读性*/

/** 使用白色作为说明文字的背景颜色*/

public static final Color COLOR_FONTBACKGROUND = new Color(0xffffff);// 白色

/** 窗口框架的宽度和高度*/

public static final int FRAME_WIDTH = 1015;

public static final int FRAME_HEIGHT = 570;

/** 定义一个boolean数组,用于实现成绩分段,速度不同*/

private boolean[] flags_p1 = new boolean[15];

/** 定义一个boolean数组,用于实现成绩分段,速度不同*/

private boolean[] flags_p2 = new boolean[15];

/** 定义为静态的缓冲图片,可以被静态代码块调用加载*/

public static BufferedImage background;

public static BufferedImage gameOverImage;

public static BufferedImage T;

public static BufferedImage S;

public static BufferedImage Z;

public static BufferedImage L;

public static BufferedImage J;

public static BufferedImage I;

public static BufferedImage O;

/** 静态代码块,用于加载一次性资源,主要是,图片*/

static {

try {

ImageIO.read(Tetris.class.getResource("tetris.png"));

gameOverImage = ImageIO.read(Tetris.class.getResource("game-over.png"));

I = ImageIO.read(Tetris.class.getResource("I.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"));

L = ImageIO.read(Tetris.class.getResource("L.png"));

J = ImageIO.read(Tetris.class.getResource("J.png"));

O = ImageIO.read(Tetris.class.getResource("O.png"));

} catch (IOException e) {

e.printStackTrace();

}

}

/** 程序的入口main方法,构建JFrame框架*/

public static void main(String[] args) {

/** 创建Tetris的对象,用于将程序装入JFrame中*/

Tetris tetris = new Tetris();

/** 新建窗口对象并且设置标题为TETRIS*/

JFrame frame = new JFrame("TETRIS");

/** 将画板添加到新建的窗口中*/

frame.add(tetris);

/** 设置窗口的宽度,高度*/

frame.setSize(FRAME_WIDTH, FRAME_HEIGHT);

/** 窗口关闭(叉)时结束程序*/

frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);

/** 窗口居中*/

frame.setLocationRelativeTo(null);

/** 设置窗口可见(默认的时候是不可见的)*/

frame.setVisible(true);

/** 执行tetris对象的action方法,静态方法不能直接调用非静态

* 方法*/

tetris.action();

}

/** 程序执行的主要方法,设置键盘监听*/

private void action() {

startAction();

repaint();

/** 通过匿名内部类创建键盘监听*/

KeyListener l = new KeyAdapter() {

public void keyPressed(KeyEvent e) {

int key = e.getKeyCode();

if (key == KeyEvent.VK_ESCAPE) {

System.exit(0);// 结束java进程

}

if (gameOver_p1 || gameOver_p2) {

// 游戏结束后,按enter回车重新开始

if (key == KeyEvent.VK_ENTER) {

startAction();

repaint();

}

return;

}

if (pause_p1 || pause_p2) {

// 暂停游戏之后,可以继续游戏

if (key == KeyEvent.VK_S) {

continueActionForP1();

}

if (key == KeyEvent.VK_LEFT) {

continueActionForP2();

}

return;

}

switch (key) {

case KeyEvent.VK_2:// 玩家2的向下

softDropActionForP2();

break;

case KeyEvent.VK_K:// 玩家1的向下

softDropActionForP1();

break;

case KeyEvent.VK_1:// 玩家2的向左

moveLeftAction(tetromino_p2, walls_p2);

break;

case KeyEvent.VK_J:// 玩家1的向左

moveLeftAction(tetromino_p1, walls_p1);

break;

case KeyEvent.VK_3:// 玩家2的向右

moveRightAction(tetromino_p2, walls_p2);

break;

case KeyEvent.VK_L:// 玩家1的向右

moveRightAction(tetromino_p1, walls_p1);

break;

case KeyEvent.VK_5:// 玩家2的旋转

rotateAction(tetromino_p2, walls_p2);

break;

case KeyEvent.VK_I:// 玩家1的旋转

rotateAction(tetromino_p1, walls_p1);

break;

case KeyEvent.VK_0:// 玩家2的快速向下

hardDropActionForP2();

break;

case KeyEvent.VK_SPACE:// 玩家1的快速向下

hardDropActionForP1();

break;

case KeyEvent.VK_RIGHT:// 玩家2的技能

cheatActionForP1();

break;

case KeyEvent.VK_D:// 玩家1的技能

cheatActionForP2();

break;

case KeyEvent.VK_UP:// 玩家2的暂停

pauseActionForP2();

break;

case KeyEvent.VK_A:// 玩家1的暂停

pauseActionForP1();

break;

}

repaint();

}

};

this.addKeyListener(l);// 在当前面板上绑定键盘监听l

this.requestFocus();// 为当前面板请求键盘输入焦点

}

/** 玩家1对玩家2的技能释放,就是调用了玩家2的快速下落方法*/

private void cheatActionForP2() {

if (scores_p1 >= 5) {

hardDropActionForP2();

scores_p1 -= 5;

}

}

/** 玩家2对玩家1的技能释放,就是调用了玩家1的快速下落方法*/

private void cheatActionForP1() {

if (scores_p2 >= 5) {

hardDropActionForP1();

scores_p2 -= 5;

}

}

/** 暂停游戏,删除定时器就可以*/

private void pauseActionForP1() {

timer_p1.cancel();

pause_p1 = true;

}

/** 暂停游戏,删除定时器就可以*/

private void pauseActionForP2() {

timer_p2.cancel();

pause_p2 = true;

}

/** 继续游戏,新建相同的定时器和任务就可以*/

private void continueActionForP1() {

pause_p1 = false;

timer_p1 = new Timer();

timer_p1.schedule(new TimerTask(){

public void run() {

softDropActionForP1();

repaint();

}

}, INTEVAL, INTEVAL);

}

/** 继续游戏*/

private void continueActionForP2() {

pause_p2 = false;

timer_p2 = new Timer();

timer_p2.schedule(new TimerTask(){

public void run() {

softDropActionForP2();

repaint();

}

}, INTEVAL, INTEVAL);

}

/** 玩家1的快速下落方法*/

private void hardDropActionForP1() {

while (canDrop(tetromino_p1, walls_p1)) {

tetromino_p1.softDrop();

}

landToWall(tetromino_p1, walls_p1);

destroyLinesForP1();

checkGameOverForP1();

tetromino_p1 = nextOne_p1;

nextOne_p1 = Tetromino.randomOne();

}

/** 玩家2的快速下落方法*/

private void hardDropActionForP2() {

while (canDrop(tetromino_p2, walls_p2)) {

tetromino_p2.softDrop();

}

landToWall(tetromino_p2, walls_p2);

destroyLinesForP2();

checkGameOverForP2();

tetromino_p2 = nextOne_p2;

nextOne_p2 = Tetromino.randomOne();

}

/** 玩家1正常下落一步的方法*/

private void softDropActionForP1() {

if (canDrop(tetromino_p1, walls_p1)) {

tetromino_p1.softDrop();

} else {

landToWall(tetromino_p1, walls_p1);

destroyLinesForP1();

checkGameOverForP1();

tetromino_p1 = nextOne_p1;

nextOne_p1 = Tetromino.randomOne();

}

}

/** 玩家2正常下落一步的方法*/

private void softDropActionForP2() {

if (canDrop(tetromino_p2, walls_p2)) {

tetromino_p2.softDrop();

} else {

landToWall(tetromino_p2, walls_p2);

destroyLinesForP2();

checkGameOverForP2();

tetromino_p2 = nextOne_p2;

nextOne_p2 = Tetromino.randomOne();

}

}

/** 玩家1判断游戏是否结束的方法*/

private void checkGameOverForP1() {

if (walls_p1[0][4] != null) {

tetromino_p1 = null;

nextOne_p1 = null;

gameOver_p1 = true;

timer_p1.cancel();

}

}

/** 玩家2判断游戏是否结束的方法*/

private void checkGameOverForP2() {

if (walls_p2[0][4] != null) {

tetromino_p2 = null;

nextOne_p2 = null;

gameOver_p2 = true;

timer_p2.cancel();

}

}

/** 玩家1消除行的方法*/

private void destroyLinesForP1() {

int lines = 0;

for (int i = 0; i < 20; i++) {

if (fullCells(i, walls_p1)) {

removeLine(i, walls_p1);

lines++;

System.out.println(i + " " + lines);

}

}

scores_p1 += SCORE_TABLE[lines];

lines_p1 += lines;

/** 游戏每过30分降低一次速度,可以说,30分提高一个等级*/

int level = scores_p1 / 30;

/** flags_p1数组默认都是flase,可以按分数(等级)

* 来决定是否加速*/

while(! flags_p1[level]) {

if(level > 11) {

break;// 11级别是最快速度

}

checkScoreForP1(level);

break;

}

}

/** 玩家2消除行的方法*/

private void destroyLinesForP2() {

int lines = 0;

for (int i = 0; i < 20; i++) {

if (fullCells(i, walls_p2)) {

removeLine(i, walls_p2);

lines++;

}

}

scores_p2 += SCORE_TABLE[lines];

lines_p2 += lines;

/** 游戏每过30分降低一次速度,可以说,30分提高一个等级*/

int level = scores_p2 / 30;

/** flags_p1数组默认都是flase,可以按分数(等级)

* 来决定是否加速*/

while(! flags_p2[level]) {

if(level > 11) {

break;

}

checkScoreForP2(level);

break;

}

}

/** 判断玩家当前所处的等级,根据等级来决定是否加速

* 也就是,时间间隔减小*/

private void checkScoreForP1(int level) {

switch (level) {

case 1 :

case 2 :

case 3 :

case 4 :

case 5 :

case 6 :

case 7 :

case 8 :

case 9 :

case 10 :

case 11 :

intevalDownForP1(level);

break;

default : return;

}

}

/** 玩家2的等级判断*/

private void checkScoreForP2(int level) {

switch (level) {

case 1 :

case 2 :

case 3 :

case 4 :

case 5 :

case 6 :

case 7 :

case 8 :

case 9 :

case 10 :

case 11 :

intevalDownForP2(level);

break;

default : return;

}

}

/** 改变玩家1的速度,创建新的定时器*/

private void intevalDownForP1(int level) {

timer_p1.cancel();

flags_p1[level] = true;

// System.out.println(level);// 测试用

timer_p1 = new Timer();

int inteval = INTEVAL - INTEVALDOWN * level;

timer_p1.schedule(new TimerTask(){

public void run(){

softDropActionForP1();

repaint();

}

}, inteval, inteval);

}

/** 改变玩家1的速度,创建新的定时器*/

private void intevalDownForP2(int level) {

timer_p2.cancel();

flags_p2[level] = true;

// System.out.println(level);// 测试用

timer_p2 = new Timer();

int inteval = INTEVAL - INTEVALDOWN * level;

timer_p2.schedule(new TimerTask(){

public void run(){

softDropActionForP2();

repaint();

}

}, inteval, inteval);

}

/** 判断给定的行是否为满,消行内调用的方法*/

private boolean fullCells(int row, Cell[][] wall) {

Cell[] line = wall[row];

for (Cell cell : line) {

if (cell == null) {

return false;

}

}

return true;

}

/** 消除满行,消行内调用的方法*/

private void removeLine(int row, Cell[][] wall) {

for (int i = row; i > 0; i--) {

System.arraycopy(wall[i - 1], 0, wall[i], 0, COLS);

}

Arrays.fill(wall[0], null);

}

/** 方块着陆到墙的方法,玩家1 2 共有的*/

private void landToWall(Tetromino tetromino, Cell[][] wall) {

Cell[] cells = tetromino.cells;

for (Cell cell : cells) {

int row = cell.getRow();

int col = cell.getCol();

wall[row][col] = cell;

}

}

/** 判断是否可以下落的方法,玩家12 共有*/

private boolean canDrop(Tetromino tetromino, Cell[][] wall) {

Cell[] cells = tetromino.cells;

for (Cell cell : cells) {

if (cell.getRow() == ROWS - 1) {

// cell有0-19,行数是20

return false;

// 如果方块走到底部,则不可以再下落了

}

int row = cell.getRow();

int col = cell.getCol();

if (wall[row + 1][col] != null) {

return false;

}

}

return true;

}

/** 向左移动的方法,玩家1 2 是一样的*/

private void moveLeftAction(Tetromino tetromino, Cell[][] wall) {

tetromino.moveLeft();

if (coincide(tetromino, wall) || outOfBounds(tetromino, wall)) {

tetromino.moveRight();

}

}

/** 向右移动的方法,玩家1 2 是一样的*/

private void moveRightAction(Tetromino tetromino, Cell[][] wall) {

tetromino.moveRight();

if (coincide(tetromino, wall) || outOfBounds(tetromino, wall)) {

tetromino.moveLeft();

}

}

/** 旋转的方法,玩家1和玩家2是一样的*/

private void rotateAction(Tetromino tetromino, Cell[][] wall) {

tetromino.rotate();

if (coincide(tetromino, wall) || outOfBounds(tetromino, wall)) {

tetromino.rotateBack();// 转回来

}

}

/** 判断方块移动之后之否与原有的格子重合*/

private boolean coincide(Tetromino tetromino, Cell[][] wall) {

for(Cell cell:tetromino.cells){

int row=cell.getRow();

int col=cell.getCol();

if(row>=0&&row=0

&&wall[row][col]!=null){

return true;

}

}

return false;

}

/**检查方块是否越界,也就是方块的所有格子都在列数范围内*/

private boolean outOfBounds(Tetromino tetromino, Cell[][] wall){

for(Cell cell:tetromino.cells){

int col=cell.getCol();

if(col<0||col>=COLS){

return true;

}

}

for(Cell cell:tetromino.cells){

int row=cell.getRow();

int col=cell.getCol();

if(!(row>=0&&row=0

)){

return true;

}

}

return false;

}

/** 用于开始程序以及重新开始程序的方法*/

private void startAction() {

pause_p1 = false;

pause_p2 = false;

gameOver_p1 = false;

gameOver_p2 = false;

scores_p1 = 0;

scores_p2 = 0;

lines_p1 = 0;

lines_p2 =0;

Arrays.fill(flags_p1, false);

Arrays.fill(flags_p2, false);

for (Cell[] line : walls_p1) {

Arrays.fill(line, null);

}

for (Cell[] line : walls_p2) {

Arrays.fill(line, null);

}

tetromino_p1 = Tetromino.randomOne();

nextOne_p1 = Tetromino.randomOne();

tetromino_p2 = Tetromino.randomOne();

nextOne_p2 = Tetromino.randomOne();

timer_p1 = new Timer();

timer_p1.schedule(new TimerTask(){

public void run() {

softDropActionForP1();

repaint();

}

}, INTEVAL, INTEVAL);

timer_p2 = new Timer();

timer_p2.schedule(new TimerTask(){

public void run() {

softDropActionForP2();

repaint();

}

}, INTEVAL, INTEVAL);

}

/** 重写paint方法,设置画板,并且实现画画*/

public void paint(Graphics g) {

/** 将背景图画三张

* 此处顺序不能改变,不然界面就错了*/

g.drawImage(background, 246, 0, null);

g.drawImage(background, 0, 0, null);

g.drawImage(background, 720, 0, null);

g.translate(15, 15);// 坐标系平移

paintWall(g);

paintTetromino(g);

paintNextOne(g);

paintScore(g);

if (gameOver_p1 || gameOver_p2) {

g.drawImage(gameOverImage, -12, -13, null);

g.drawImage(gameOverImage, 512, -13, null);

Font font = getFont();

font = new Font(font.getName(), font.PLAIN, 150);

g.setFont(font);

String str1 = "WIN!";

String str2 = "回车开始";

if (gameOver_p1) {

g.drawString(str1, 515, 150);

g.drawString(str2, 0, 350);

} else {

g.drawString(str1, 0, 150);

g.drawString(str2, 0, 350);

}

}

}

/** 分数等信息的绘制*/

private void paintScore(Graphics g) {

int x1 = 289;

int x2 = 535;

int y = 160;

g.setColor(FONT_COLOR);

Font font = getFont();

font = new Font(font.getName(), Font.BOLD, FONT_SIZE);

g.setFont(font);

String str1 = "SCORE:" + scores_p1;

String str2 = "SCORE:" + scores_p2;

g.drawString(str1, x1, y);

g.drawString(str2, x2, y);

y += 56;

str1 = "LINES:" + lines_p1;

g.drawString(str1, x1, y);

str2 = "LINES:" + lines_p2;

g.drawString(str2, x2, y);

y += 56;

str1 = str2 = "[A/UP]PAUSE";

if (pause_p1 || pause_p2) {

str1 = str2 = "[S/LEFT]CONTINUE";

x1 -= 15;

x2 -= 15;

}

g.drawString(str1, x1, y);

g.drawString(str2, x2, y);

font = new Font(font.getName(), Font.BOLD, 18);

g.setFont(font);

g.drawString("1玩家 I转 K下 J左 L右 空格快落", 280, 313);

g.drawString("玩家可以减去5分," +

"使用技能[D]/[右方向键][ESC]退出", 280, 340);

g.drawString("2玩家 5转 2下 1左 3右 0快落", 280, 367);

}

/** 绘制下一个下落的方块*/

private void paintNextOne(Graphics g) {

if (nextOne_p1 == null) {

return;

}

Cell[] cells = nextOne_p1.cells;

for (int i = 0; i < cells.length; i++) {

Cell cell = cells[i];

int x = (cell.getCol()-1) * CELL_SIZE;

int y = cell.getRow() * CELL_SIZE;

g.drawImage(cell.getImage(), x + 260, y + 30, null);

}

if (nextOne_p2 == null) {

return;

}

cells = nextOne_p2.cells;

for (int i = 0; i < cells.length; i++) {

Cell cell = cells[i];

int x = (cell.getCol()-1) * CELL_SIZE;

int y = cell.getRow() * CELL_SIZE;

g.drawImage(cell.getImage(), x + 500, y + 30, null);

}

}

private void paintTetromino(Graphics g) {

if (tetromino_p1 == null) {

// 如果没有正在下落的方块,就不绘制

return;

}

for(Cell cell:tetromino_p1.cells){

g.drawImage(cell.getImage(), CELL_SIZE*cell.getCol()-1, CELL_SIZE*cell.getRow()-1, null);

}

if (tetromino_p2 == null) {

// 如果没有正在下落的方块,就不绘制

return;

}

g.translate(720, 0);

for(Cell cell:tetromino_p2.cells){

g.drawImage(cell.getImage(), CELL_SIZE*cell.getCol()-1, CELL_SIZE*cell.getRow()-1, null);

}

g.translate(-720, 0);

}

private void paintWall(Graphics g) {

for (int row = 0; row < walls_p1.length; row++) {

Cell[] line = walls_p1[row];

for (int col = 0; col < line.length; col++) {

Cell cell = line[col];

int x = col * CELL_SIZE;

int y = row * CELL_SIZE;

if (cell == null) {

g.setColor(new Color(0));// 黑色

g.drawRect(x, y, CELL_SIZE, CELL_SIZE);

} else {

g.drawImage(cell.getImage(), x - 1, y - 1, null);

}

}

}

for (int row = 0; row < walls_p2.length; row++) {

Cell[] line = walls_p2[row];

for (int col = 0; col < line.length; col++) {

Cell cell = line[col];

int x = col * CELL_SIZE + 720;

int y = row * CELL_SIZE;

if (cell == null) {

g.setColor(new Color(0));// 黑色

g.drawRect(x, y, CELL_SIZE, CELL_SIZE);

} else {

g.drawImage(cell.getImage(), x - 1, y - 1, null);

}

}

}

g.setColor(new Color(0xffffff));

g.fillRect(267 , 293, CELL_SIZE * 17, CELL_SIZE * 3);

}

}

/----------------------------Cell类-----------------------------

import java.awt.p_w_picpath.BufferedImage;

/**

* 俄罗斯方块的格子类,包含格子属性,行列 图片

* 添加读取设置方法

* 添加移动的方法,还有toString方法

*

* @author soft01

*

*/

public class Cell {

private int row;

private int col;

private BufferedImage p_w_picpath;

public Cell() {

}

public Cell(int row, int col, BufferedImage p_w_picpath) {

super();

this.row = row;

this.col = col;

this.p_w_picpath = p_w_picpath;

}

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 p_w_picpath;

}

public void setImage(BufferedImage p_w_picpath) {

this.p_w_picpath = p_w_picpath;

}

public void drop() {

row ++;

}

public void moveRight() {

col ++;

}

public void moveLeft() {

col --;

}

public String toString() {

return row + "," + col;

}

}

/-----------------------Tetromino类--------------

import java.util.Arrays;

import java.util.Random;

/**

* 四格方块的类

*

* @author soft01

*

*/

public class Tetromino {

/** 用四个格子,对应四格方块*/

protected Cell[] cells = new Cell[4];

// /** c用于接收四格方块构造器的字符,可以进行测试,查看方块是否正常生成*/

// char c;

// /** */

// int index = 0;

/** 用于实现旋转的State数组*/

protected State[] states;

/** 通过取余运算来实现周期性,遍历格子1 2 3*/

protected int index = 10000;

/** 私有构造器*/

private Tetromino() {

}

/** State内部类,一共六个属性,对应方块除了轴以外的三个格子,行列坐标*/

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;

}

}

/** 下落一步的方法*/

public void softDrop() {

for (int i = 0; i < cells.length; i ++) {

cells[i].drop();

}

}

/** 左移一步的方法*/

public void moveLeft() {

for (int i = 0; i < cells.length; i ++) {

cells[i].moveLeft();

}

}

/** 右移一步的方法*/

public void moveRight() {

for (int i = 0; i < cells.length; i ++) {

cells[i].moveRight();

}

}

/** 旋转的方法

* 旋转的实现,

* 1 获得当前的轴

* 2 获得下一个状态的数据变化(相对于轴的数据变化)

* 3 利用加法来实现数据变化*/

public void rotate() {

Cell o = cells[0];

int row = o.getRow();

int col = o.getCol();

index++;

State s = states[index % states.length];

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 rotateBack() {

Cell o = cells[0];

int row = o.getRow();

int col = o.getCol();

index--;

State s = states[index % states.length];

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);

}

/** 重写toString方法*/

public String toString() {

return Arrays.toString(cells);

}

/** 创建四格方块的实例的方法,随机生成方块*/

public static Tetromino randomOne() {

Random r = new Random();

int type = r.nextInt(7);

switch (type) {

case 0 : return new T();

case 1 : return new L();

case 2 : return new J();

case 3 : return new I();

case 4 : return new O();

case 5 : return new Z();

case 6 : return new S();

}

return null;

}

/** 静态方法中只能使用静态内部类*/

private static 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[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);

states[0]=new State(0,0,0,-1,0,1,1,0);

}

}

private static 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) };

}

}

private static 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) };

}

}

private static 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[] { new State(0, 0, -1, -1, -1, 0, 0, 1),

new State(0, 0, -1, 1, 0, 1, 1, 0) };

}

}

private static 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) };

}

}

private static 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) };

}

}

private static 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) };

}

}

}

java双人俄罗斯方块_双人版俄罗斯方块相关推荐

  1. java web开发学习手册_【Java手册】Java开发手册_华山版(2019.06)

    版本号:1.5.0 更新日期:2019.06.19 制定团队:阿里巴巴与Java社区开发者 更新亮点:华山版,新增21条设计规约,修改描述112处,完善若干处示例 2017年春天,<阿里巴巴Ja ...

  2. C语言 Linux版俄罗斯方块,C语言版——俄罗斯方块(一)

    --使用软件VC6.0(需要一个函数库--Easy_X) #include #include #include #include #include #include #include #include ...

  3. VC写的双人版俄罗斯方块

    以前写过C++版的俄罗斯方块,后来老师让写双人版,刚开始大家都认为是把所有的代码copy一遍就行了,但实际并不是这样,这样做并不能实现双人版. 在老师的提示下,我们写出来C++版的俄罗斯方块游戏,现在 ...

  4. VC版双人PK版俄罗斯方块

    源代码下载地址:http://download.csdn.net/detail/qq_29187355/9855657 1 题目要求 设计一个双人俄罗斯方块游戏 2 功能需求 (1)   实现双人俄罗 ...

  5. MFC双人版俄罗斯方块

    俄罗斯方块 第一次单独完成了一个小游戏,虽然是按照老师编的实验指导书上面单人版俄罗斯方块改过来的,但是还是很有成就感的. 砖块实现思路: 给砖块设置一个中心点,然后依次按照中心块的位置设置其他块的坐标 ...

  6. Java版俄罗斯方块

    Java版俄罗斯方块 08年写的一个Java版俄罗斯方块程序 界面做的中规中矩,每种形状颜色都不相同 程序控制还可以,没什么大的Bug 消磨时间的时候可以Down下来玩玩 下载链接:http://do ...

  7. java俄罗斯方块英文书籍_Java版俄罗斯方块

    Java版俄罗斯方块 08年写的一个Java版俄罗斯方块程序 界面做的中规中矩,每种形状颜色都不相同 程序控制还可以,没什么大的Bug 消磨时间的时候可以Down下来玩玩 下载链接:http://do ...

  8. 《游戏学习》Java版俄罗斯方块小游戏源码实战

    [Java版俄罗斯方块]     增加保存配置信息到文件的功能,声音设置.显示设置.关卡选择等配置信息在修改后将会保存在jar包同级目录下(以jar相同的文件名+.cfg后缀保存) [菜单选项]    ...

  9. java版的俄罗斯方块_Java版俄罗斯方块

    Java版俄罗斯方块 08年写的一个Java版俄罗斯方块程序 界面做的中规中矩,每种形状颜色都不相同 程序控制还可以,没什么大的Bug 消磨时间的时候可以Down下来玩玩 下载链接:http://do ...

最新文章

  1. 化栈为队(两个栈来实现一个队列)
  2. CNN模型之MobileNet
  3. python运维脚本部署jdk_Jenkins自动执行Python脚本,并输出测试报告
  4. asp.net 安装element ui_Vue组件库系列三:打造属于自己的 UI 库文档(新版本的方案)...
  5. 30分钟掌握ES6/ES2015核心内容(上)
  6. OpenCASCADE绘制测试线束:OCAF 命令之基本命令
  7. [网络安全自学篇] 四十五.病毒详解及批处理病毒原理分析(自启动、修改密码、定时关机、蓝屏、进程关闭)
  8. JavaScript中的数学对象Math
  9. cpu利用率低linux,linux计算,cpu 利用率超低,如何处理?
  10. 调用operator+=来定义operator+比其他方法更有效?
  11. JavaScript JSON 对象使用详解、JSON. parse()、JSON. stringify()
  12. 马尔科夫链(Markov Chain),机器学习和人工智能的基石
  13. 极客星球 | Unity3D插件模板化探索
  14. python分词、词频统计以及根据词频绘制词云
  15. 闪信霸屏短信USSD是什么?
  16. linux之atoi,atol,atoll,atof
  17. 灰色页面,HTML灰色页面
  18. 最全的网站推广方案(SEO)
  19. MAC快速查看本地 SSH KEY
  20. 关于支付宝的支付流程

热门文章

  1. 基于Ubuntu 多进程基础知识笔记
  2. 最新抖音取图小程序源码-支持达人入驻和多端发布
  3. python中turtle的用法及实例--你的唐僧哥哥
  4. 关于springcloud中eureka server端配置的一些总结
  5. 杰理之提示音配置【篇】
  6. h264基础知识 宏块,片
  7. 膜拜!用最少的代码却实现了最牛逼的滚动动画
  8. 基金的募集、申购、赎回与交易
  9. 一个简单的监控系统的设计
  10. 2022.11.13 英语背诵