基于java的俄罗斯小方块(三),code code...

本文详细介绍了如何在Java中开发俄罗斯方块游戏,包括游戏逻辑的设计、方块移动与旋转的实现、碰撞检测、障碍物生成及消除满行等功能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

接着上一篇,继续---------------------------------

碰到游戏面板的边界时,要让方块做出反应。碰左壁,不能再向左移。碰右壁,不能再向右移

在Global.java添加两个常量

   public static final int WIDTH=15;

   public static final int HEIGHT=15;

修改GamePanel.java的大小

   @Override

   protected void paintComponent(Graphicsg) {

      //重新显示

      super.paintComponent(g);

      g.fillRect(0, 0, Global.WIDTH*Global.CELL_SIZE,Global.HEIGHT*Global.CELL_SIZE);

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

      if(shape!=null && ground!=null){

      shape.drawMe(g);

      ground.drawMe();

      }

   }

  

   public GamePanel(){

      this.setSize(Global.WIDTH*Global.CELL_SIZE,Global.HEIGHT*Global.CELL_SIZE);

   }

 

在Shape.java中添加几个方向常量

public classShape {

   public static final int ROTATE=0;

   public static final int LEFT=1;

   public static final int RIGHT=2;

   public static final int DOWN=3;

 

在Shape.java中添加取得方块坐标的方法和判断是否自己成员的方法

   public int getTop(){

      return top;

   }

   public int getLeft(){

      return left;

   }

   public boolean isMember(int x,int y,boolean rotate){

      int tempStatus=status;

      if(rotate){

         tempStatus=(status+1)%body.length;

      }

      return body[tempStatus][y*4+x]==1;

   }

在Ground.java中添加如下方法

public boolean isMoveable(Shape shape,int action){

      int left=shape.getLeft();

      int top=shape.getTop();

      switch(action){

      case Shape.LEFT:

         left--;

         break;

      case Shape.RIGHT:

         left++;

         break;

      case Shape.DOWN:

         top++;

         break;

      }

      for(int x=0;x<4;x++){

         for(int y=0;y<4;y++){

            if(shape.isMember(x, y,action==Shape.ROTATE)){

                if(top+y>=Global.HEIGHT ||

                      left+x<0||

                      left+x>=Global.WIDTH)

                   return false;

            }

         }

      }

      return true;

   }

 

在Controller.java下添加如下代码

   @Override

   public void keyPressed(KeyEvent e){

      // TODO Auto-generated method stub

      super.keyPressed(e);

      switch (e.getKeyCode()) {

      case KeyEvent.VK_LEFT:

         if(ground.isMoveable(shape,Shape.LEFT))

         shape.moveLeft();

         break;

      case KeyEvent.VK_UP:

         if(ground.isMoveable(shape, Shape.ROTATE))

         shape.rotate();

         break;

      case KeyEvent.VK_RIGHT:

         if(ground.isMoveable(shape,Shape.RIGHT))

         shape.moveRight();

         break;

      case KeyEvent.VK_DOWN:

         if(ground.isMoveable(shape,Shape.DOWN))

            shape.moveDown();

      default:

         break;

      }

      gamePanel.display(ground, shape);

   }

 

在ShapeListener.java下添加一个抽象方法

public interfaceShapeListener {

   void shapeMoveDown(Shapeshape);

  

   booleanisShapeMoveDownable(Shapeshape);

}

 

修改实现该接口的类Controller.java

   @Override

   public boolean isShapeMoveDownable(Shape shape) {

      boolean result=ground.isMoveable(shape,Shape.DOWN);

      return result;

   }

修改Shape.java的定时下落

   private class ShapeDriver implements Runnable {

 

      @Override

      public void run() {

         // 定时向下落

         while (listener.isShapeMoveDownable(Shape.this)){

            moveDown();

            listener.shapeMoveDown(Shape.this);

            try {

                Thread.sleep(1000);

            }catch(InterruptedException e) {

                // TODO Auto-generated catch block

                e.printStackTrace();

            }

         }

      }

 

   }

 

将图形变成障碍物和显示

 

修改Controller类的方法isShapeMoveDownable为同步。

   @Override

   public synchronizedboolean isShapeMoveDownable(Shape shape) {

      boolean result=ground.isMoveable(shape,Shape.DOWN);

      return result;

   }

 

修改Controller类的方法isShapeMoveDownable,图形到达底部,产生新图形

   @Override

   public synchronized boolean isShapeMoveDownable(Shape shape) {

      if(ground.isMoveable(shape,Shape.DOWN))

         return true;

      ground.accept(this.shape);

      this.shape=shapeFactory.getShape(this);

      return false;

   }

在Ground.java中添加增加障碍物,显示障碍物的判断

public classGround {

   private int[][] obstacles=new int[Global.WIDTH][Global.HEIGHT];

   public void accept(Shape shape){

      System.out.println("把方块变成障碍物");

      for(int x=0;x<4;x++){

         for(int y=0;y<4;y++){

            if(shape.isMember(x, y, false)){

                obstacles[shape.getLeft()+x][shape.getTop()+y]=1;

            }

         }

      }

   }

   public void drawMe(Graphics g){

      System.out.println("画出障碍物");

      for(int x=0;x<Global.WIDTH;x++){

         for(int y=0;y<Global.HEIGHT;y++){

            if(obstacles[x][y]==1){

                g.fill3DRect(x*Global.CELL_SIZE, y*Global.CELL_SIZE,

                      Global.CELL_SIZE, Global.CELL_SIZE, true);

            }

         }

      }

   }

 

修改GamePanel.java

   @Override

   protected void paintComponent(Graphicsg) {

      //重新显示

      super.paintComponent(g);

      g.fillRect(0,0, Global.WIDTH*Global.CELL_SIZE,Global.HEIGHT*Global.CELL_SIZE);

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

      if(shape!=null && ground!=null){

      shape.drawMe(g);

      ground.drawMe(g);

      }

   }

 

当碰到障碍物的时候也停止,修改GamePanel.java下的

   public boolean isMoveable(Shape shape,int action){

      int left=shape.getLeft();

      int top=shape.getTop();

      switch(action){

      case Shape.LEFT:

         left--;

         break;

      case Shape.RIGHT:

         left++;

         break;

      case Shape.DOWN:

         top++;

         break;

      }

      for(int x=0;x<4;x++){

         for(int y=0;y<4;y++){

            if(shape.isMember(x,y,action==Shape.ROTATE)){

                if(top+y>=Global.HEIGHT ||

                      left+x<0||

                      left+x>=Global.WIDTH ||

                      1==obstacles[left+x][top+y])

                   return false;

            }

         }

      }

      return true;

   }

 

 

消除满行的障碍物

这一行没有空白,则这一行就是满行了。

上面所有的行,整体下移一行

在Ground.java下添加

   public void accept(Shape shape){

      System.out.println("把方块变成障碍物");

      for(int x=0;x<4;x++){

         for(int y=0;y<4;y++){

            if(shape.isMember(x, y, false)){

                obstacles[shape.getLeft()+x][shape.getTop()+y]=1;

            }

         }

      }

      deleteFullLine();

   }

   private void deleteFullLine(){

      for(int y=Global.HEIGHT-1;y>0;y--){

         boolean full=true;

         for(int x=0;x<Global.WIDTH;x++){

            if(0==this.obstacles[x][y]){

                full=false;

            }

         }

         if(full){

               deleteLine(y++);

         }

      }

   }

   private void deleteLine(int lineNum) {

      for(int y=lineNum;y>0;y--){

         for(int x=0;x<Global.WIDTH;x++){

            this.obstacles[x][y]=this.obstacles[x][y-1];

         }

      }

      for(int x=0;x<Global.WIDTH;x++){

         this.obstacles[x][0]=0;

      }

   }

 

增加游戏结束功能

如果有的障碍物超出了上边界,就是游戏结束

第一行如果有障碍物,就是游戏结束

在Ground.java下添加

   public boolean isFull(){

      for(int x=0;x<Global.WIDTH;x++){

         if(1==this.obstacles[x][0]){

            return true;

         }

      }

      return false;

   }

 

在Controller.java下判断

@Override

   public synchronized booleanisShapeMoveDownable(Shape shape) {

      if(ground.isMoveable(shape,Shape.DOWN))

         return true;

      ground.accept(this.shape);

      if(!ground.isFull()){

      this.shape=shapeFactory.getShape(this);

      }else{

         System.out.println("game over");

      }

      return false;

   }

 

解决定时下落与按下键同时生成障碍物的问题

在controller.java中修改

@Override

   public void keyPressed(KeyEvent e){

      // TODO Auto-generated method stub

      super.keyPressed(e);

      switch (e.getKeyCode()) {

      case KeyEvent.VK_LEFT:

         if(ground.isMoveable(shape, Shape.LEFT))

         shape.moveLeft();

         break;

      case KeyEvent.VK_UP:

         if(ground.isMoveable(shape, Shape.ROTATE))

         shape.rotate();

         break;

      case KeyEvent.VK_RIGHT:

         if(ground.isMoveable(shape, Shape.RIGHT))

         shape.moveRight();

         break;

      case KeyEvent.VK_DOWN:

         if(this.isShapeMoveDownable(shape))

            shape.moveDown();

      default:

         break;

      }

      gamePanel.display(ground, shape);

   }

 

@Override

   public synchronized booleanisShapeMoveDownable(Shape shape) {

      if(this.shape!=shape){

         returnfalse;

      }

     

      if(ground.isMoveable(shape,Shape.DOWN))

         return true;

      ground.accept(this.shape);

      if(!ground.isFull()){

      this.shape=shapeFactory.getShape(this);

      }else{

         System.out.println("game over");

       

      }

      return false;

   }


后续问题:

给游戏添加各种形状的图形

解决游戏时的画面闪烁问题



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值