Java Swing实现俄罗斯方块

来源:互联网 发布:刘备 皇室 知乎 编辑:程序博客网 时间:2024/05/21 06:12
import javax.swing.*;
import javax.swing.border.*;
import java.awt.*;
import java.awt.event.*;
import java.util.*;
public class Matrix extends JPanel{
    
private JLabel matrix[][];
    
public static final int ROW = 20;
    
public static final int COLUMN = 15;
    
private MatrixModel model;
    
public Matrix(){
        
this.setLayout(new GridLayout(ROW, COLUMN));        
        init();
        Dimension size 
= new Dimension(COLUMN*20, ROW*20);
        
this.setPreferredSize(size);
        
this.setMinimumSize(size);
        
this.setMaximumSize(size);
        
this.addKeyListener(new MyKeyListener());
        
this.setFocusable(true);
        model 
= new MatrixModel(this);
    }
    
    
    
public void start(){
        model.start();
    }

    
    
private void init(){
        matrix 
= new JLabel[ROW][COLUMN];    
        JLabel label 
= null;
        
for(int i=0; i<ROW; i++){
            
for(int j=0; j<COLUMN; j++){
                label 
= new JLabel(" ");
                label.setBorder(
new LineBorder(Color.GRAY));
                label.setOpaque(
true);
                matrix[i][j] 
= label;                
                add(matrix[i][j]);
            }

        }

    }

    
    
public void displayState(int[][] state){
        
for(int i=0; i<state.length; i++){
            
for(int j=0; j<state[i].length; j++){
                
if(state[i][j] == 1){
                    matrix[i][j].setBackground(Color.red);
                }
else{
                    matrix[i][j].setBackground(Color.black);
                }

            }

        }

    }

    
    
class MyKeyListener extends KeyAdapter{
         
public void keyPressed(KeyEvent e) {
            
if(e.getKeyCode() == KeyEvent.VK_LEFT){
                model.moveLeft();
            }

            
else if(e.getKeyCode() == KeyEvent.VK_RIGHT){
                model.moveRight();
            }
else if(e.getKeyCode() == KeyEvent.VK_DOWN){
                model.down();
            }
else if(e.getKeyCode() == KeyEvent.VK_UP){
                model.rotateSharp();
            }

         }

        
    }

    
    
public static void main(String arg[]){
        JFrame frame 
= new JFrame();        
        Matrix matrix 
= new Matrix();    
        matrix.start();
        frame.add(
new JScrollPane(matrix));
        frame.pack();        
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setVisible(
true);            
    
/*
        int i[][] = {{10,20}, {11, 21}, {21, 31}};
        int j[][] = new int[3][2];
        System.arraycopy(i, 0, j, 0, i.length);
        for(int x=0; x<j.length; x++){
            for(int y=0; y<j[x].length; y++){
                System.out.print(j[x][y]+" ");
            }
            System.out.println();
        }
*/

    }

}

 
import java.util.*;
public class MatrixModel{
    
private int model[][];
    
private int sharp[][];    
    
private int state[][];
    
private int currentX, currentY;
    
private Matrix myParent;
    
private RunThread runThread;
    
private int currentIndex;
    
public MatrixModel(Matrix parent){
        myParent 
= parent;
        model 
= new int[Matrix.ROW][Matrix.COLUMN];
        state 
= new int[Matrix.ROW][Matrix.COLUMN];
        newSharp();            
    }
    
    
    
public void start(){
        runThread 
= new RunThread();
        runThread.start();
    }

    
    
private int[][] randomSharp(){
        currentIndex 
= (int)(MatrixSharp.NUMBER*Math.random());
        
return MatrixSharp.sharp[currentIndex];
    }

    
    
private synchronized boolean isMoveAvaliable(int currentX, int currentY){
        
if(currentX>Matrix.COLUMN-1){
            
return false;
        }

        
if(currentX<0){
            
for(int i=0; i<4; i++){
                
for(int j=0; j<Math.abs(currentX); j++)
                
if(sharp[i][j] != 0){
                    
return false;
                }

            }

        }

        
if(currentY<0 || currentY>Matrix.ROW-1){
            
return false;
        }

        
for(int x=0; x<4; x++){
            
for(int y=0; y<4; y++){
                
if(currentX+x>-1 && currentX+x<Matrix.COLUMN && currentY+y<Matrix.ROW ){
                    
if((sharp[y][x] & model[currentY+y][currentX+x]) != 0){
                        
return false;
                    }

                }
else{                    
                    
if(currentX+>= Matrix.COLUMN){
                        
if(sharp[y][x] != 0){
                            
return false;
                        }

                    }

                    
else if(currentY+>= Matrix.ROW){
                        
if(sharp[y][x] != 0){
                            
return false;
                        }

                    }

                }

            }

        }

        
return true;
    }

    
    
private synchronized void moveTo(int x, int y){
        
for(int i=0; i<Matrix.ROW; i++){
            
for(int j=0; j<Matrix.COLUMN; j++){
                state[i][j] 
= model[i][j];
            }

        }

        
for(int c=0; c<4; c++){
            
for(int r=0; r<4; r++){
                
if(currentX+c>-1 && currentX+c<Matrix.COLUMN && currentY+r<Matrix.ROW){
                    state[currentY
+r][currentX+c] |= sharp[r][c];
                }

            }

        }
        
        myParent.displayState(state);        
    }

    
    
public void over(){
        System.out.println(
"game over");
        runThread.end();
    }

    
    
public synchronized void moveLeft(){        
        
if(isMoveAvaliable(currentX-1, currentY)){
            currentX 
-= 1;
            moveTo(currentX, currentY);
        }

    }

    
    
public synchronized void moveRight(){
        
if(isMoveAvaliable(currentX+1, currentY)){
            currentX 
+= 1;
            moveTo(currentX, currentY);
        }
        
    }

    
    
private boolean isOver(){
        
if(currentY==0){
            
return false;
        }

        
return false;
    }

    
    
private synchronized void resetState(){
        state 
= new int[Matrix.ROW][Matrix.COLUMN];
        moveTo(currentX, currentY);
    }

    
    
public synchronized void down(){        
        
if(isMoveAvaliable(currentX, currentY+1)){
            currentY 
+= 1;
            moveTo(currentX, currentY);
        }
else{
            
if(isOver()){
                over();
                
return;
            }
            
            model 
= state;    
            check();
            resetState();
            newSharp();
        }

    }

    
    
public synchronized void check(){
        Vector clearVector 
= new Vector();
        
for(int i=Matrix.ROW-1; i>0; i--){
            
int j = 0;
            
for(; j<Matrix.COLUMN; j++){
                
if(model[i][j] == 0){
                    
break;
                }

            }

            
if(j == Matrix.COLUMN){
                clearVector.add(
new Integer(i));
            }

        }

        clearRows(clearVector);
    }

    
    
private synchronized void clearRows(Vector clearVector){
        
        
for(int i = clearVector.size(); i>0; i--){
            
int row = ((Integer)clearVector.get(i-1)).intValue();            
            
for(int j=0; j<Matrix.COLUMN; j++){
                
for(int k=row; k>=0; k--){
                    
if(k ==  0){
                        model[k][j]
=0;
                    }
else{
                        model[k][j] 
= model[k-1][j];
                    }

                }

            }

        }

    }

    
    
public synchronized void rotateSharp(){
        
int tmpIndex = currentIndex++;
        
if(currentIndex % 4 == 0){
            currentIndex 
-= 4;
        }
        
        
int[][] tmpSharp = MatrixSharp.sharp[currentIndex];        
        
if(isRotateAble(tmpSharp)){
            sharp 
= MatrixSharp.sharp[currentIndex];            
            moveTo(currentX, currentY);
        }
else{            
            currentIndex 
= tmpIndex;            
        }

    }

    
    
private synchronized boolean isRotateAble(int sharp[][]){
        
for(int x=0; x<4; x++){
            
for(int y=0; y<4; y++){
                
if((currentX+x<0 || currentX+x>=Matrix.COLUMN) ||
                        (currentY
+y<0 || currentY+y>=Matrix.ROW)){
                    
if(sharp[y][x] != 0){
                        
return false;
                    }

                }

            }

        }

        
return isMoveAvaliable(currentX, currentY);
    }

    
    
private synchronized void newSharp(){
        currentX 
= Matrix.COLUMN/2;
        currentY 
= 0;        
        sharp 
= randomSharp();
    }

    
    
class RunThread extends Thread{
        
boolean isRun = true;
        
public void end(){
            isRun 
= false;
        }

        
public void run(){
            
while(isRun){                
                down();                
                
try{
                    sleep(
500);
                }
catch(Exception e){
                    e.printStackTrace();
                }

            }

        }

    }

}


interface MatrixSharp{    
    
static int sharp[][][] = new int[][][]{
            
{{0,0,1,0},{0,0,1,0},{0,1,1,0},{0,0,0,0}},
            
{{0,0,0,0},{0,1,0,0},{0,1,1,1},{0,0,0,0}},
            
{{0,1,1,0},{0,1,0,0},{0,1,0,0},{0,0,0,0}},
            
{{0,0,0,0},{1,1,1,0},{0,0,1,0},{0,0,0,0}},
            
{{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}},
            
{{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}},
            
{{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}},
            
{{0,0,0,0},{0,1,1,0},{0,1,1,0},{0,0,0,0}},
            
{{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0}},
            
{{0,1,0,0},{0,1,0,0},{0,1,0,0},{0,1,0,0}},
            
{{1,1,1,1},{0,0,0,0},{0,0,0,0},{0,0,0,0}},
            
{{0,1,0,0},{0,1,0,0},{0,1,0,0},{0,1,0,0}},
            
{{0,0,0,0},{0,1,1,0},{0,0,1,1},{0,0,0,0}},        
            
{{0,0,1,0},{0,1,1,0},{0,1,0,0},{0,0,0,0}},
            
{{0,0,0,0},{0,1,1,0},{0,0,1,1},{0,0,0,0}},        
            
{{0,0,1,0},{0,1,1,0},{0,1,0,0},{0,0,0,0}},            
            
{{0,0,1,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}},        
            
{{0,0,1,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}},
            
{{0,0,1,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}},    
            
{{0,0,1,0},{0,0,0,0},{0,0,0,0},{0,0,0,0}},            
            
{{0,1,0,0},{0,1,0,0},{0,1,1,0},{0,0,0,0}},        
            
{{0,0,0,0},{0,0,1,0},{1,1,1,0},{0,0,0,0}},
            
{{0,1,1,0},{0,0,1,0},{0,0,1,0},{0,0,0,0}},    
            
{{0,0,0,0},{0,1,1,1},{0,1,0,0},{0,0,0,0}}            
        }
;
        
static int NUMBER = sharp.length;
}
一简单的俄罗斯方块游戏,用到了线程及gridLayout,,用JLabel的背景来控制效果,运行效率虽然低,但程序编写很方便。Matrix.java用于控制显示,MatrixModel.java用于处理变换的数据
原创粉丝点击