趋于完善版
步骤1:
package game;
import java.awt.image.BufferedImage;
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 void left(){
col--;
}
public void down(){
row++;
}
public void right(){
col++;
}
@Override
public String toString() {
return "Cell [row=" + row + ", col=" + col + "]";
}
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
}
}
步骤2:
package game;
public class Tetromino {
Cell[] cells = new Cell[4];
/**向左移动*/
public void moveLeft(){
for(int i=0;i<cells.length;i++){
cells[i].left();
}
}
/**向下移动*/
public void moveDown(){
for(int i=0;i<cells.length;i++){
cells[i].down();
}
}
/**向右移动*/
public void moveRight(){
for(int i=0;i<cells.length;i++){
cells[i].right();
}
}
/**添加一个方法,随机产生一种子类对象*/
public static Tetromino randomOne(){
Tetromino one = null;
int num = (int)(Math.random()*7);
switch(num){
case 0:one = new T();break;
case 1:one = new I();break;
case 2:one = new O();break;
case 3:one = new S();break;
case 4:one = new Z();break;
case 5:one = new J();break;
default:one = new L();
}
return one;
}
/**使用内部类定义7个子类型*/
static class T extends Tetromino{
public T(){
cells[0] = new Cell(0,4,TestTetromino.T);
cells[1] = new Cell(0,3,TestTetromino.T);
cells[2] = new Cell(0,5,TestTetromino.T);
cells[3] = new Cell(1,4,TestTetromino.T);
}
}
static class I extends Tetromino{
public I(){
cells[0] = new Cell(0,4,TestTetromino.I);
cells[1] = new Cell(0,3,TestTetromino.I);
cells[2] = new Cell(0,5,TestTetromino.I);
cells[3] = new Cell(0,6,TestTetromino.I);
}
}
static class O extends Tetromino{
public O(){
cells[0] = new Cell(0,4,TestTetromino.O);
cells[1] = new Cell(0,3,TestTetromino.O);
cells[2] = new Cell(1,3,TestTetromino.O);
cells[3] = new Cell(1,4,TestTetromino.O);
}
}
static class S extends Tetromino{
public S(){
cells[0] = new Cell(0,4,TestTetromino.S);
cells[1] = new Cell(0,5,TestTetromino.S);
cells[2] = new Cell(1,3,TestTetromino.S);
cells[3] = new Cell(1,4,TestTetromino.S);
}
}
static class Z extends Tetromino{
public Z(){
cells[0] = new Cell(0,4,TestTetromino.Z);
cells[1] = new Cell(0,3,TestTetromino.Z);
cells[2] = new Cell(1,4,TestTetromino.Z);
cells[3] = new Cell(1,5,TestTetromino.Z);
}
}
static class J extends Tetromino{
public J(){
cells[0] = new Cell(0,4,TestTetromino.J);
cells[1] = new Cell(0,3,TestTetromino.J);
cells[2] = new Cell(0,5,TestTetromino.J);
cells[3] = new Cell(1,5,TestTetromino.J);
}
}
static class L extends Tetromino{
public L(){
cells[0] = new Cell(0,4,TestTetromino.L);
cells[1] = new Cell(0,3,TestTetromino.L);
cells[2] = new Cell(0,5,TestTetromino.L);
cells[3] = new Cell(1,3,TestTetromino.L);
}
}
/**
* 变形:旋转
*/
public void rotate() {
int num = cells[1].getRow();
cells[1].setRow(cells[0].getRow()+cells[1].getCol()-cells[0].getCol());
cells[1].setCol(cells[0].getCol()+cells[0].getRow()-num);
num = cells[2].getRow();
cells[2].setRow(cells[0].getRow()+cells[2].getCol()-cells[0].getCol());
cells[2].setCol(cells[0].getCol()+cells[0].getRow()-num);
num = cells[3].getRow();
cells[3].setRow(cells[0].getRow()+cells[3].getCol()-cells[0].getCol());
cells[3].setCol(cells[0].getCol()+cells[0].getRow()-num);
}
/**
* 碰撞
* @param cell 已堆积的方块
* @return true / false
*/
public boolean hit(Cell cell) {
for(int i=0;i<cells.length;i++){
if((cells[i].getCol()==cell.getCol()&&
cells[i].getRow()==cell.getRow()-1)){
return true;
}
}
return false;
}
/**
* 底边的碰撞
* @param cell
* @return
*/
public boolean hitBound() {
for(int i=0;i<cells.length;i++){
if(cells[i].getRow()>=19){
return true;
}
}
return false;
}
public boolean hitLeft(Cell[] cs) {
for(int i=0;i<cs.length;i++){
for(int j=0;j<cells.length;j++){
if(cells[j].getRow()==cs[i].getRow()&&
cells[j].getCol()==cs[i].getCol()+1){
return true;
}
}
}
return false;
}
public boolean hitRight(Cell[] cs) {
for(int i=0;i<cs.length;i++){
for(int j=0;j<cells.length;j++){
if(cells[j].getRow()==cs[i].getRow()&&
cells[j].getCol()==cs[i].getCol()-1){
return true;
}
}
}
return false;
}
}
步骤3:
package game;
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 java.util.Timer;
import java.util.TimerTask;
import javax.imageio.ImageIO;
import javax.swing.JFrame;
import javax.swing.JPanel;
/**TestTetromino 是一个画板*/
public class TestTetromino extends JPanel{
//常量 矩形的宽度,方格的宽度
public static final int CELL_SIZE = 26;
//成员变量
Tetromino currentOne = Tetromino.randomOne();
Tetromino currentNext = Tetromino.randomOne();
private Cell[] cs = {};
private boolean[][] b = new boolean[20][10];
private int state;
public static final int RUNNING = 0;
public static final int GAMEOVER = 1;
private int score=0;
public static BufferedImage I;
public static BufferedImage T;
public static BufferedImage O;
public static BufferedImage S;
public static BufferedImage Z;
public static BufferedImage J;
public static BufferedImage L;
public static BufferedImage tetris;
public static BufferedImage gameover;
static{
try {
//read读取硬盘上的图片
//getResource(String path):path是图片的相对当前包的位置
I = ImageIO.read(TestTetromino.class.getResource("I.png"));
T = ImageIO.read(TestTetromino.class.getResource("T.png"));
O = ImageIO.read(TestTetromino.class.getResource("O.png"));
S = ImageIO.read(TestTetromino.class.getResource("S.png"));
Z = ImageIO.read(TestTetromino.class.getResource("Z.png"));
J = ImageIO.read(TestTetromino.class.getResource("J.png"));
L = ImageIO.read(TestTetromino.class.getResource("L.png"));
tetris = ImageIO.read(TestTetromino.class.getResource("tetris.png"));
gameover = ImageIO.read(TestTetromino.class.getResource("gameover.png"));
} catch (Exception e) {
//打印栈中的信息
e.printStackTrace();
}
}
/**重写绘制功能,此功能画板默认调用*/
public void paint(Graphics g){
g.drawImage(tetris,0, 0, null);
//平移坐标轴
g.translate(15, 15);
paintScore(g);
panelWall(g);
paintCurrentOne(g);
paintCurrentNext(g);
paintCs(g);
paintState(g);
}
private void paintState(Graphics g) {
if(state==GAMEOVER){
g.drawImage(gameover, 0, 0, null);
}
}
private void paintCurrentNext(Graphics g) {
Cell[] cells = currentNext.cells;
for(int i=0;i<cells.length;i++){
Cell cell = cells[i];
int col = cell.getCol();
int row = cell.getRow();
g.drawImage(cell.getImage(), col*CELL_SIZE+270, row*CELL_SIZE+25, null);
}
}
private void paintScore(Graphics g) {
Font font = new Font(Font.SANS_SERIF,Font.BOLD,20);
g.setFont(font);
g.drawString("SCORE:"+score, 340, 270);
}
private void paintCs(Graphics g) {
Cell[] cells = cs;
for(int i=0;i<cells.length;i++){
Cell cell = cells[i];
int col = cell.getCol();
int row = cell.getRow();
g.drawImage(cell.getImage(), col*CELL_SIZE, row*CELL_SIZE, null);
}
}
/**绘制当前下落的四方块*/
private void paintCurrentOne(Graphics g) {
//获取正在下落的方块组合内的数组对象
Cell[] cells = currentOne.cells;
for(int i=0;i<cells.length;i++){
Cell cell = cells[i];
int col = cell.getCol();
int row = cell.getRow();
g.drawImage(cell.getImage(), col*CELL_SIZE, row*CELL_SIZE, null);
}
}
/**绘制一个墙,20行,10列的表格*/
public void panelWall(Graphics g){
for(int i=0;i<20;i++){
for(int j=0;j<10;j++){
//横坐标j,纵坐标i
g.drawRect(j*CELL_SIZE, i*CELL_SIZE, CELL_SIZE, CELL_SIZE);
}
}
}
private Timer timer;
public void action(){
/*
* 定义监听器对象,用于监听键盘事件
* */
KeyListener l = new KeyAdapter(){
public void keyPressed(KeyEvent e){
int code = e.getKeyCode();
System.out.println("code:"+code);
if(state==RUNNING){
switch(code){
case 37:
if(!currentOne.hitLeft(cs)){
currentOne.moveLeft();
}
break;
case 39:
if(!currentOne.hitRight(cs)){
currentOne.moveRight();
}
break;
case 40:currentOne.moveDown();break;
case 38:currentOne.rotate();
}
outOfBoundAction();//越界
}
if(code==83){
cs = new Cell[]{};
b = new boolean[20][10];
score = 0;
currentOne = Tetromino.randomOne();
currentNext = Tetromino.randomOne();
state=RUNNING;
}
//重新绘制
repaint();
}
};
//面板添加键盘监听事件
this.addKeyListener(l);
//面板设置成屏幕焦点
this.requestFocus();
timer = new Timer();
timer.schedule(new TimerTask(){
public void run(){
if(state==RUNNING){
hitAction();//碰撞
hitBoundAction();//碰撞底边
deleteAction();//消除
gameoverAction();//检查游戏是否结束
}
repaint();
}
},0,1);
while(true){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
if(state==RUNNING){
currentOne.moveDown();
}
//重写绘制整个画板上的内容
repaint();
}
}
protected void gameoverAction() {
if(isGameOver()){
state = GAMEOVER;
}
}
private boolean isGameOver() {
for(int i=0;i<cs.length;i++){
if(cs[i].getRow()==0){
return true;
}
}
return false;
}
protected void deleteAction() {
for(int i=0;i<b.length;i++){
boolean bool = false;
for(int j=0;j<b[0].length;j++){
if(!b[i][j]){
bool = true;
break;
}
}
if(!bool){
score+=15;
for(int k=0;k<cs.length;k++){
if(cs[k].getRow()==i){
cs[k] = cs[cs.length-1];
cs = Arrays.copyOf(cs, cs.length-1);
k--;
}
}
for(int k=0;k<cs.length;k++){
if(cs[k].getRow()<i){
cs[k].setRow(cs[k].getRow()+1);
}
}
}
}
b = new boolean[20][10];
for(int i=0;i<cs.length;i++){
b[cs[i].getRow()][cs[i].getCol()] = true;
}
}
/**
* 到底边
*/
private void hitBoundAction() {
Cell[] cells = currentOne.cells;
for(int i=0;i<cells.length;i++){
if(currentOne.hitBound()){
for(int j=0;j<cells.length;j++){
cs = Arrays.copyOf(cs, cs.length+1);
cs[cs.length-1] = cells[j];
b[cs[cs.length-1].getRow()][cs[cs.length-1].getCol()] = true;
}
currentOne = currentNext;
currentNext = Tetromino.randomOne();
break;
}
}
}
/**
* 方块间的碰撞
*/
protected void hitAction() {
for(int i=0;i<cs.length;i++){
if(currentOne.hit(cs[i])){
Cell[] cells = currentOne.cells;
for(int j=0;j<cells.length;j++){
cs = Arrays.copyOf(cs, cs.length+1);
cs[cs.length-1] = cells[j];
b[cs[cs.length-1].getRow()][cs[cs.length-1].getCol()] = true;
}
currentOne = currentNext;
currentNext = Tetromino.randomOne();
break;
}
}
}
/**
* 左右边界
*/
protected void outOfBoundAction() {
Cell[] cells = currentOne.cells;
for(int i=0;i<cells.length;i++){
if(cells[i].getCol()<0){
for(int j=0;j<cells.length;j++){
cells[j].setCol(cells[j].getCol()+1);
}
break;
}else if(cells[i].getCol()>9){
for(int j=0;j<cells.length;j++){
cells[j].setCol(cells[j].getCol()-1);
}
break;
}
}
}
public static void main(String[] args) {
//创建一个游戏窗口
JFrame frame = new JFrame("俄罗斯方块");
//设计窗口的大小
frame.setSize(540, 588);
//创建一个画板对象
TestTetromino panel = new TestTetromino();
//画板嵌入窗口
frame.add(panel);
//设置窗口居中
frame.setLocationRelativeTo(null);
//设置窗口关闭
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
//设置可见性
frame.setVisible(true);
panel.action();
}
}
用到的图片可以自己在网上寻找*_*