Tetris类
private int state;
public static final int RUNNING=0;
public static final int PAUSE=1;
public static final int GAME_OVER=2;
private int score;
private int lines;//销毁的行数
private Cell[][] wall;//背景墙
private Tetromino tetromino;
private Tetromino nextOne;
public static final int ROWS=20;
public static final int COLS=10;
private static BufferedImage background;
public static BufferedImage T;
public static BufferedImage S;
public static BufferedImage I;
public static BufferedImage L;
public static BufferedImage J;
public static BufferedImage O;
public static BufferedImage Z;
private static BufferedImage gameOver;
private static BufferedImage pause;
private Timer timer;
private int speed;
private int level;
private int index;
public static final int CELL_SIZE=20;
static {
try {
background=ImageIO.read(Tetris.class.getClassLoader().getResource("image/background.png"));
T=ImageIO.read(Tetris.class.getClassLoader().getResource("image/diamond1.png"));
I=ImageIO.read(Tetris.class.getClassLoader().getResource("image/diamond1.png"));
S=ImageIO.read(Tetris.class.getClassLoader().getResource("image/diamond1.png"));
Z=ImageIO.read(Tetris.class.getClassLoader().getResource("image/diamond1.png"));
J=ImageIO.read(Tetris.class.getClassLoader().getResource("image/diamond1.png"));
L=ImageIO.read(Tetris.class.getClassLoader().getResource("image/diamond1.png"));
O=ImageIO.read(Tetris.class.getClassLoader().getResource("image/diamond1.png"));
gameOver=ImageIO.read(Tetris.class.getClassLoader().getResource("image/diamond1.png"));
pause=ImageIO.read(Tetris.class.getClassLoader().getResource("image/diamond1.png"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
public static void main(String args[]){
final JFrame frame=new JFrame();
Tetris tetris=new Tetris();
tetris.setBackground(new Color(0x0000ff));
frame.setSize(400, 500);
frame.setLocationRelativeTo(null);
frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
frame.setVisible(true);
JMenu file=new JMenu("菜单");
JMenuItem explandItem=new JMenuItem("说明");
file.add(explandItem);
JMenuBar mb=new JMenuBar();
mb.add(file);
frame.setJMenuBar(mb);
frame.add(tetris);
final JLabel jlabel=new JLabel();
jlabel.setText("Q is quit\n"+"P is pause\n"+"C is running");
explandItem.addActionListener(new ActionListener(){
@Override
public void actionPerformed(ActionEvent e) {
switch(e.getActionCommand()){
case "说明":
JDialog dialog=new JDialog(frame, "使用说明", JDialog.DEFAULT_MODALITY_TYPE);
dialog.add(jlabel);
dialog.setSize(300, 300);
dialog.setLocationRelativeTo(null);
dialog.setVisible(true);
}
}
});
tetris.action();
}
//添加上paint,它就不会显示背景的蓝色了
public void paint(Graphics g){
g.drawImage(background, 0, 0, null);
g.translate(15, 15);
paintWall(g);
paintTetromion(g);
paintNextOne(g);
paintScore(g);
paintState(g);
}
private void paintState(Graphics g) {
switch(state){
case PAUSE:
g.drawImage(pause, 15, 15, null);
break;
case GAME_OVER:
g.drawImage(gameOver,15, 15, null);
break;
}
}
public static final int FONT_COLOR=0x667799;
public static final int FONT_SIZE=30;
public void paintScore(Graphics g){
int x=210;
int y=160;
g.setColor(new Color(FONT_COLOR));
Font font=g.getFont();
font=new Font(font.getName(),font.getStyle(),FONT_SIZE);
g.setFont(font);
String str="SCORE :"+score;
g.drawString(str, x, y);
y+=56;
str="LINES:"+lines;
g.drawString(str, x, y);
y+=56;
g.drawString("LEVEL"+level, x, y);
}
public void paintNextOne(Graphics g){
if(nextOne==null){
return;
}
Cell cells[]=nextOne.cells;
for(int i=0;i<cells.length;i++){
Cell cell=cells[i];
int x=(cell.getCol()+10)*CELL_SIZE;
int y=cell.getRow()*CELL_SIZE;
g.drawImage(cell.getImage(), x, y, null);
}
}
public void Tetromino(){
}
public void paintWall(Graphics g){
for(int i=0;i<wall.length;i++){
Cell cell[]=wall[i];
for(int j=0;j<cell.length;j++){
Cell cell1=cell[j];
int x=j*CELL_SIZE;
int y=i*CELL_SIZE;
if(cell1==null){
g.drawRect(x, y, CELL_SIZE, CELL_SIZE);
}
else{
g.drawImage(cell1.getImage(), x, y, null);
}
}
}
}
public void startAction(){
}
public void action(){
wall =new Cell[ROWS][COLS];
tetromino=nextOne;
tetromino=Tetromino.randomOne();
nextOne=Tetromino.randomOne();
KeyAdapter l=new KeyAdapter(){
@Override
public void keyPressed(KeyEvent e) {
int key=e.getKeyCode();
switch(state){
case GAME_OVER:
break;
case PAUSE:
processGameoverKey(key);
break;
case RUNNING:
processRunningKey(key);
break;
}
repaint();
}
};
this.requestFocus();
this.addKeyListener(l);
timer=new Timer();
timer.schedule(new TimerTask(){
@Override
public void run() {
speed=40-(lines/100);
speed=speed<1?1:speed;
level=41-speed;
if(state==RUNNING&&index%speed==0){
softDropAction();
}
index++;
repaint();
}
}, 10,10);
}
private void processGameoverKey(int key) {
switch(key){
case KeyEvent.VK_Q:
System.exit(0);
break;
case KeyEvent.VK_S:
this.lines=0;
this.score=0;
this.wall=new Cell[ROWS][COLS];
this.tetromino=Tetromino.randomOne();
this.nextOne=Tetromino.randomOne();
this.state=RUNNING;
this.index=0;
break;
}
}
private void processRunningKey(int key) {
switch(key){
case KeyEvent.VK_DOWN:
processPauseKey(key);
softDropAction();
break;
case KeyEvent.VK_RIGHT:
moveRightAction();
break;
case KeyEvent.VK_LEFT:
moveLeftAction();
break;
case KeyEvent.VK_SPACE:
hardDropAction();
break;
case KeyEvent.VK_UP:
rotateRightAction();
break;
case KeyEvent.VK_P:
state=PAUSE;
break;
}
}
private void processPauseKey(int key) {
switch(key){
case KeyEvent.VK_Q:
System.exit(0);
break;
case KeyEvent.VK_C:
state=RUNNING;
break;
}
}
public void paintTetromion(Graphics g){
if(tetromino==null){
return;
}
Cell cells[]=tetromino.cells;
for(int i=0;i<cells.length;i++){
Cell cell=cells[i];
int x=cell.getCol()*CELL_SIZE;
int y=cell.getRow()*CELL_SIZE;
g.drawImage(cell.getImage(), x, y, null);
}
}
public void checkGameOverAction(){
}
public void continueAction(){
}
public void pauseAction(){
}
public void rotateRightAction(){
tetromino.rotateRight();
if(outOfBounds()||coincide()){
tetromino.rotateLeft();
}
}
public void hardDropAction(){
while(canDrop()){
tetromino.softDrop();
}
landIntoWall();
destoryLines();
tetromino=nextOne;
nextOne=Tetromino.randomOne();
}
public void softDropAction(){
if(canDrop()){
tetromino.softDrop();
}else{
landIntoWall();
destoryLines();
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(wall[row][col]!=null){
return true;
}
}
return false;
}
private static int[] scoreTable={0,1,10,50,100};
public void landIntoWall(){
Cell[] cells=tetromino.cells;
for(int i=0;i<cells.length;i++){
Cell cell=cells[i];
int row=cell.getRow();
int col=cell.getCol();
wall[row][col]=cell;
}
}
public void destoryLines(){
int lines=0;
for(int row=0;row<wall.length;row++){
if(fullCells(row)){
deleteRow(row);
lines++;
}
}
this.score+=scoreTable[lines];
this.lines+=lines;
}
public boolean fullCells(int row){
Cell[] line=wall[row];
for(Cell cell:line){
if(cell==null){
return false;
}
}
return true;
}
public void deleteRow(int row){
for(int i=row;i>1;i--){
System.arraycopy(wall[i-1], 0, wall[i], 0, COLS);
}
Arrays.fill(wall[0], null);
}
public 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&&wall[row][col]!=null){
return false;
}
}
return true;
}
public void moveLeftAction(){
tetromino.moveLeft();
if(outOfBounds()||coincide()){
tetromino.moveRight();
}
}
public void moveRightAction(){
tetromino.moveRight();
if(outOfBounds()||coincide()){
tetromino.moveLeft();
}
}
public 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;
}
public boolean coincide(){
Cell cells[]=tetromino.cells;
for(int i=0;i<cells.length;i++){
Cell cell=cells[i];
int col=cell.getCol();
int row=cell.getRow();
//有问题。只要有一个砖块满足这个条件就行了吗?
if(row>=0&&row<ROWS&&col<=COLS&&col>=0&&wall[row][col]!=null){
return true;
}
}
return false;
}
Tetromino类
public abstract class Tetromino {
Cell cells[]=new Cell[4];
State states[];
int index=10000;
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);
}
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 rotateRight(){
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);
}
/**
* 随机生产4个格子的方块
* @return
*/
public static Tetromino randomOne(){
Random random=new Random();
int type=random.nextInt(7);
switch(type){
case 0:
return new T();
case 1:
return new I();
case 2:
return new S();
case 3:
return new J();
case 4:
return new L();
case 5:
return new Z();
case 6:
return new O();
}
return null;
}
/*
*
* 方块下落
*/
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();
}
}
public String toString(){
return Arrays.toString(cells);
}
}
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 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 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 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);
}
}
class S extends Tetromino{
public S(){
cells[0]=new Cell(1,4,Tetris.S);
cells[1]=new Cell(1,3,Tetris.S);
cells[2]=new Cell(0,4,Tetris.S);
cells[3]=new Cell(0,5,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);
}
}
Celll类
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 void drop(){
row++;
}
public void moveRight(){
col++;
}
public void moveLeft(){
col--;
}
public String toString(){
return "";
}
public BufferedImage getImage() {
return image;
}
public void setImage(BufferedImage image) {
this.image = image;
}
}
图片是在新建的image的包下