-
Notifications
You must be signed in to change notification settings - Fork 0
/
GalaxianFinal.pde
324 lines (265 loc) · 6.87 KB
/
GalaxianFinal.pde
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
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
/*
*/
import sprites.utils.*;
import sprites.maths.*;
import sprites.*;
// The dimensions of the monster grid.
int monsterCols = 10; // Orginial = 10
int monsterRows = 5; // Original = 5
long mmCounter = 0;
int mmStep = 1;
int missileSpeed = 500;
double upRadians = 4.71238898;
// Lower difficulty values introduce a more
// random falling monster descent.
int difficulty = 100;
double fmRightAngle = 0.3490; // 20 degrees
double fmLeftAngle = 2.79253; // 160 degrees
double fmSpeed = 150;
boolean gameOver = false;
int score = 0;
int fallingMonsterPts = 20;
int gridMonsterPts = 10;
Sprite ship, missile, fallingMonster, explosion, gameOverSprite;
Sprite monsters[] = new Sprite[monsterCols * monsterRows];
KeyboardController kbController;
SoundPlayer soundPlayer;
StopWatch stopWatch = new StopWatch();
void setup()
{
kbController = new KeyboardController(this);
soundPlayer = new SoundPlayer(this);
// register the function (pre) that will be called
// by Processing before the draw() function.
registerMethod("pre", this);
size(700, 500);
S4P.messagesEnabled(true);
buildSprites();
resetMonsters();
// Ship Explosion Sprite
explosion = new Sprite(this, "explosion_strip16.png", 17, 1, 90);
explosion.setScale(1);
// Game Over Sprite
gameOverSprite = new Sprite(this, "gameOver.png", 100);
gameOverSprite.setDead(true);
}
void buildSprites()
{
// The Ship
ship = buildShip();
// Missile(s)
missile = buildMissile();
// The Grid Monsters
buildMonsterGrid();
}
Sprite buildShip()
{
Sprite ship = new Sprite(this, "ship.png", 50);
ship.setXY(width/2, height - 30);
ship.setVelXY(0.0f, 0);
ship.setScale(.75);
ship.setRot(3.14159);
// Domain keeps the moving sprite withing specific screen area
ship.setDomain(0, height-ship.getHeight(), width, height, Sprite.HALT);
return ship;
}
// Populate the monsters grid
void buildMonsterGrid()
{
for (int idx = 0; idx < monsters.length; idx++ ) {
monsters[idx] = buildMonster();
}
}
// Arrange Monsters into a grid
void resetMonsters()
{
for (int idx = 0; idx < monsters.length; idx++ ) {
Sprite monster = monsters[idx];
monster.setSpeed(0, 0);
double mwidth = monster.getWidth() + 20;
double totalWidth = mwidth * monsterCols;
double start = (width - totalWidth)/2 - 25;
double mheight = monster.getHeight();
int xpos = (int)((((idx % monsterCols)*mwidth)+start));
int ypos = (int)(((int)(idx / monsterCols)*mheight)+50);
monster.setXY(xpos, ypos);
monster.setDead(false);
}
}
void replaceFallingMonster()
{
if (fallingMonster != null) {
fallingMonster.setDead(true);
fallingMonster = null;
}
// select new falling monster
fallingMonster = pickNonDeadMonster();
if (fallingMonster == null) {
return;
}
fallingMonster.setSpeed(fmSpeed, fmRightAngle);
// Domain keeps the moving sprite within specific screen area
fallingMonster.setDomain(0, 0, width, height+100, Sprite.REBOUND);
}
// Build individual monster
Sprite buildMonster()
{
Sprite monster = new Sprite(this, "monster.png", 30);
monster.setScale(.5);
monster.setDead(false);
return monster;
}
// Pick the first monster on the grid that is not dead.
// Return null if they are all dead.
Sprite pickNonDeadMonster()
{
for (int idx = 0; idx < monsters.length; idx++) {
Sprite monster = monsters[idx];
if (!monster.isDead()) {
return monster;
}
}
return null;
}
Sprite buildMissile()
{
// The Missile
Sprite sprite = new Sprite(this, "rocket.png", 10);
sprite.setScale(.5);
sprite.setDead(true); // Initially hide the missile
return sprite;
}
void fireMissile()
{
if (missile.isDead() && !ship.isDead()) {
missile.setPos(ship.getPos());
missile.setSpeed(missileSpeed, upRadians);
missile.setDead(false);
}
}
void stopMissile()
{
missile.setSpeed(0, upRadians);
missile.setDead(true);
}
// Executed before draw() is called
public void pre()
{
checkKeys();
processCollisions();
moveMonsters();
// If missile flies off screen
if (!missile.isDead() && ! missile.isOnScreem()) {
stopMissile();
}
if(pickNonDeadMonster() == null) {
resetMonsters();
}
// if falling monster is off screen
if (fallingMonster == null || !fallingMonster.isOnScreem()) {
replaceFallingMonster();
}
S4P.updateSprites(stopWatch.getElapsedTime());
}
void checkKeys()
{
if (focused) {
if (kbController.isLeft()) {
ship.setX(ship.getX()-10);
}
if (kbController.isRight()) {
ship.setX(ship.getX()+10);
}
if (kbController.isSpace()) {
fireMissile();
}
}
}
void moveMonsters()
{
// Move Grid Monsters
mmCounter++;
if ((mmCounter % 100) == 0) mmStep *= -1;
for (int idx = 0; idx < monsters.length; idx++ ) {
Sprite monster = monsters[idx];
if (!monster.isDead()&& monster != fallingMonster) {
monster.setXY(monster.getX()+mmStep, monster.getY());
}
}
// Move Falling Monster
if (fallingMonster != null) {
if (int(random(difficulty)) == 1) {
// Change FM Speed
fallingMonster.setSpeed(fallingMonster.getSpeed()
+ random(-40, 40));
// Reverse FM direction.
if (fallingMonster.getDirection() == fmRightAngle)
fallingMonster.setDirection(fmLeftAngle);
else
fallingMonster.setDirection(fmRightAngle);
}
}
}
// Detect collisions between sprites
void processCollisions()
{
// Detect collisions between Grid Monsters and Missile
for (int idx = 0; idx < monsters.length; idx++) {
Sprite monster = monsters[idx];
if (!missile.isDead() && !monster.isDead()
&& monster != fallingMonster
&& missile.bb_collision(monster)) {
score += gridMonsterPts;
monsterHit(monster);
missile.setDead(true);
}
}
// Between Falling Monster and Missile
if (!missile.isDead() && fallingMonster != null
&& missile.cc_collision(fallingMonster)) {
score += fallingMonsterPts;
monsterHit(fallingMonster);
missile.setDead(true);
fallingMonster = null;
}
// Between Falling Monster and Ship
if (fallingMonster!= null && !ship.isDead()
&& fallingMonster.bb_collision(ship)) {
explodeShip();
monsterHit(fallingMonster);
fallingMonster = null;
gameOver = true;
}
}
void monsterHit(Sprite monster)
{
//soundPlayer.playPop();
monster.setDead(true);
}
void explodeShip()
{
soundPlayer.playExplosion();
explosion.setPos(ship.getPos());
explosion.setFrameSequence(0, 16, 0.1, 1);
ship.setDead(true);
}
void drawScore()
{
textSize(32);
String msg = " Score: " + score;
text(msg, 10, 30);
}
void drawGameOver()
{
gameOverSprite.setXY(width/2, height/2);
gameOverSprite.setDead(false);
}
public void draw()
{
background(0);
drawScore();
S4P.drawSprites();
if (gameOver) {
drawGameOver();
}
}