首页 > 代码库 > cs106a编程方法学作业解答(3)

cs106a编程方法学作业解答(3)

此次要求我们做一个打砖块的游戏。打砖块相信大家都玩过,介绍什么的就略去了。直接贴代码:

  1 /*  2  * File: Breakout.java  3  * -------------------  4  * Name:  5  * Section Leader:  6  *   7  * This file will eventually implement the game of Breakout.  8  */  9  10 import acm.graphics.*; 11 import acm.program.*; 12 import acm.util.*; 13 import java.applet.*; 14 import java.awt.*; 15 import java.awt.event.*; 16  17 public class Breakout extends GraphicsProgram { 18  19 /** Width and height of application window in pixels */ 20     public static final int APPLICATION_WIDTH = 400; 21     public static final int APPLICATION_HEIGHT = 600; 22  23 /** Dimensions of game board (usually the same) */ 24     private static final int WIDTH = APPLICATION_WIDTH; 25     private static final int HEIGHT = APPLICATION_HEIGHT; 26  27 /** Dimensions of the paddle */ 28     private static final int PADDLE_WIDTH = 60; 29     private static final int PADDLE_HEIGHT = 10; 30  31 /** Offset of the paddle up from the bottom */ 32     private static final int PADDLE_Y_OFFSET = 30; 33  34 /** Number of bricks per row */ 35     private static final int NBRICKS_PER_ROW = 10; 36  37 /** Number of rows of bricks */ 38     private static final int NBRICK_ROWS = 10; 39  40 /** Separation between bricks */ 41     private static final int BRICK_SEP = 4; 42  43 /** Width of a brick */ 44     private static final int BRICK_WIDTH = 45       (WIDTH - (NBRICKS_PER_ROW - 1) * BRICK_SEP) / NBRICKS_PER_ROW; 46  47 /** Height of a brick */ 48     private static final int BRICK_HEIGHT = 8; 49  50 /** Radius of the ball in pixels */ 51     private static final int BALL_RADIUS = 10; 52  53 /** Offset of the top brick row from the top */ 54     private static final int BRICK_Y_OFFSET = 70; 55  56 /** Number of turns */ 57     private static final int NTURNS = 3; 58      59     private static final int DELAY=10; 60      61  62 /** Runs the Breakout program. */ 63     public void run() { 64         setup(); 65         waitForClick(); 66         ballbouncing(); 67          68          69     } 70     public void setup(){                   //初始化砖块的位置和颜色 71         GRect brick; 72         int X=(WIDTH-NBRICKS_PER_ROW*BRICK_WIDTH-(NBRICKS_PER_ROW-1)*BRICK_SEP)/2; 73         int Y=(BRICK_WIDTH+BRICK_SEP); 74         int Z=(BRICK_HEIGHT+BRICK_SEP); 75         for(int i=0;i<NBRICK_ROWS;i++){   //添加砖块 76             for(int j=0;j<NBRICKS_PER_ROW;j++){ 77                int x=X+j*Y; 78                int y=BRICK_Y_OFFSET+i*Z; 79                brick=new GRect(x,y,BRICK_WIDTH,BRICK_HEIGHT); 80                add(brick); 81             } 82         } 83         for(int i=0;i<NBRICKS_PER_ROW;i++){    //按列循环给砖块染色 84              GObject Brick; 85              Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET); 86              ((GRect) Brick).setFilled(true); 87              ((GRect) Brick).setFillColor(Color.RED); 88              Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+Z); 89              ((GRect) Brick).setFilled(true); 90              ((GRect) Brick).setFillColor(Color.RED); 91              Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+2*Z); 92              ((GRect) Brick).setFilled(true); 93              ((GRect) Brick).setFillColor(Color.ORANGE); 94              Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+3*Z); 95              ((GRect) Brick).setFilled(true); 96              ((GRect) Brick).setFillColor(Color.ORANGE); 97              Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+4*Z); 98              ((GRect) Brick).setFilled(true); 99              ((GRect) Brick).setFillColor(Color.YELLOW);100              Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+5*Z);101              ((GRect) Brick).setFilled(true);102              ((GRect) Brick).setFillColor(Color.YELLOW);103              Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+6*Z);104              ((GRect) Brick).setFilled(true);105              ((GRect) Brick).setFillColor(Color.GREEN);106              Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+7*Z);107              ((GRect) Brick).setFilled(true);108              ((GRect) Brick).setFillColor(Color.GREEN);109              Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+8*Z);110              ((GRect) Brick).setFilled(true);111              ((GRect) Brick).setFillColor(Color.CYAN);112              Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+9*Z);113              ((GRect) Brick).setFilled(true);114              ((GRect) Brick).setFillColor(Color.CYAN);115             116         }117         paddle=new GRect((WIDTH-PADDLE_WIDTH)/2,HEIGHT-PADDLE_HEIGHT-PADDLE_Y_OFFSET,PADDLE_WIDTH,PADDLE_HEIGHT);   //初始化板子118         paddle.setFilled(true);119         add(paddle);120         addMouseListeners();121         ball=new GOval(WIDTH/2-BALL_RADIUS,HEIGHT/2-BALL_RADIUS,2*BALL_RADIUS,2*BALL_RADIUS);                       //初始化球和球速122         ball.setFilled(true);123         vx =vx = rgen.nextDouble(1.0, 3.0);124         if (rgen.nextBoolean(0.5)) vx = -vx;125         vy= 3.0;126         127         128         129     }130     131     public void mouseMoved(MouseEvent e){132              133              last=new GPoint(paddle.getX(),paddle.getY());134              if((paddle.getX()+e.getX()-last.getX()>0)&&(paddle.getX()+e.getX()-last.getX()<WIDTH-PADDLE_WIDTH)){135                   paddle.move(e.getX()-last.getX(), 0);136                   last=new GPoint(paddle.getX(),paddle.getY());137              }138         139     }140     public void ballbouncing(){             //运行部分141         add(ball);142         while((remainlives!=0)&&(num_remainbricks!=0)){143             moveball();144             checkforcollision();145             pause(DELAY);146             147             148         }149         if(num_remainbricks==0){          //胜利150             add(congraduation);151         }152         if(remainlives==0){               //失败153             add(sorry);154         }155     }156     private void moveball(){157         ball.move(vx,vy);158         159     }160     private void checkforcollision(){                            //完成碰撞的动作161         if(ball.getY()>HEIGHT-2*BALL_RADIUS){                    //检测是否触底162             vy=-vy;163             double diff=ball.getY()-(HEIGHT-2*BALL_RADIUS);      //修正超出边界的运动,后面类似164             ball.move(0,-diff); 165             remainlives--;166         }167         if(ball.getX()>WIDTH-2*BALL_RADIUS){                     //检测是否撞到右边界168             vx=-vx;169         }170         if(ball.getX()<0){                                       //检测是否撞到左边界171             vx=-vx;172         }173         if(ball.getY()<0){                                       //检测是否撞到天花板174             vy=-vy;175         }176         collider=getCollidingObject();                           //设置collider来判断是否接触砖块或者板子177         if((collider!=null)&&(collider!=paddle)){                //碰到砖块的情况     178             179             num_remainbricks=num_remainbricks-1;                    180             remove(collider);181             bounceClip.play();                                   //声音效果182             collider=null;183         }184         if((getElementAt(paddle.getX(),paddle.getY()-1)!=null)||(getElementAt(paddle.getX()+PADDLE_WIDTH,paddle.getY()-1)!=null)){             //增加板子上面两角搓球的功能,即能把球原路撞回去185             vx=-vx;186             vy=-vy;187         }188         189         190     }191     private GObject getCollidingObject(){                                                        //球的碰撞检测点机制,返回所撞物体192         if(getElementAt(ball.getX()+BALL_RADIUS,ball.getY()-1)!=null){                           //球正上方1个像素位置作为检测点,检测是否撞到上方,以下类似193             vy=-vy;             194             collider=getElementAt(ball.getX()+BALL_RADIUS,ball.getY()-1);195             if(collider==paddle){196                 double diff=ball.getY()-1-paddle.getY()-PADDLE_HEIGHT;197                 ball.move(0, -diff);198             }199         }200         if(getElementAt(ball.getX()+2*BALL_RADIUS+1,ball.getY()+BALL_RADIUS)!=null){201             vx=-vx;           202             collider=getElementAt(ball.getX()+2*BALL_RADIUS+1,ball.getY()+BALL_RADIUS);203             if(collider==paddle){204                 double diff=ball.getX()+2*BALL_RADIUS+1-paddle.getX();205                 ball.move(-diff, 0);206             }207         }208         if(getElementAt(ball.getX()+BALL_RADIUS,ball.getY()+2*BALL_RADIUS+1)!=null){209             vy=-vy;210             collider=getElementAt(ball.getX()+BALL_RADIUS,ball.getY()+2*BALL_RADIUS+1);211             if(collider==paddle){212                 double diff=ball.getY()+2*BALL_RADIUS+1-paddle.getY();213                 ball.move(0, -diff);214             }215         }216         if(getElementAt(ball.getX()-1,ball.getY()+BALL_RADIUS)!=null){217             vx=-vx;218             collider=getElementAt(ball.getX()-1,ball.getY()+BALL_RADIUS);219             if(collider==paddle){220                 double diff=ball.getX()-1-paddle.getX()-PADDLE_WIDTH;221                 ball.move(-diff, 0);222             }223         }224         return collider;225     }226  227     228         229         230     AudioClip bounceClip = MediaTools.loadAudioClip("bounce.au");                 231     private GLabel congraduation=new GLabel("You Win!",100,100);232     private GLabel sorry=new GLabel("Sorry,You Lose!",100,50);233     private int remainlives=NTURNS;234     private int num_remainbricks=100;235     private GObject collider;236     private GRect paddle;237     private GPoint last;238     private RandomGenerator rgen = RandomGenerator.getInstance();239     private GOval ball;240     private double vx,vy;241 }
上述代码实现了全部基本功能,还做了一些简单的扩展,例如胜利失败时的提示,板子“搓球”的功能,添加了打砖块的声音。还有一些诸如随着游戏进行球速越来越快以及计分功能则偷懒没有加上去了。

cs106a编程方法学作业解答(3)