A collection of games I worked on in high school.
1//sounds
2var sound_thwip;
3var sound_upg;
4var sound_amb;
5
6//constants
7var WINDOW_WIDTH = 800;
8var WINDOW_HEIGHT = 600;
9var PLAYER_POSX = WINDOW_WIDTH / 2;
10var PLAYER_POSY = WINDOW_HEIGHT / 2;
11var MOVE_SPEED = 8;
12var REFRESH_RATE = 15;
13var FIRE_COOLDOWN = 15; //number of frames
14var DRAW_COOLDOWN = 5;
15var CARD_EXPIRATION_DATE = 100; //age at which thrown cards self-remove
16var DEFAULT_CARD_SPEED = 12;
17var FOUR_TIME = 3; //delay between shots
18var NINE_TIME = 6;
19var HEALTH_DRAIN = 0; //was 0.12
20
21var KING_LIMIT = 1;
22var QUEEN_LIMIT = 1;
23var ROOK_LIMIT = 2;
24var BISHOP_LIMIT = 2;
25var KNIGHT_LIMIT = 2;
26var PAWN_LIMIT = 8;
27
28var KING_COST = 9;
29var QUEEN_COST = 9;
30var ROOK_COST = 5;
31var BISHOP_COST = 3;
32var KNIGHT_COST = 3;
33var PAWN_COST = 1;
34
35//variables
36var credits = 0;
37var muted = 0;
38
39var move_left = 0;
40var move_right = 0;
41var move_up = 0;
42var move_down = 0;
43var offsetx = 0;
44var offsety = 0;
45var deltax = 0;
46var deltay = 0;
47
48var mousex = 0;
49var mousey = 0;
50var facing = 0;
51var health = 100;
52
53var heldcard = 15; //the first card is always the 2 of clubs
54var number = 2;
55var suit = 1;
56
57var cooldown = 0;
58
59var uid = 0;
60var generate_num = 20; //encounter your first shrine sooner
61
62//upgrade array
63var deckupgrades = new Array(52);
64for (var i = 0; i < 52; i++) {
65 if (i % 13 >= 1 && i % 13 <= 4) {
66 deckupgrades[i] = 1;
67 } else {
68 deckupgrades[i] = 0;
69 }
70}
71var totalupgrades = 0;
72
73//objects and arrays (mostly for web workers)
74var newenemies = []; //array that contains pertinant stuff about all new enemies
75var deadenemies = []; //array of dead enemies returned from the web worker to be deleted
76var movedenemies = []; //array of moved enemies returned from the web worker
77var hitenemies = []; //array of enemies hit by a card
78var message = { "newenemies": newenemies, "hitenemies": hitenemies};
79var delayed_shots = [];
80
81function startenemyWorker() {
82 if (typeof (Worker) !== "undefined") {
83 if (typeof (w) == "undefined") {
84 w = new Worker("enemyWorker.js"); //defining file that will run on new thread
85 }
86 w.onmessage = function (event) {
87 var message = JSON.parse(event.data);
88 deadenemies.push.apply(deadenemies, message[0]);
89 movedenemies.push.apply(movedenemies, message[1]);
90 for (var j = 0; j < message[2].length; j++) { //response is array of numbers so three pawns attack would look like [10,10,10]
91 health -= message[2][j]; //subtracts health from player done by units in range
92 }
93 };
94 }
95 else {
96 $("#playground").text = "Sorry, your browser does not support Web Workers... Please use the lastest version of Chrome, Internet Explorer, or Firefox.";
97 }
98}
99
100function stopenemyWorker() {
101 w.terminate();
102}
103
104var load_sounds = function () {
105 sound_thwip = soundManager.createSound({
106 url: "assets/aud/thwip.mp3",
107 autoLoad: true
108 });
109 sound_upg = soundManager.createSound({
110 url: "assets/aud/upgrade.mp3"
111 });
112 sound_amb = soundManager.createSound({
113 url: "assets/aud/ambient.mp3"
114 });
115 loopSound(sound_amb);
116};
117
118function loopSound(sound) {
119 sound.play({
120 onfinish: function() {
121 loopSound(sound);
122 }
123 });
124}
125
126//initialize soundManager
127soundManager.setup({
128 // where to find flash audio SWFs, as needed
129 url: '/assets/swf-files/',
130 // optional: prefer HTML5 over Flash for MP3/MP4
131 preferFlash: false,
132 debugMode: false,
133 onready: function () {
134 load_sounds();
135 }
136});
137
138$.when(
139 $.getScript("functions.js"),
140 $.getScript("init.js"),
141 $.Deferred(function (deferred) {
142 $(deferred.resolve);
143 })
144).done(function () {
145
146 $(function () {
147
148 //main loop!
149 $.playground().registerCallback(function () {
150
151 message.delta = { "x": deltax, "y": deltay };
152 w.postMessage(JSON.stringify(message)); //sends new enemies and hit enemies to the enemy worker
153 newenemies.length = 0;
154 hitenemies.length = 0;
155
156 $("#healthbar").width( 8 * health );
157 health -= HEALTH_DRAIN;
158 if (health <= 0) {
159 $.playground().pauseGame();
160 stopenemyWorker();
161 $("#healthbar").hide();
162 $("#playground").prepend("<div id='welcomeScreen'>");
163 $("#welcomeScreen").css('background-image', 'url(assets/img/youdiedcredits.png)');
164 $("#welcomeScreen").css('opacity', '100');
165 }
166
167 //get input, but block movement into solids
168 if ($.gQ.keyTracker[65] && $("#leftbound").collision("#terrain,.solid").length === 0) { move_left = 1; } else { move_left = 0; }
169 if ($.gQ.keyTracker[68] && $("#rightbound").collision("#terrain,.solid").length === 0) { move_right = 1; } else { move_right = 0; }
170 if ($.gQ.keyTracker[87] && $("#upbound").collision("#terrain,.solid").length === 0) { move_up = 1; } else { move_up = 0; }
171 if ($.gQ.keyTracker[83] && $("#downbound").collision("#terrain,.solid").length === 0) { move_down = 1; } else { move_down = 0; }
172
173 var delta_vector = normal({x: (move_left - move_right), y: (move_up - move_down)});
174 deltax = MOVE_SPEED * delta_vector.x;
175 deltay = MOVE_SPEED * delta_vector.y;
176
177 mousex = $.gQ.mouseTracker.x;
178 mousey = $.gQ.mouseTracker.y;
179
180 //get mouse rotation
181 facing = (180 / Math.PI) * angle(mousex - PLAYER_POSX, mousey - PLAYER_POSY);
182
183 //turn to face mouse
184 $("#feet").rotate(facing + 90, false);
185 $("#playerspr").rotate(facing, false);
186
187 //pause/resume feet animation
188 if (delta_vector.x !== 0 || delta_vector.y !== 0) {
189 $("#feet").resumeAnimation();
190 } else {
191 $("#feet").pauseAnimation();
192 }
193
194 //spin the wheel
195 $("#sealui").rotate(1, true);
196
197 //tick cooldown
198 if (cooldown > 0) cooldown--;
199
200
201 //obtain upgrades!
202 if ($("#playerspr").collision("#terrain,.upgrade").length > 0) {
203
204 var counter;
205 do {
206 counter++;
207 if (counter > 1000) break;
208 heldcard = Math.floor(51 * Math.random());
209 number = heldcard % 13;
210 suit = Math.floor(heldcard / 13);
211 } while (deckupgrades[heldcard] == 1 || number < 2 || number > 10);
212
213 deckupgrades[heldcard] = 1;
214 totalupgrades++;
215
216 //DING!
217 sound_upg.play();
218
219 update_hud();
220
221 //destroy pickup
222 $("#playerspr").collision("#terrain,.upgrade").each(function () { $(this).remove(); });
223
224 //win the game!
225 if (totalupgrades >= 40) {
226 $.playground().pauseGame();
227 stopenemyWorker();
228 $("#healthbar").hide();
229 $("#playground").prepend("<div id='welcomeScreen'>");
230 $("#welcomeScreen").css('background-image', 'url(assets/img/youwincredits.png)');
231 $("#welcomeScreen").css('opacity', '100');
232 }
233 }
234
235 //scroll terrain
236 offsetx += deltax;
237 offsety += deltay;
238 if (offsetx >= 64) {
239 offsetx -= 64;
240 generate("left");
241 }
242 if (offsetx <= -64) {
243 offsetx += 64;
244 generate("right");
245 }
246 if (offsety >= 64) {
247 offsety -= 64;
248 generate("up");
249 }
250 if (offsety <= -64) {
251 offsety += 64;
252 generate("down");
253 }
254 $("#bg").xy(offsetx - 64, offsety - 64, false);
255
256 //resolve delay effects
257 for (var i = 0; i < delayed_shots.length; i++) {
258 if (delayed_shots[i].delay < 1) {
259 spawn_card(PLAYER_POSX - 16, PLAYER_POSY - 16, delayed_shots[i].suit, facing + delayed_shots[i].dirmod, DEFAULT_CARD_SPEED);
260 delayed_shots.splice(i, 1);
261 } else {
262 delayed_shots[i].delay -= 1;
263 }
264 }
265
266 //process thrown cards
267
268 $(".thrown_card").each(function () {
269
270 //age and expire
271 $(this)[0].thrown_card.age += 1;
272 if ($(this)[0].thrown_card.age > CARD_EXPIRATION_DATE) {
273 $(this).remove();
274 return;
275 }
276 //handle movement UPDATE WHEN VECTORS ARE ADDED
277 $(this).xy(
278 $(this)[0].thrown_card.speed * Math.cos($(this)[0].thrown_card.direction * (Math.PI / 180)) + deltax,
279 $(this)[0].thrown_card.speed * Math.sin($(this)[0].thrown_card.direction * (Math.PI / 180)) + deltay, true);
280 //star turn!
281 if ($(this)[0].thrown_card.option == 5 && $(this)[0].thrown_card.age == 10) {
282 $(this)[0].thrown_card.direction += 162;
283 }
284 //boomerang curve!
285 if ($(this)[0].thrown_card.option == 7) {
286 $(this)[0].thrown_card.direction -= 4;
287 }
288 //diffusion split!
289 if ($(this)[0].thrown_card.option == 10 && $(this)[0].thrown_card.age % 5 === 0) {
290 spawn_card($(this).x(), $(this).y(), $(this)[0].thrown_card.suit, $(this)[0].thrown_card.direction + 90, DEFAULT_CARD_SPEED);
291 spawn_card($(this).x(), $(this).y(), $(this)[0].thrown_card.suit, $(this)[0].thrown_card.direction - 90, DEFAULT_CARD_SPEED);
292 }
293 //detect collisions
294 var hitsomething = 0;
295
296 $(this).collision("#enemies,.enemy").each(function () {
297 $(this)[0].enemy.health -= 1;
298 if ($(this)[0].enemy.health <= 1) {
299 hitenemies.push({ "id": $(this)[0].enemy.name });
300 console.log($(this)[0].enemy.name + " was killed.");
301 switch ($(this)[0].enemy.type) {
302 case "pawn":
303 health += 5;
304 break;
305 case "knight":
306 health += 10;
307 break;
308 case "bishop":
309 health += 10;
310 break;
311 case "rook":
312 health += 10;
313 break;
314 case "queen":
315 health += 25;
316 break;
317 case "king":
318 health += 50;
319 break;
320 }
321 if (health > 100) { health = 100; }
322 }
323
324 hitsomething = 1;
325
326 });
327 if ((hitsomething || $(this).collision("#terrain,.solid").length > 0) && ($(this)[0].thrown_card.option != 7 && $(this)[0].thrown_card.option != 10)) {
328
329 spawn_fx($(this)[0].thrown_card.suit, $(this).x(), $(this).y());
330
331 //bomb boom!
332 if ($(this)[0].thrown_card.option == 6) {
333 spawn_card($(this).x(), $(this).y(), $(this)[0].thrown_card.suit, $(this)[0].thrown_card.direction - 150, DEFAULT_CARD_SPEED);
334 spawn_card($(this).x(), $(this).y(), $(this)[0].thrown_card.suit, $(this)[0].thrown_card.direction - 90, DEFAULT_CARD_SPEED);
335 spawn_card($(this).x(), $(this).y(), $(this)[0].thrown_card.suit, $(this)[0].thrown_card.direction - 30, DEFAULT_CARD_SPEED);
336 spawn_card($(this).x(), $(this).y(), $(this)[0].thrown_card.suit, $(this)[0].thrown_card.direction + 30, DEFAULT_CARD_SPEED);
337 spawn_card($(this).x(), $(this).y(), $(this)[0].thrown_card.suit, $(this)[0].thrown_card.direction + 90, DEFAULT_CARD_SPEED);
338 spawn_card($(this).x(), $(this).y(), $(this)[0].thrown_card.suit, $(this)[0].thrown_card.direction + 150, DEFAULT_CARD_SPEED);
339 }
340
341 $(this).remove();
342 return;
343 }
344 });
345
346 //process obstacles
347 $(".doodad").each(function () {
348 //handle movement
349 $(this).xy(deltax, deltay, true);
350 //handle outofbounds - past farthest spawn distance
351 if ($(this).x() < -2 * $(this).h() ||
352 $(this).x() > WINDOW_WIDTH + $(this).h() ||
353 $(this).y() < -2 * $(this).h() ||
354 $(this).y() > WINDOW_HEIGHT + $(this).h()) {
355 $(this).remove();
356 }
357 });
358
359 //----process enemies----
360 if (movedenemies.length > 0) {
361 for (var j = 0; j <= movedenemies.length - 1; j++) {
362 $("#" + movedenemies[j].id).xy(movedenemies[j].x, movedenemies[j].y, true);
363 }
364 movedenemies.length = 0;
365 }
366 if (deadenemies.length > 0) {
367 for (var k = 0; k <= deadenemies.length - 1; k++) {
368 console.log(deadenemies[k] + " died");
369 $("#" + deadenemies[k]).remove();
370 }
371 deadenemies.length = 0;
372 }
373
374 //----process enemy projectiles----
375
376
377 }, REFRESH_RATE);
378 });
379
380});
381