`
rainytimes
  • 浏览: 7079 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

俄罗斯方块源代码

    博客分类:
  • J2SE
阅读更多
Email:shun_shun@21cn.com


三叶

      有几个类文件,注释写的比较详细,由于这里篇幅有限制所以我只帖出三个类,如果想添加新的图形就再写一个类,继承shape这个类,将里面的数组按照想要的形状初始化就好了,当然在RRFrame中也要做点修改,要不然新的图形怎么能显示出来,本来想写个配置文件把所有的图形初始化信息都写到里面,实在没有时间了,现在又在学oracle比较忙,~~~~~~~~希望大家能给我提点宝贵意见,谢谢, sql语句,看起来简单做起来难啊!~~~~~~~~~~~,

                  顺便说下如果有人想转载我的文章摆脱,把前面的说明也顺便一道转了

                 呵呵,帮帮兄弟烧烧人气吧.谢谢!~~~~~~~~~~~~~

-------------------------------------------------------------------------------------------------------------------------------

RRFrame.java

            import java.awt.Color;
import java.awt.Font;
import java.awt.Frame;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.Menu;
import java.awt.MenuBar;
import java.awt.MenuItem;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.KeyAdapter;
import java.awt.event.KeyEvent;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;



public class RRFrame extends Frame {




MenuBar mb=new MenuBar();

Menu    m_control=new Menu("控制");

Menu m_about=new Menu("关于");

MenuItem mit_Start = new MenuItem("Strat(F2)");
MenuItem mit_Pause = new MenuItem("Pause(F5)");



Random rand=new Random();


public static final int step=10;//网格大小

public static final int GameWidth = 20;//网格宽的 个数
public static final int GameHeight = 40;//网格 高的 个数

public static final int ScreenWidth = 300;
public static final int ScreenHeight = 500;

public static final int SmallShapeX = 230;
public static final int SmallShapeY = 150;


/**
    * 记录游戏的状态,死亡时 为true
    *       运行时为false
    * */
private boolean dead = false;
/**
    * 记录游戏的状态,暂停时为 true
    *       运行时为 false
    * */
private boolean pause = false;

/**
    * 
    * 记录得分规则为:
    *     基础得分(100)*
    *  
    * */
public int source = 0;
/**
    * 游戏死亡的高度
    * 
    * */
public int DeadHeight = 1;

/**
    * 
    * 双缓冲屏幕所用的图片
    * 
    * */
Image offScreenImage = null;


/**
    * 
    * 记录整个游戏图形堆积的信息;
    * 
    * */
byte[][] DataStruct=new byte[GameHeight][GameWidth];


/**
    * 当前正在操作的图形;
    * */
Shape shape = null;

/**
    * 
    * 下一个图形
    * 
    * */

Shape nextshape = null;




/**
    * 
    * 随机获取一个图形;
    * 
    * */

public Shape getShape(){
  
     Shape s = null;
   
     int i=rand.nextInt(7);

     switch(i){

     case 0 :
      s = new ShapeI(this);
      break;
     case 1 :
      s = new ShapeL(this);
      break;
     case 2 :
      s = new ShapeRec(this);
      break;
     case 3 :
      s = new ShapeJ(this);
      break;
     case 4 :
      s = new ShapeS(this);
      break;
     case 5 :
      s = new ShapeS2(this);
      break;
     case 6 :
      s = new ShapeT(this);
      break;
   
    }
   
     return s;
}



/**
    * 
    * 程序运行时的配置方法;
    * */

private void    lanuch() {
  
    this.shape = this.getShape();
    this.nextshape = this.getShape();
  
    mb.add(m_control);
    mb.add(m_about);
  
    m_control.add(mit_Start);
    m_control.add(mit_Pause);
  
    mit_Start.addActionListener(new ActionListener(){
     public void actionPerformed(ActionEvent e){
      restart();
     }
    });
    mit_Pause.addActionListener(new ActionListener(){
     public void actionPerformed(ActionEvent e){
      pauseAction();
     }
    });
  
    this.setMenuBar(mb);
  
  
  
  
    this.setLocation(200,200);
    this.setSize(ScreenWidth,ScreenHeight);
  
  
  
    this.addKeyListener(new KeyMonitor());
  
  
    this.addWindowListener(new WindowAdapter(){
     public void windowClosing(WindowEvent e){
      System.exit(0);
     }
    });
    this.setVisible(true);
  
    new Thread(new Repaint()).start();
  
  
  
}


public void paint(Graphics g){

    this.drawNextShape(g);
    this.drawDataStruct(g);
    this.gameOver(g);
    shape.draw(g);
  
    this.drawSource(g);
  
  
    this.drawPause(g);
  
  
  
  
}

/**
    * 显示游戏得分情况
    * 
    * */

public void drawSource(Graphics g){
  

    Font f=new Font("隶书",20,20);
  
    Font fg=g.getFont();
  
  
    g.setFont(f);
  
    g.drawString("Source:", 210, 80);
    g.drawString(""+source, 230, 100);
  
    g.setFont(fg);
}


/**
    * 
    * 双缓冲方法
    * */
public void update(Graphics g){
  
    if(offScreenImage==null)
     offScreenImage=this.createImage(ScreenWidth,ScreenHeight);
  
    Graphics goffScreenImage=offScreenImage.getGraphics();
  
    Color c=goffScreenImage.getColor();
  
    goffScreenImage.setColor(Color.GREEN);
    goffScreenImage.fillRect(0, 0, ScreenWidth,ScreenHeight);
    
    goffScreenImage.setColor(c);
  
    paint(goffScreenImage);
  
    g.drawImage(offScreenImage, 0, 0, null);
  
  
  
  
  
  
}

/**
    * 将整个游戏的数据结构变成图形显示在屏幕上
    * 
    * */
public void drawDataStruct(Graphics g){
  
    Color c = g.getColor();
  
    g.setColor(Color.red);
    for(int i=0;i<this.GameHeight;i++){
     for(int j=0;j<this.GameWidth;j++) {
      if(DataStruct[i][j]==0){
       g.drawRect(j*step, i*step, step, step);     
      }else {
       if(DataStruct[i][j]==1){
        g.fillOval(j*step, i*step, step, step);
       }
      }
     }
   
    }
  
    g.setColor(c);
}

/**
    * 
    * 测试游戏是否死亡的方法;
    * 
    * */

private boolean deadTest() {
  
    for(int i=0;i<DataStruct[DeadHeight].length;i++) {
     if(1 == DataStruct[DeadHeight][i]) {
      this.dead = true;
      return true;
     }
    }
  
  
  
    return false;
}


public static void main(String[] args) {
  
    RRFrame rrframe=new RRFrame();
    rrframe.lanuch();
    //rrframe.nextShape();
  
}



/**
    * 删除行的方法,当Shape调用bulid()方法时调用此方法
    * delRows(int startRow,int height)
    * 
    *    参数int startRow为DataStruct开始检测的行数,
    *    参数 int height为要检测的高度
    * 
    * 
    * */
public void delRows(int startRow,int height){
  
    boolean    rowflag=true;

    List<Integer> rowNumber =new ArrayList<Integer>();
    for(int h=startRow; h<startRow+height; h++) {
     for(int w=0; w<DataStruct[0].length; w++){
      if(DataStruct[h][w]==0){
       rowflag=false;
       break;
      }
    
     }
   
     if(rowflag)rowNumber.add(h);
     rowflag=true;
   
   
    }
    if(rowNumber.size()>0){
     source = source +Double.valueOf(100*Math.pow(2.0,(double)rowNumber.size()-1)).intValue();
    }
    for(int i=0;i<rowNumber.size();i++){

     System.arraycopy(DataStruct, 0, DataStruct, 1, rowNumber.get(i));
    }
  
  
}

/**
    * 当游戏达到死亡条件时显示 Game Over 字样
    * */

public void    gameOver(Graphics g) {
  
    if(this.deadTest()){
     Font f = new Font("隶书",60,60);
     Font of = g.getFont();
     Color c = g.getColor();
     g.setColor(new Color(100,50,50));
     g.setFont(f);
   
     g.drawString("Game Over", 20, 200);
   
   
   
     g.setColor(c);
   

     g.setFont(of);
   
   
    }
}

/**
    * 将nextshap的图形信息显示在屏幕上
    * 
    * 
    * */
public void drawNextShape(Graphics g){

    Font f=new Font("隶书",20,16);
  
    Font fg=g.getFont();
  
  
    g.setFont(f);
  
    g.drawString("Next Shape", 210, 140);
  
  
    g.setFont(fg);
  

    for(int h=0;h<nextshape.shapeData[nextshape.currentkind].length;h++){
   
     for(int w=0;w<nextshape.shapeData[nextshape.currentkind][0].length;w++){

      if(nextshape.shapeData[nextshape.currentkind][h][w]==1){
       g.fillOval(this.SmallShapeX+w*step,this.SmallShapeY+h*step,step,step);
     
      }
    
     }
   
   
    }
  
  
  

  
  
}



/**
    * 游戏重新开始的方法
    * 
    * */
private void restart(){
  
  
    for(int h=0;h<this.DataStruct.length; h++){
     for(int w=0; w<this.DataStruct[0].length;w++){
      this.DataStruct[h][w] = 0;
     }
    }
  
    this.shape = this.getShape();
    this.nextshape = this.getShape();
  
  
  
    if(true == this.dead || true == pause){
     this.dead = false;
     pause = false;
     new Thread(new Repaint()).start();
    }
  
}


private void drawPause(Graphics g){
  
    if(!pause) {
     return;
    }

    Font f=new Font("隶书",20,20);
  
    Font fg=g.getFont();
  
  
    g.setFont(f);
  
    g.drawString("PAUSE", 220, 220);

  
    g.setFont(fg);
  
}

/**
    * 处理游戏暂停的方法
    * */
private void pauseAction(){
    if(true == pause){
     pause = false;
   
     new Thread(new Repaint()).start();
   
    }else {
     pause = true;
   
     this.repaint();
   
   
   
    }
  
  
}



/**
    * 
    * 屏幕刷新线程
    * */



class Repaint implements Runnable{


public void run(){
    while(!pause && !dead){

     repaint();
     try {
    
    
       Thread.sleep(50);
   
     } catch (InterruptedException e) {
    
      e.printStackTrace();
     }
   
    }
  
  
}




}


/**
    * 
    * 键盘监听事件
    * */


class KeyMonitor extends KeyAdapter {


public void keyPressed(KeyEvent e) {
    if(e.getKeyCode() == KeyEvent.VK_F2){
     restart();
    }
  
    if(dead){
     return;
    }
    if(e.getKeyCode() == KeyEvent.VK_F5){
     pauseAction();
   
    }
  
  

    shape.keyPressed(e);

}


public void keyReleased(KeyEvent e) {
    shape.keyReleased(e);

}






}



}



-------------------------------------------------------------------------------------------------------------------------------

Shape.java



import java.awt.Graphics;
import java.awt.event.KeyEvent;
import java.util.Random;


/**
* 
* 在初始化shapeData时,要靠左上对齐
* 
* 也就是图形的左边界贴在shapeData的左边界
* 图形的下边界要贴在shapeData的右边界;
* 理由:这样只用计算图形的下边界和右边界即可,方便运算
* 例如:
*    static {
  
    shapeData=new byte[][][]{
    
      {
       {1,1},
       {0,1},
       {0,1},
     
      },
    
      {
       {0,0,1},
       {1,1,1},
     
      },
    
      {
       {1,0},
       {1,0},
       {1,1},
     
      },
    
    
    
      {
       {1,1,1},
       {1,0,0},
     
      },
   
    };
  
}

* 
* 
* 
* 
* 
* */

public class Shape {

static Random rand=new Random();
//private    Random r=new Random();

/**
    * 
    * 控制下落速度的常量
    * 也就是说没刷屏DownSpeed的次数,图形的位置下降一个单位
    * 
    * 
    * */
    private static final int DownSpeed=5;
  
  


    private int downspeedi = 0;// DownSpeed的计数器
  
// public int ShapeWidth;
// public int ShapeHeight;
  



/**
    * 这个为存储图形形状的数组
    *    byte[z][y][x]
    *     byte.length为本图形的状态数
    *     byte[z].length为图形在z状态下的高度;
    *     byte[z][0].length为图形在z状态下的宽度
    *  
    *
    * 
    * */
byte[][][] shapeData;//=new byte[ShapeHeight][ShapeWidth];

public int kind; 


public int currentkind;

private int step=RRFrame.step;

private int x = (RRFrame.GameWidth/2-2)*step;
private int y = 0;

private RRFrame rrf;
/**
    * 向左的键按下后为true
    * */
private boolean left = false;
/**
    * 向右的键按下后为true
    * */
private boolean right = false;
/**
    * 向下的键按下后为true
    * */
private boolean down = false;




public Shape(RRFrame rrf) {
    this.rrf = rrf;
  
  
  
  
  
  
}


/**
    * 
    * 画图形的方法
    * 
    * */

public void    draw(Graphics g){

  

    for(int h=0;h<shapeData[currentkind].length;h++){
   
     for(int w=0;w<shapeData[currentkind][0].length;w++){

      if(shapeData[currentkind][h][w]==1){
       g.fillOval(x+w*step,y+h*step,step,step);
     
      }
    
     }
   
   
    }
  
    move();
  
}

// public void setShape(){
//    currentkind=rand.nextInt(kind);
//    //ShapeWidth = shapeData[currentkind][0].length;
//    //ShapeHeight = shapeData[currentkind].length;
// }


/**
    * 
    * 图形旋转的方法
    * 
    * */
private void rotate(){
  
    if(!rotateTest((currentkind+1)%kind)){
     return;
    }
  
  
    this.currentkind=(currentkind+1)%kind;
//    ShapeWidth = shapeData[currentkind][0].length;
//    ShapeHeight = shapeData[currentkind].length;
  
  
  
  
  
  
  
  
}

/**
    * 
    * 检测当前图形位置是否能够旋转
    *     如果可以旋转返回true;
    *     如果不可旋转返回false;
    * 
    * */

private boolean rotateTest(int testKind) {
  
    if((rrf.GameWidth < mappedX(shapeData[testKind][0].length)) || (rrf.GameHeight < mappedY(shapeData[testKind].length))){
     return false;
    }
  
  
    for(int h=0; h<shapeData[testKind].length; h++){
     for(int w=0; w<shapeData[testKind][0].length; w++){
      if((1 == shapeData[testKind][h][w]) && (1 ==rrf.DataStruct[mappedY(h)][mappedX(w)])){
       return false;
      }
    
    
     }
   
    }
  
  
  
  
  
    return true;
} 

/**
    * 
    * 当图形所在位置符合游戏设计的堆加原则,调用此方法,
    * 改写RRFrame.DataStruct[][]的内容
    * 
    * 
    * 
    * */
private void bulid(){
  
  
    int tempw;
    int temph;
    for(int h=0; h<shapeData[currentkind].length; h++) {
     for(int w=0; w<shapeData[currentkind][0].length; w++) {
      if(shapeData[currentkind][h][w]==1) {
       tempw = x/step+w;
       temph = y/step+h;

       rrf.DataStruct[temph][tempw]=1;
     
      }
     }
    
    }
    rrf.delRows(mappedY(0), shapeData[currentkind].length);
    //rrf.shape=new ShapeI(rrf);
    rrf.shape = rrf.nextshape;
    rrf.nextshape = rrf.getShape();
}

private void move(){
  

  
  
    //控制自然落下down 的速度
    if(downspeedi%this.DownSpeed == 0 || down){
     y=y + step;
    }
    this.downspeedi ++;

  
    //控制左右的移动
    if(left && !touchLeftSide()){
     this.x = this.x - step;
   
    }else if(right && !touchRightSide()) {
     this.x = this.x + step; 
   
    }
  

    this.tuchDownObject();
  
}

/**
    * 
    * 判断碰触底边物体
    * 
    * */

private    boolean tuchDownObject() {
  
    if(rrf.GameHeight == mappedY(shapeData[currentkind].length)) {
   
     this.bulid();
     return true;
   
    }
  
    for(int h=0; h < shapeData[currentkind].length;h++){
   
     for(int w=0; w < shapeData[currentkind][0].length; w++){
      if((1 == shapeData[currentkind][h][w]) && (1 == rrf.DataStruct[mappedY(h)+1][mappedX(w)])){
       this.bulid();
       return true;
      }
     }
   
    }
  
  
    return false;
}


/**
    * 
    * 判断碰触左边物体
    * 
    * */

private boolean touchLeftSide() {

  
    if(0 == x ){
     return true;
    }
    for(int h=0; h <shapeData[currentkind].length; h++){
   
     for(int w=0; w < shapeData[currentkind][0].length; w++) {
    
      if((1 == shapeData[currentkind][h][w]) && (1 == rrf.DataStruct[mappedY(h)][mappedX(w)-1])){
     
       return true;
      }
   
     }
  
    }

    return false;

}

/**
    * 
    * 判断碰触右边物体
    * 
    * */

private boolean touchRightSide() {

  
    if(mappedX(shapeData[currentkind][0].length) == rrf.GameWidth ){
     return true;
    }
    for(int h=0; h < shapeData[currentkind].length; h++){
   
     for(int w=0; w < shapeData[currentkind][0].length; w++) {
    
      if((1 == shapeData[currentkind][h][w]) && (1 == rrf.DataStruct[mappedY(h)][mappedX(w)+1])){
     
       return true;
      }
   
     }
  
    }

    return false;

}

/**
    * 
    * 此函数是将图形内横向的点映射到,RRFrame的DataStruct中
    * 参数 int w为图形点所在的列数
    * 
    * */
private int mappedX(int w){
    int i=0;
  
    i=x/step+w;


    return i;
  
}
/**
    * 
    * 此函数是将图形内纵向的点映射到,RRFrame的DataStruct中
    * 参数 int h为图形点所在的行数
    * 
    * */
private int mappedY(int h){
    int i=0;
    i=y/step+h;

    return i;
  
}





/**
    * 
    * 响应键盘事件
    * VK_DOWN : 向下加速
    * VK_LEFT :向左移动
    * VK_RIGHT :向右移动
    * VK_SPACE :旋转图形
    * */

public void keyPressed(KeyEvent e) {
    switch(e.getKeyCode()) {
    case KeyEvent.VK_DOWN :
     down = true;
     break;
    case KeyEvent.VK_LEFT :
     this.left = true;
     break;
    case KeyEvent.VK_RIGHT :
     this.right = true;
     break;
    case KeyEvent.VK_SPACE :
     this.rotate();
     break;

    }
  
}

/**
    * 
    * 响应键盘事件
    * VK_DOWN : 向下加速
    * VK_LEFT :向左移动
    * VK_RIGHT :向右移动
    * VK_SPACE :旋转图形
    * */

public void keyReleased(KeyEvent e) {
  
    switch(e.getKeyCode()){
    case KeyEvent.VK_DOWN :
     down = false;
     break;
    case KeyEvent.VK_LEFT :
     this.left = false;
     break;
    case KeyEvent.VK_RIGHT :
     this.right = false;
     break;
  
    }

}



}



----------------------------------------------------------------------------------------------------------------------------

ShapeI.java



public class ShapeI extends Shape {







public ShapeI(RRFrame rrf) {
    super(rrf);
    shapeData=new byte[][][]{
    
      {
       {1},
       {1},
       {1},
       {1},
     
      },
    
      {
       {1,1,1,1}     
     
      },
    
    };
    kind = shapeData.length;

  

    currentkind=rand.nextInt(kind);

  
}

}


-----------------------------------------------------------------------------------------------------------------------------

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics