斯坦福CS106A作业3

这次作业是设计一个很有意思的小游戏。

  • problem1:
    这题还是比较简单的,只要看一下课本第10章即可。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
/*
* File: MouseReporter.java
* -----------------------------
* Output the location of the mouse to a label on the
* screen. Change the color of the label to red when
* the mouse touches it.
*/

import java.awt.Color;
import java.awt.event.MouseEvent;

import acm.graphics.*;
import acm.program.*;

public class MouseReporter extends GraphicsProgram {

// A constant for the x value of the label
private static final int INDENT = 20;

// This variable is visible to the entire program
// It is called an "instance" variable
private GLabel label = new GLabel("");

public void run() {
// this code already adds the label to the screen!
// run it to see what it does.
label.setFont("Courier-24");
label.setColor(Color.BLUE);

// this setLabel method takes in a "String"
// you can concatenate integers and commas as such:
label.setLabel(0 + "," + 0);

// add the label to the screen!
add(label, INDENT, getHeight()/2);

addMouseListeners();
//GObject getElementAt(double x,double y);
}

public void mouseMoved(MouseEvent e) {
last = new GPoint(e.getPoint());
gobj = getElementAt(last);
label.setLabel(e.getX()+","+e.getY());
if(gobj!=null) {
label.setColor(Color.RED);
}
}

private GObject gobj;
private GPoint last;

}
  • problem2:


这题刚看的时候确实比较复杂,但是只要根据作业的讲义一步步来就可以了,这里添加了一些补充功能,如声音,计分等等。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
/*
* File: Breakout.java
* -------------------
* Name:
* Section Leader:
*
* This file will eventually implement the game of Breakout.
*/

import acm.graphics.*;
import acm.program.*;
import acm.util.*;

import java.applet.*;
import java.awt.*;
import java.awt.event.*;
import java.awt.event.*;

public class Breakout extends GraphicsProgram {

// Dimensions of the canvas, in pixels
// These should be used when setting up the initial size of the game,
// but in later calculations you should use getWidth() and getHeight()
// rather than these constants for accurate size information.
public static final double CANVAS_WIDTH = 420;
public static final double CANVAS_HEIGHT = 600;

// Number of bricks in each row
public static final int NBRICK_COLUMNS = 10;

// Number of rows of bricks
public static final int NBRICK_ROWS = 10;

// Separation between neighboring bricks, in pixels
public static final double BRICK_SEP = 4;

// Width of each brick, in pixels
public static final double BRICK_WIDTH = Math.floor(
(CANVAS_WIDTH - (NBRICK_COLUMNS + 1.0) * BRICK_SEP) / NBRICK_COLUMNS);

// Height of each brick, in pixels
public static final double BRICK_HEIGHT = 8;

// Offset of the top brick row from the top, in pixels
public static final double BRICK_Y_OFFSET = 70;

// Dimensions of the paddle
public static final double PADDLE_WIDTH = 60;
public static final double PADDLE_HEIGHT = 10;

// Offset of the paddle up from the bottom
public static final double PADDLE_Y_OFFSET = 30;

// Radius of the ball in pixels
public static final double BALL_RADIUS = 10;

// The ball's vertical velocity.
public static final double VELOCITY_Y = 3.0;

// The ball's minimum and maximum horizontal velocity; the bounds of the
// initial random velocity that you should choose (randomly +/-).
public static final double VELOCITY_X_MIN = 1.0;
public static final double VELOCITY_X_MAX = 3.0;

// Animation delay or pause time between ball moves (ms)
public static final double DELAY = 1000.0 / 60.0;

// Number of turns
public static final int NTURNS = 3;

public void run() {
// Set the window's title bar text
setTitle("CS 106A Breakout");

// Set the canvas size. In your code, remember to ALWAYS use getWidth()
// and getHeight() to get the screen dimensions, not these constants!
setCanvasSize(CANVAS_WIDTH, CANVAS_HEIGHT);

//增加声音
Setupbricks();
Setuppaddle();
Setupball();
}

private void Setupbricks() {
for(int i=0;i<NBRICK_ROWS;i++) {
for(int j=0;j<NBRICK_COLUMNS;j++) {
GRect a=new GRect(BRICK_SEP+j*(BRICK_SEP+BRICK_WIDTH),BRICK_Y_OFFSET+i*(BRICK_SEP+BRICK_HEIGHT),
BRICK_WIDTH,BRICK_HEIGHT);
a.setFilled(true);
switch(i/2) {
case 0:
a.setColor(Color.RED);
break;
case 1:
a.setColor(Color.ORANGE);
break;
case 2:
a.setColor(Color.YELLOW);
break;
case 3:
a.setColor(Color.GREEN);
break;
case 5:
a.setColor(Color.CYAN);
break;
}
add(a);
}
}
}

private void Setuppaddle() {
paddle=new GRect((getWidth()-PADDLE_WIDTH)/2,getHeight()-PADDLE_Y_OFFSET-PADDLE_HEIGHT,
PADDLE_WIDTH,PADDLE_HEIGHT);
paddle.setFilled(true);
add(paddle);
addMouseListeners();
}

public void mouseMoved(MouseEvent e) {
double x=e.getX();
double y=e.getY();
paddle.move(x-paddle.getX(), 0);
//paddle.move(x-paddle.getX(), y-paddle.getY());
}

private void Setupball() {
//初始化球
ball =new GOval(getWidth()/2-BALL_RADIUS,getHeight()/2-BALL_RADIUS,BALL_RADIUS*2,BALL_RADIUS*2);
ball.setFilled(true);
add(ball);
//初始化速度
vx=rgen.nextDouble(VELOCITY_X_MIN , VELOCITY_X_MAX);
if (rgen.nextBoolean(0.5)) vx = -vx;
vy=VELOCITY_Y;

//增加声音
AudioClip bounceClip = MediaTools.loadAudioClip("bounce.au");

//增加分数
score=new GLabel("Your score is:"+0);
add(score,(getWidth()-score.getWidth())/2,20);

while(true) {
//移动球
moveball();
//判断是否碰壁
checkForCollision();
//碰到底部结束
if(ball.getY()>getHeight()-2*BALL_RADIUS) {
GLabel label=new GLabel("You Lose!");
add(label,(getWidth()-label.getWidth())/2,(getHeight()-label.getHeight())/2);
break;
}
//判断是否碰到物体
GObject collider=getCollidingObject();
if(collider==paddle) {
bounceClip.play();
vy=-vy;
}else if(collider!=null) {
bounceClip.play();
remove(collider);
vy=-vy;
count++;
remove(score);
score=new GLabel("Your score is:"+count);
add(score,(getWidth()-score.getWidth())/2,20);
//每7次增加速度
if(count>0 && count%7==0) {
vx=2*vx;
vy=2*vy;
}
//全部完成
if(count==NBRICK_COLUMNS*NBRICK_ROWS) {
GLabel label=new GLabel("You Win!");
add(label,(getWidth()-label.getWidth())/2,(getHeight()-label.getHeight())/2);
break;
}
}
}
}

//移动球
private void moveball() {
ball.move(vx, vy);
pause(speed);
}

//判断是否碰壁
private void checkForCollision() {
AudioClip bounceClip = MediaTools.loadAudioClip("bounce.au");
if(ball.getX()>getWidth()-2*BALL_RADIUS || ball.getX()<0){
vx=-vx;
bounceClip.play();
}

if(ball.getY()>getHeight()-2*BALL_RADIUS || ball.getY()<0) {
vy=-vy;
bounceClip.play();
}
}

//判断是否碰到物体
private GObject getCollidingObject() {
double x=ball.getX();
double y=ball.getY();
if(getElementAt(x,y)!=null) {
return getElementAt(x,y);
}else if(getElementAt(x+2*BALL_RADIUS,y)!=null) {
return getElementAt(x+2*BALL_RADIUS,y);
}else if(getElementAt(x+2*BALL_RADIUS,y+2*BALL_RADIUS)!=null) {
return getElementAt(x+2*BALL_RADIUS,y+2*BALL_RADIUS);
}else {
return getElementAt(x,y+2*BALL_RADIUS);
}
}

//底部物块
private GRect paddle;
//速度
private double vx, vy;
//随机数生成器
private RandomGenerator rgen = RandomGenerator.getInstance();
//球
private GOval ball;
//记录得分
private int count=0;
//得分标签
private GLabel score;
//速度
private int speed=10;
}