-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathball.pde
More file actions
198 lines (167 loc) · 6.14 KB
/
ball.pde
File metadata and controls
198 lines (167 loc) · 6.14 KB
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
class Ball {
PVector position, velocity;
boolean sticky, bounced;
int start_dir = 0;
final float r = 15 * gUnit, speed = 10 * gUnit;
final float eff_vel = sqrt(pow(speed, 2) * 2);
final float perimeter_w = 3 * gUnit, lift_h = 30 * gUnit, offset = 0;
float test_x, test_y, dist_x, dist_y, dist, overlapLeft, overlapRight, overlapTop, overlapBottom, minOverlap;
float[] overlaps = new float[4];
final color inner_col = color(255, 255, 255),
outer_col = color(130, 130, 130);
Ball() {
reset();
}
void reset() {
sticky = true;
start_dir = int(random(0, 2));
if(start_dir == 0)
velocity = new PVector(-speed, -speed); // move left
else
velocity = new PVector(speed, -speed); // move right
//velocity = new PVector(0, speed); // for testing
}
void checkSticky() {
if(sticky)
stick();
}
void stick() {
position = new PVector(player.position.x + player.w / 2 + offset, player.position.y - lift_h);
}
void move() {
if(!sticky)
position.add(velocity);
}
void checkBounds() {
if(position.y + r >= height) { // bottom
reset();
player.health --;
}
if(!bounced) {
if(position.y - r <= 0) { // top
bounced = true;
velocity.y = abs(velocity.y);
print(frameCount + " hit top bound... \n");
}
if((position.x - r <= margin)) { // left
bounced = true;
velocity.x = abs(velocity.x);
print(frameCount + " hit left bound... \n");
}
if((position.x + r >= width - margin)) { // right
bounced = true;
velocity.x = abs(velocity.x) * - 1;
print(frameCount + " hit right bound... \n");
}
}
}
void checkCollisionPlayer() {
if(position.y + r >= player.position.y // is between top edge
&& position.y - r < player.position.y + player.h / 2 // and half height
&& position.x + r > player.position.x // is between left edge
&& position.x - r < player.position.x + player.w) { // and right edge
print(frameCount + " hit player... \n");
velocity.y = -speed;
rebouncePlayer();
}
}
void checkCollisionBrick(Brick brick) {
String collisionType = collision(brick.position, brick.w, brick.h);
if(collisionType != null && !brick.destroyed && !bounced) {
rebounceBrick(collisionType);
print(frameCount + " hit brick... \n");
brick.destroy();
player.score ++;
}
}
void rebouncePlayer() {
int direction;
float player_cent_w = player.position.x + player.w / 2;
float distance = position.x - player_cent_w; // calculate the distance between the center of the player and the center of the ball
print(frameCount + " dist: " + distance + "\n"); // max-right = 89, max-left = -89
if(distance < 0) // set direction of rebouncing
direction = -1;
else
direction = 1;
if(abs(distance) < 10) // set vertical velocity depending on the distance
velocity.x = 1.5 * direction * gUnit;
else if(abs(distance) < 20)
velocity.x = 3.0 * direction * gUnit;
else if(abs(distance) < 30)
velocity.x = 5.0 * direction * gUnit;
else if(abs(distance) < 40)
velocity.x = 7.0 * direction * gUnit;
else if(abs(distance) < 50)
velocity.x = 9.0 * direction * gUnit;
else if(abs(distance) < 60)
velocity.x = 10.0 * direction * gUnit;
else if(abs(distance) < 65)
velocity.x = 11.0 * direction * gUnit;
else if(abs(distance) < 70)
velocity.x = 12.0 * direction * gUnit;
else if(abs(distance) < 75)
velocity.x = 13.0 * direction * gUnit;
else if(abs(distance) < 80)
velocity.x = 13.3 * direction * gUnit;
else if(abs(distance) < 85)
velocity.x = 13.5 * direction * gUnit;
else {
velocity.x = 13.7 * direction * gUnit;
}
velocity.y = calcVerticalVelocity(velocity.x, eff_vel);
print(frameCount + " vel E: " + eff_vel + "\n");
print(frameCount + " vel X: " + velocity.x + "\n");
print(frameCount + " vel Y: " + velocity.y + "\n");
}
// calculate vertical velocity based on horizontal and effective velocities
float calcVerticalVelocity(float x_vel, float eff_vel) {
float y_vel_sqr = pow(eff_vel, 2) - pow(x_vel, 2);
return -1 * sqrt(y_vel_sqr);
}
void rebounceBrick(String collisionType) { // ball rebounce logic based on collisionType
bounced = true;
if(collisionType.equals("left") || collisionType.equals("right")) {
velocity.x *= -1; // invert x direction
} else if(collisionType.equals("top") || collisionType.equals("bottom")) {
velocity.y *= -1; // Invert y direction
}
}
String collision(PVector rect_pos, float rect_w, float rect_h) {
test_x = position.x;
test_y = position.y;
// check the closest edge
if(position.x < rect_pos.x)
test_x = rect_pos.x; // left edge
else if(position.x > rect_pos.x + rect_w)
test_x = rect_pos.x + rect_w; // right edge
if(position.y < rect_pos.y)
test_y = rect_pos.y; // top edge
else if(position.y > rect_pos.y + rect_h)
test_y = rect_pos.y + rect_h; // bottom edge
dist_x = position.x - test_x;
dist_y = position.y - test_y;
dist = sqrt(pow(dist_x, 2) + pow(dist_y, 2));
if(dist <= r) { // determine the collision side
overlaps[0] = position.x - (rect_pos.x - r); // left
overlaps[1] = (rect_pos.x + rect_w + r) - position.x; // right
overlaps[2] = position.y - (rect_pos.y - r); // top
overlaps[3] = (rect_pos.y + rect_h + r) - position.y; // bottom
minOverlap = min(overlaps);
if (minOverlap == overlaps[0])
return "left";
if (minOverlap == overlaps[1])
return "right";
if (minOverlap == overlaps[2])
return "top";
if (minOverlap == overlaps[3])
return "bottom";
}
return null;
}
void draw(PVector position, float radius) {
fill(outer_col);
circle(position.x, position.y, radius * 2);
fill(inner_col);
circle(position.x, position.y, radius * 2 - radius * 0.2);
}
}