cs106a编程方法学作业解答(3)
此次作业要求我们做一个简单的打砖块游戏。
1 * File: Breakout.java 2 * ------------------- 3 * Name: 4 * Section Leader: 5 * 6 * This file will eventually implement the game of Breakout. 7 */ 8 9 import acm.graphics.*; 10 import acm.program.*; 11 import acm.util.*; 12 import java.applet.*; 13 import java.awt.*; 14 import java.awt.event.*; 15 16 public class Breakout extends GraphicsProgram { 17 18 /** Width and height of application window in pixels */ 19 public static final int APPLICATION_WIDTH = 400; 20 public static final int APPLICATION_HEIGHT = 600; 21 22 /** Dimensions of game board (usually the same) */ 23 private static final int WIDTH = APPLICATION_WIDTH; 24 private static final int HEIGHT = APPLICATION_HEIGHT; 25 26 /** Dimensions of the paddle */ 27 private static final int PADDLE_WIDTH = 60; 28 private static final int PADDLE_HEIGHT = 10; 29 30 /** Offset of the paddle up from the bottom */ 31 private static final int PADDLE_Y_OFFSET = 30; 32 33 /** Number of bricks per row */ 34 private static final int NBRICKS_PER_ROW = 10; 35 36 /** Number of rows of bricks */ 37 private static final int NBRICK_ROWS = 10; 38 39 /** Separation between bricks */ 40 private static final int BRICK_SEP = 4; 41 42 /** Width of a brick */ 43 private static final int BRICK_WIDTH = 44 (WIDTH - (NBRICKS_PER_ROW - 1) * BRICK_SEP) / NBRICKS_PER_ROW; 45 46 /** Height of a brick */ 47 private static final int BRICK_HEIGHT = 8; 48 49 /** Radius of the ball in pixels */ 50 private static final int BALL_RADIUS = 10; 51 52 /** Offset of the top brick row from the top */ 53 private static final int BRICK_Y_OFFSET = 70; 54 55 /** Number of turns */ 56 private static final int NTURNS = 3; 57 58 private static final int DELAY=10; 59 60 61 /** Runs the Breakout program. */ 62 public void run() { 63 setup(); 64 waitForClick(); 65 ballbouncing(); 66 67 68 } 69 public void setup(){ //初始化 70 GRect brick; //按要求添加排列好的砖块 71 int X=(WIDTH-NBRICKS_PER_ROW*BRICK_WIDTH-(NBRICKS_PER_ROW-1)*BRICK_SEP)/2; 72 int Y=(BRICK_WIDTH+BRICK_SEP); 73 int Z=(BRICK_HEIGHT+BRICK_SEP); 74 for(int i=0;i<NBRICK_ROWS;i++){ 75 for(int j=0;j<NBRICKS_PER_ROW;j++){ 76 int x=X+j*Y; 77 int y=BRICK_Y_OFFSET+i*Z; 78 brick=new GRect(x,y,BRICK_WIDTH,BRICK_HEIGHT); 79 add(brick); 80 } 81 } 82 for(int i=0;i<NBRICKS_PER_ROW;i++){ //按列给砖块染色 83 GObject Brick; 84 Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET); 85 ((GRect) Brick).setFilled(true); 86 ((GRect) Brick).setFillColor(Color.RED); 87 Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+Z); 88 ((GRect) Brick).setFilled(true); 89 ((GRect) Brick).setFillColor(Color.RED); 90 Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+2*Z); 91 ((GRect) Brick).setFilled(true); 92 ((GRect) Brick).setFillColor(Color.ORANGE); 93 Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+3*Z); 94 ((GRect) Brick).setFilled(true); 95 ((GRect) Brick).setFillColor(Color.ORANGE); 96 Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+4*Z); 97 ((GRect) Brick).setFilled(true); 98 ((GRect) Brick).setFillColor(Color.YELLOW); 99 Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+5*Z); 100 ((GRect) Brick).setFilled(true); 101 ((GRect) Brick).setFillColor(Color.YELLOW); 102 Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+6*Z); 103 ((GRect) Brick).setFilled(true); 104 ((GRect) Brick).setFillColor(Color.GREEN); 105 Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+7*Z); 106 ((GRect) Brick).setFilled(true); 107 ((GRect) Brick).setFillColor(Color.GREEN); 108 Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+8*Z); 109 ((GRect) Brick).setFilled(true); 110 ((GRect) Brick).setFillColor(Color.CYAN); 111 Brick = getElementAt(X+i*Y,BRICK_Y_OFFSET+9*Z); 112 ((GRect) Brick).setFilled(true); 113 ((GRect) Brick).setFillColor(Color.CYAN); 114 115 } 116 paddle=new GRect((WIDTH-PADDLE_WIDTH)/2,HEIGHT-PADDLE_HEIGHT-PADDLE_Y_OFFSET,PADDLE_WIDTH,PADDLE_HEIGHT); //初始化板子 117 paddle.setFilled(true); 118 add(paddle); 119 addMouseListeners(); 120 ball=new GOval(WIDTH/2-BALL_RADIUS,HEIGHT/2-BALL_RADIUS,2*BALL_RADIUS,2*BALL_RADIUS); //初始化球和球速,其中球的水平速度由随机数决定 121 ball.setFilled(true); 122 vx =vx = rgen.nextDouble(1.0, 3.0); 123 if (rgen.nextBoolean(0.5)) vx = -vx; 124 vy= 3.0; 125 126 127 128 } 129 130 public void mouseMoved(MouseEvent e){ //实现鼠标左右移动对板子的控制 131 132 last=new GPoint(paddle.getX(),paddle.getY()); 133 if((paddle.getX()+e.getX()-last.getX()>0)&&(paddle.getX()+e.getX()-last.getX()<WIDTH-PADDLE_WIDTH)){ 134 paddle.move(e.getX()-last.getX(), 0); 135 last=new GPoint(paddle.getX(),paddle.getY()); 136 } 137 138 } 139 public void ballbouncing(){ //游戏循环体 140 add(ball); 141 while((remainlives!=0)&&(num_remainbricks!=0)){ 142 moveball(); 143 checkforcollision(); 144 pause(DELAY); 145 146 147 } 148 if(num_remainbricks==0){ 149 add(congraduation); 150 } 151 if(remainlives==0){ 152 add(sorry); 153 } 154 } 155 private void moveball(){ 156 ball.move(vx,vy); 157 158 } 159 private void checkforcollision(){ //实现碰撞机理 160 if(ball.getY()>HEIGHT-2*BALL_RADIUS){ //检测是否触底,并修正了超过边界的运动量,下面类似 161 vy=-vy; 162 double diff=ball.getY()-(HEIGHT-2*BALL_RADIUS); 163 ball.move(0,-diff); 164 remainlives--; 165 } 166 if(ball.getX()>WIDTH-2*BALL_RADIUS){ 167 vx=-vx; 168 } 169 if(ball.getX()<0){ 170 vx=-vx; 171 } 172 if(ball.getY()<0){ 173 vy=-vy; 174 } 175 collider=getCollidingObject(); 176 if((collider!=null)&&(collider!=paddle)){ //碰到砖块 177 178 num_remainbricks=num_remainbricks-1; 179 remove(collider); 180 bounceClip.play(); 181 collider=null; 182 } 183 if(getElementAt(paddle.getX(),paddle.getY()-1)!=null){ //增加板子两个角触球使得球原路弹回的设定。同样修正了超过边界的运动量 184 vx=-vx; 185 vy=-vy; 186 double diff1=ball.getY()+2*BALL_RADIUS-paddle.getY(); 187 double diff2=ball.getX()+2*BALL_RADIUS-paddle.getX(); 188 ball.move(-diff2, -diff1); 189 } 190 if(getElementAt(paddle.getX()+PADDLE_WIDTH,paddle.getY()-1)!=null){ 191 vx=-vx; 192 vy=-vy; 193 double diff1=ball.getY()+2*BALL_RADIUS-paddle.getY(); 194 double diff2=ball.getX()-paddle.getX()-PADDLE_WIDTH; 195 ball.move(-diff2, -diff1); 196 } 197 198 199 } 200 private GObject getCollidingObject(){ //判定球触碰的物体并返回这个物体,通过在球的正上下左右1像素位置设置了4个参考点实现 201 if(getElementAt(ball.getX()+BALL_RADIUS,ball.getY()-1)!=null){ 202 vy=-vy; 203 collider=getElementAt(ball.getX()+BALL_RADIUS,ball.getY()-1); 204 if(collider==paddle){ 205 double diff=ball.getY()-1-paddle.getY()-PADDLE_HEIGHT; 206 ball.move(0, -diff); 207 } 208 } 209 if(getElementAt(ball.getX()+2*BALL_RADIUS+1,ball.getY()+BALL_RADIUS)!=null){ 210 vx=-vx; 211 collider=getElementAt(ball.getX()+2*BALL_RADIUS+1,ball.getY()+BALL_RADIUS); 212 if(collider==paddle){ 213 double diff=ball.getX()+2*BALL_RADIUS+1-paddle.getX(); 214 ball.move(-diff, 0); 215 } 216 } 217 if(getElementAt(ball.getX()+BALL_RADIUS,ball.getY()+2*BALL_RADIUS+1)!=null){ 218 vy=-vy; 219 collider=getElementAt(ball.getX()+BALL_RADIUS,ball.getY()+2*BALL_RADIUS+1); 220 if(collider==paddle){ 221 double diff=ball.getY()+2*BALL_RADIUS+1-paddle.getY(); 222 ball.move(0, -diff); 223 } 224 } 225 if(getElementAt(ball.getX()-1,ball.getY()+BALL_RADIUS)!=null){ 226 vx=-vx; 227 collider=getElementAt(ball.getX()-1,ball.getY()+BALL_RADIUS); 228 if(collider==paddle){ 229 double diff=ball.getX()-1-paddle.getX()-PADDLE_WIDTH; 230 ball.move(-diff, 0); 231 } 232 } 233 return collider; 234 } 235 236 237 238 239 AudioClip bounceClip = MediaTools.loadAudioClip("bounce.au"); 240 private GLabel congraduation=new GLabel("You Win!",100,100); 241 private GLabel sorry=new GLabel("Sorry,You Lose!",100,50); 242 private int remainlives=NTURNS; 243 private int num_remainbricks=100; 244 private GObject collider; 245 private GRect paddle; 246 private GPoint last; 247 private RandomGenerator rgen = RandomGenerator.getInstance(); 248 private GOval ball; 249 private double vx,vy; 250 }
posted on 2014-10-15 01:18 livingisgood 阅读(610) 评论(0) 编辑 收藏 举报