Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
titaniumnetwork-dev
GitHub Repository: titaniumnetwork-dev/Incognito-old
Path: blob/main/static/src/gs/public/pacman/pacman-canvas.js
1344 views
1
/*-------------------------------------------------------------------
2
3
___________ ____ _____ _____ ____
4
\____ \__ \ _/ ___\ / \\__ \ / \
5
| |_> > __ \\ \___| Y Y \/ __ \| | \
6
| __(____ /\___ >__|_| (____ /___| /
7
|__| \/ \/ \/ \/ \/ .platzh1rsch.ch
8
9
author: platzh1rsch (www.platzh1rsch.ch)
10
11
-------------------------------------------------------------------*/
12
13
"use strict";
14
15
function geronimo() {
16
/* ----- Global Variables ---------------------------------------- */
17
var canvas;
18
var joystick;
19
var context;
20
var game;
21
var canvas_walls, context_walls;
22
var inky, blinky, clyde, pinky;
23
24
var mapConfig = "data/map.json";
25
26
27
/* AJAX stuff */
28
function getHighscore() {
29
setTimeout(ajax_get,30);
30
}
31
function ajax_get() {
32
var date = new Date().getTime();
33
$.ajax({
34
datatype: "json",
35
type: "GET",
36
url: "data/db-handler.php",
37
data: {
38
timestamp: date,
39
action: "get"
40
},
41
success: function(msg){
42
$("#highscore-list").text("");
43
for (var i = 0; i < msg.length; i++) {
44
$("#highscore-list").append("<li>"+msg[i]['name']+"<span id='score'>"+msg[i]['score']+"</span></li>");
45
}
46
}
47
});
48
}
49
function ajax_add(n, s, l) {
50
51
$.ajax({
52
type: 'POST',
53
url: 'data/db-handler.php',
54
data: {
55
action: 'add',
56
name: n,
57
score: s,
58
level: l
59
},
60
dataType: 'json',
61
success: function(data) {
62
console.log('Highscore added: ' + data);
63
$('#highscore-form').html('<span class="button" id="show-highscore">View Highscore List</span>');
64
},
65
error: function(errorThrown) {
66
console.log(errorThrown);
67
}
68
});
69
}
70
71
function addHighscore() {
72
var name = $("input[type=text]").val();
73
$("#highscore-form").html("Saving highscore...");
74
ajax_add(name ,game.score.score, game.level);
75
}
76
77
function buildWall(context,gridX,gridY,width,height) {
78
console.log("BuildWall");
79
width = width*2-1;
80
height = height*2-1;
81
context.fillRect(pacman.radius/2+gridX*2*pacman.radius,pacman.radius/2+gridY*2*pacman.radius, width*pacman.radius, height*pacman.radius);
82
}
83
84
function between(x, min, max) {
85
return x >= min && x <= max;
86
}
87
88
89
// Logger
90
var logger = function() {
91
var oldConsoleLog = null;
92
var pub = {};
93
94
pub.enableLogger = function enableLogger()
95
{
96
if(oldConsoleLog === null)
97
return;
98
99
window['console']['log'] = oldConsoleLog;
100
};
101
102
pub.disableLogger = function disableLogger()
103
{
104
oldConsoleLog = console.log;
105
window['console']['log'] = function() {};
106
};
107
108
return pub;
109
}();
110
111
// stop watch to measure the time
112
function Timer() {
113
this.time_diff = 0;
114
this.time_start = 0;
115
this.time_stop = 0;
116
this.start = function() {
117
this.time_start = new Date().getTime();
118
}
119
this.stop = function() {
120
this.time_stop = new Date().getTime();
121
this.time_diff += this.time_stop - this.time_start;
122
this.time_stop = 0;
123
this.time_start = 0;
124
}
125
this.reset = function() {
126
this.time_diff = 0;
127
this.time_start = 0;
128
this.time_stop = 0;
129
}
130
this.get_time_diff = function() {
131
return this.time_diff;
132
}
133
}
134
135
// Manages the whole game ("God Object")
136
function Game() {
137
this.timer = new Timer();
138
this.refreshRate = 33; // speed of the game, will increase in higher levels
139
this.running = false;
140
this.pause = true;
141
this.score = new Score();
142
this.soundfx = 0;
143
this.map;
144
this.pillCount; // number of pills
145
this.monsters;
146
this.level = 1;
147
this.refreshLevel = function(h) {
148
$(h).html("Lvl: "+this.level);
149
};
150
this.gameOver = false;
151
this.canvas = $("#myCanvas").get(0);
152
this.wallColor = "Blue";
153
this.width = this.canvas.width;
154
this.height = this.canvas.height;
155
156
this.pillSize = 3;
157
this.powerpillSizeMin = 2;
158
this.powerpillSizeMax = 6;
159
this.powerpillSizeCurrent = this.powerpillSizeMax;
160
this.powerPillAnimationCounter = 0;
161
this.nextPowerPillSize = function() {
162
/*if (this.powerPillAnimationCounter === 3) {
163
this.powerPillAnimationCounter = 0;
164
this.powerpillSizeCurrent = this.powerpillSizeMin + this.powerpillSizeCurrent % (this.powerpillSizeMax-this.powerpillSizeMin);
165
} else {
166
this.powerPillAnimationCounter++;
167
}*/
168
return this.powerpillSizeCurrent;
169
};
170
171
this.ghostFrightened = false;
172
this.ghostFrightenedTimer = 240;
173
this.ghostMode = 0; // 0 = Scatter, 1 = Chase
174
this.ghostModeTimer = 200; // decrements each animationLoop execution
175
this.ghostSpeedNormal = (this.level > 4 ? 3 : 2); // global default for ghost speed
176
this.ghostSpeedDazzled = 2; // global default for ghost speed when dazzled
177
178
/* Game Functions */
179
this.startGhostFrightened = function() {
180
console.log("ghost frigthened");
181
this.ghostFrightened = true;
182
this.ghostFrightenedTimer = 240;
183
inky.dazzle();
184
pinky.dazzle();
185
blinky.dazzle();
186
clyde.dazzle();
187
};
188
189
this.endGhostFrightened = function() {
190
console.log("ghost frigthened end");
191
this.ghostFrightened = false;
192
inky.undazzle();
193
pinky.undazzle();
194
blinky.undazzle();
195
clyde.undazzle();
196
};
197
198
199
this.checkGhostMode = function() {
200
if (this.ghostFrightened) {
201
202
this.ghostFrightenedTimer--;
203
if (this.ghostFrightenedTimer === 0) {
204
this.endGhostFrightened();
205
this.ghostFrigthenedTimer = 240;
206
/*inky.reverseDirection();
207
pinky.reverseDirection();
208
clyde.reverseDirection();
209
blinky.reverseDirection();*/
210
}
211
}
212
// always decrement ghostMode timer
213
this.ghostModeTimer--;
214
if (this.ghostModeTimer === 0 && game.level > 1) {
215
this.ghostMode ^= 1;
216
this.ghostModeTimer = 200 + this.ghostMode * 450;
217
console.log("ghostMode=" + this.ghostMode);
218
219
game.buildWalls();
220
221
inky.reverseDirection();
222
pinky.reverseDirection();
223
clyde.reverseDirection();
224
blinky.reverseDirection();
225
}
226
};
227
228
this.getMapContent = function (x, y) {
229
var maxX = game.width / 30 -1;
230
var maxY = game.height / 30 -1;
231
if (x < 0) x = maxX + x;
232
if (x > maxX) x = x-maxX;
233
if (y < 0) y = maxY + y;
234
if (y > maxY) y = y-maxY;
235
return this.map.posY[y].posX[x].type;
236
};
237
238
this.setMapContent = function (x,y,val) {
239
this.map.posY[y].posX[x].type = val;
240
};
241
242
this.toggleSound = function() {
243
this.soundfx === 0 ? this.soundfx = 1 : this.soundfx = 0;
244
$('#mute').toggle();
245
};
246
247
this.reset = function() {
248
};
249
250
this.newGame = function() {
251
var r = confirm("Are you sure you want to restart?");
252
if (r) {
253
console.log("new Game");
254
this.init(0);
255
this.pauseResume();
256
}
257
};
258
259
this.nextLevel = function() {
260
this.level++;
261
console.log("Level "+game.level);
262
game.showMessage("Level "+game.level, this.getLevelTitle() + "<br/>(Click to continue!)");
263
game.refreshLevel(".level");
264
this.init(1);
265
};
266
267
this.drawHearts = function (count) {
268
var html = "";
269
for (var i = 0; i<count; i++) {
270
html += " <img src='img/heart.png'>";
271
}
272
$(".lives").html("Lives: "+html);
273
274
};
275
276
this.showContent = function (id) {
277
$('.content').hide();
278
$('#'+id).show();
279
};
280
281
this.getLevelTitle = function() {
282
switch(this.level) {
283
case 2:
284
return '"The chase begins"';
285
// activate chase / scatter switching
286
case 3:
287
return '"Inky\s awakening"';
288
// Inky starts leaving the ghost house
289
case 4:
290
return '"Clyde\s awakening"';
291
// Clyde starts leaving the ghost house
292
case 5:
293
return '"need for speed"';
294
// All the ghosts get faster from now on
295
case 6:
296
return '"hunting season 1"';
297
// TODO: No scatter mood this time
298
case 7:
299
return '"the big calm"';
300
// TODO: Only scatter mood this time
301
case 8:
302
return '"hunting season 2"';
303
// TODO: No scatter mood and all ghosts leave instantly
304
case 9:
305
return '"ghosts on speed"';
306
// TODO: Ghosts get even faster for this level
307
default:
308
return '"nothing new"';
309
}
310
}
311
312
this.showMessage = function(title, text) {
313
this.timer.stop();
314
this.pause = true;
315
$('#canvas-overlay-container').fadeIn(200);
316
if ($('.controls').css('display') != "none") $('.controls').slideToggle(200);
317
$('#canvas-overlay-content #title').text(title);
318
$('#canvas-overlay-content #text').html(text);
319
};
320
321
this.closeMessage = function() {
322
$('#canvas-overlay-container').fadeOut(200);
323
$('.controls').slideToggle(200);
324
};
325
326
this.pauseResume = function () {
327
if (!this.running) {
328
// start timer
329
this.timer.start();
330
331
this.pause = false;
332
this.running = true;
333
this.closeMessage();
334
animationLoop();
335
}
336
else if (this.pause) {
337
// stop timer
338
this.timer.stop();
339
340
this.pause = false;
341
this.closeMessage();
342
}
343
else {
344
this.showMessage("Pause","Click to Resume");
345
}
346
};
347
348
this.init = function (state) {
349
350
console.log("init game "+state);
351
352
// reset timer if restart
353
if( state === 0 ) {
354
this.timer.reset();
355
}
356
357
// get Level Map
358
$.ajax({
359
url: mapConfig,
360
async: false,
361
beforeSend: function(xhr){
362
if (xhr.overrideMimeType) xhr.overrideMimeType("application/json");
363
},
364
dataType: "json",
365
success: function (data) {
366
game.map = data;
367
}
368
});
369
370
var temp = 0;
371
$.each(this.map.posY, function(i, item) {
372
$.each(this.posX, function() {
373
if (this.type == "pill") {
374
temp++;
375
//console.log("Pill Count++. temp="+temp+". PillCount="+this.pillCount+".");
376
}
377
});
378
});
379
380
this.pillCount = temp;
381
382
if (state === 0) {
383
this.score.set(0);
384
this.score.refresh(".score");
385
pacman.lives = 3;
386
game.level = 1;
387
this.refreshLevel(".level");
388
game.gameOver = false;
389
}
390
pacman.reset();
391
392
game.drawHearts(pacman.lives);
393
394
this.ghostFrightened = false;
395
this.ghostFrightenedTimer = 240;
396
this.ghostMode = 0; // 0 = Scatter, 1 = Chase
397
this.ghostModeTimer = 200; // decrements each animationLoop execution
398
399
// initalize Ghosts, avoid memory flooding
400
if (pinky === null || pinky === undefined) {
401
pinky = new Ghost("pinky",7,5,'img/pinky.svg',2,2);
402
inky = new Ghost("inky",8,5,'img/inky.svg',13,11);
403
blinky = new Ghost("blinky",9,5,'img/blinky.svg',13,0);
404
clyde = new Ghost("clyde",10,5,'img/clyde.svg',2,11);
405
}
406
else {
407
//console.log("ghosts reset");
408
pinky.reset();
409
inky.reset();
410
blinky.reset();
411
clyde.reset();
412
}
413
blinky.start(); // blinky is the first to leave ghostHouse
414
inky.start();
415
pinky.start();
416
clyde.start();
417
};
418
419
this.check = function() {
420
if ((this.pillCount === 0) && game.running) {
421
this.nextLevel();
422
}
423
};
424
425
this.win = function () {};
426
this.gameover = function () {};
427
428
this.toPixelPos = function (gridPos) {
429
return gridPos*30;
430
};
431
432
this.toGridPos = function (pixelPos) {
433
return ((pixelPos % 30)/30);
434
};
435
436
/* ------------ Start Pre-Build Walls ------------ */
437
this.buildWalls = function() {
438
if (this.ghostMode === 0) game.wallColor = "Blue";
439
else game.wallColor = "Red";
440
canvas_walls = document.createElement('canvas');
441
canvas_walls.width = game.canvas.width;
442
canvas_walls.height = game.canvas.height;
443
context_walls = canvas_walls.getContext("2d");
444
445
context_walls.fillStyle = game.wallColor;
446
context_walls.strokeStyle = game.wallColor;
447
448
//horizontal outer
449
buildWall(context_walls,0,0,18,1);
450
buildWall(context_walls,0,12,18,1);
451
452
// vertical outer
453
buildWall(context_walls,0,0,1,6);
454
buildWall(context_walls,0,7,1,6);
455
buildWall(context_walls,17,0,1,6);
456
buildWall(context_walls,17,7,1,6);
457
458
// ghost base
459
buildWall(context_walls,7,4,1,1);
460
buildWall(context_walls,6,5,1,2);
461
buildWall(context_walls,10,4,1,1);
462
buildWall(context_walls,11,5,1,2);
463
buildWall(context_walls,6,6,6,1);
464
465
// ghost base door
466
context_walls.fillRect(8*2*pacman.radius,pacman.radius/2+4*2*pacman.radius+5, 4*pacman.radius, 1);
467
468
// single blocks
469
buildWall(context_walls,4,0,1,2);
470
buildWall(context_walls,13,0,1,2);
471
472
buildWall(context_walls,2,2,1,2);
473
buildWall(context_walls,6,2,2,1);
474
buildWall(context_walls,15,2,1,2);
475
buildWall(context_walls,10,2,2,1);
476
477
buildWall(context_walls,2,3,2,1);
478
buildWall(context_walls,14,3,2,1);
479
buildWall(context_walls,5,3,1,1);
480
buildWall(context_walls,12,3,1,1);
481
buildWall(context_walls,3,3,1,3);
482
buildWall(context_walls,14,3,1,3);
483
484
buildWall(context_walls,3,4,1,1);
485
buildWall(context_walls,14,4,1,1);
486
487
buildWall(context_walls,0,5,2,1);
488
buildWall(context_walls,3,5,2,1);
489
buildWall(context_walls,16,5,2,1);
490
buildWall(context_walls,13,5,2,1);
491
492
buildWall(context_walls,0,7,2,2);
493
buildWall(context_walls,16,7,2,2);
494
buildWall(context_walls,3,7,2,2);
495
buildWall(context_walls,13,7,2,2);
496
497
buildWall(context_walls,4,8,2,2);
498
buildWall(context_walls,12,8,2,2);
499
buildWall(context_walls,5,8,3,1);
500
buildWall(context_walls,10,8,3,1);
501
502
buildWall(context_walls,2,10,1,1);
503
buildWall(context_walls,15,10,1,1);
504
buildWall(context_walls,7,10,4,1);
505
buildWall(context_walls,4,11,2,2);
506
buildWall(context_walls,12,11,2,2);
507
/* ------------ End Pre-Build Walls ------------ */
508
};
509
510
}
511
512
game = new Game();
513
514
515
516
function Score() {
517
this.score = 0;
518
this.set = function(i) {
519
this.score = i;
520
};
521
this.add = function(i) {
522
this.score += i;
523
};
524
this.refresh = function(h) {
525
$(h).html("Score: "+this.score);
526
};
527
528
}
529
530
531
532
// used to play sounds during the game
533
var Sound = {};
534
Sound.play = function (sound) {
535
if (game.soundfx == 1) {
536
var audio = document.getElementById(sound);
537
(audio !== null) ? audio.play() : console.log(sound+" not found");
538
}
539
};
540
541
542
// Direction object in Constructor notation
543
function Direction(name,angle1,angle2,dirX,dirY) {
544
this.name = name;
545
this.angle1 = angle1;
546
this.angle2 = angle2;
547
this.dirX = dirX;
548
this.dirY = dirY;
549
this.equals = function(dir) {
550
return JSON.stringify(this) == JSON.stringify(dir);
551
};
552
}
553
554
// Direction Objects
555
var up = new Direction("up",1.75,1.25,0,-1); // UP
556
var left = new Direction("left",1.25,0.75,-1,0); // LEFT
557
var down = new Direction("down",0.75,0.25,0,1); // DOWN
558
var right = new Direction("right",0.25,1.75,1,0); //
559
/*var directions = [{},{},{},{}];
560
directions[0] = up;
561
directions[1] = down;
562
directions[2] = right;
563
directions[3] = left;*/
564
565
566
// DirectionWatcher
567
function directionWatcher() {
568
this.dir = null;
569
this.set = function(dir) {
570
this.dir = dir;
571
};
572
this.get = function() {
573
return this.dir;
574
};
575
}
576
577
//var directionWatcher = new directionWatcher();
578
579
// Ghost object in Constructor notation
580
function Ghost(name, gridPosX, gridPosY, image, gridBaseX, gridBaseY) {
581
this.name = name;
582
this.posX = gridPosX * 30;
583
this.posY = gridPosY * 30;
584
this.startPosX = gridPosX * 30;
585
this.startPosY = gridPosY * 30;
586
this.gridBaseX = gridBaseX;
587
this.gridBaseY = gridBaseY;
588
this.speed = game.ghostSpeedNormal;
589
this.images = JSON.parse(
590
'{"normal" : {'
591
+ '"inky" : "0",'
592
+ '"pinky" : "1",'
593
+ '"blinky" : "2",'
594
+ '"clyde" : "3"'
595
+ '},'
596
+
597
'"frightened1" : {'
598
+
599
'"left" : "", "up": "", "right" : "", "down": ""},'
600
+
601
'"frightened2" : {'
602
+
603
'"left" : "", "up": "", "right" : "", "down": ""},'
604
+
605
'"dead" : {'
606
+
607
'"left" : "", "up": "", "right" : "", "down": ""}}'
608
);
609
this.image = new Image();
610
this.image.src = image;
611
this.ghostHouse = true;
612
this.dazzled = false;
613
this.dead = false;
614
this.dazzle = function() {
615
this.changeSpeed(game.ghostSpeedDazzled);
616
// ensure ghost doesnt leave grid
617
if (this.posX > 0) this.posX = this.posX - this.posX % this.speed;
618
if (this.posY > 0) this.posY = this.posY - this.posY % this.speed;
619
this.dazzled = true;
620
}
621
this.undazzle = function() {
622
// only change speed if ghost is not "dead"
623
if (!this.dead) this.changeSpeed(game.ghostSpeedNormal);
624
// ensure ghost doesnt leave grid
625
if (this.posX > 0) this.posX = this.posX - this.posX % this.speed;
626
if (this.posY > 0) this.posY = this.posY - this.posY % this.speed;
627
this.dazzled = false;
628
}
629
this.dazzleImg = new Image();
630
this.dazzleImg.src = 'img/dazzled.svg';
631
this.dazzleImg2 = new Image();
632
this.dazzleImg2.src = 'img/dazzled2.svg';
633
this.deadImg = new Image();
634
this.deadImg.src = 'img/dead.svg';
635
this.direction = right;
636
this.radius = pacman.radius;
637
this.draw = function (context) {
638
if (this.dead) {
639
context.drawImage(this.deadImg, this.posX, this.posY, 2*this.radius, 2*this.radius);
640
}
641
else if (this.dazzled) {
642
if (pacman.beastModeTimer < 50 && pacman.beastModeTimer % 8 > 1) {
643
context.drawImage(this.dazzleImg2, this.posX, this.posY, 2*this.radius, 2*this.radius);
644
} else {
645
context.drawImage(this.dazzleImg, this.posX, this.posY, 2*this.radius, 2*this.radius);
646
}
647
}
648
else context.drawImage(this.image, this.posX, this.posY, 2*this.radius, 2*this.radius);
649
}
650
this.getCenterX = function () {
651
return this.posX+this.radius;
652
}
653
this.getCenterY = function () {
654
return this.posY+this.radius;
655
}
656
657
this.reset = function() {
658
this.dead = false;
659
this.posX = this.startPosX;
660
this.posY = this.startPosY;
661
this.ghostHouse = true;
662
this.undazzle();
663
}
664
665
this.die = function() {
666
if (!this.dead) {
667
game.score.add(100);
668
//this.reset();
669
this.dead = true;
670
this.changeSpeed(game.ghostSpeedNormal);
671
}
672
}
673
this.changeSpeed = function(s) {
674
// adjust gridPosition to new speed
675
this.posX = Math.round(this.posX / s) * s;
676
this.posY = Math.round(this.posY / s) * s;
677
this.speed = s;
678
}
679
680
this.move = function() {
681
682
this.checkDirectionChange();
683
this.checkCollision();
684
685
// leave Ghost House
686
if (this.ghostHouse == true) {
687
688
// Clyde does not start chasing before 2/3 of all pills are eaten and if level is < 4
689
if (this.name == "clyde") {
690
if ((game.level < 4) || ((game.pillCount > 104/3))) this.stop = true;
691
else this.stop = false;
692
}
693
// Inky starts after 30 pills and only from the third level on
694
if (this.name == "inky") {
695
if ((game.level < 3) || ((game.pillCount > 104-30))) this.stop = true;
696
else this.stop = false;
697
}
698
699
if ((this.getGridPosY() == 5) && this.inGrid()) {
700
if ((this.getGridPosX() == 7)) this.setDirection(right);
701
if ((this.getGridPosX() == 8) || this.getGridPosX() == 9) this.setDirection(up);
702
if ((this.getGridPosX() == 10)) this.setDirection(left);
703
}
704
if ((this.getGridPosY() == 4) && ((this.getGridPosX() == 8) || (this.getGridPosX() == 9)) && this.inGrid()) {
705
console.log("ghosthouse -> false");
706
this.ghostHouse = false;
707
}
708
}
709
710
if (!this.stop) {
711
// Move
712
this.posX += this.speed * this.dirX;
713
this.posY += this.speed * this.dirY;
714
715
// Check if out of canvas
716
if (this.posX >= game.width-this.radius) this.posX = this.speed-this.radius;
717
if (this.posX <= 0-this.radius) this.posX = game.width-this.speed-this.radius;
718
if (this.posY >= game.height-this.radius) this.posY = this.speed-this.radius;
719
if (this.posY <= 0-this.radius) this.posY = game.height-this.speed-this.radius;
720
}
721
}
722
723
this.checkCollision = function() {
724
725
/* Check Back to Home */
726
if (this.dead && (this.getGridPosX() == this.startPosX /30) && (this.getGridPosY() == this.startPosY / 30)) this.reset();
727
else {
728
729
/* Check Ghost / Pacman Collision */
730
if ((between(pacman.getCenterX(), this.getCenterX()-10, this.getCenterX()+10))
731
&& (between(pacman.getCenterY(), this.getCenterY()-10, this.getCenterY()+10)))
732
{
733
if ((!this.dazzled) && (!this.dead)) {
734
pacman.die();
735
}
736
else {
737
this.die();
738
}
739
}
740
}
741
}
742
743
/* Pathfinding */
744
this.getNextDirection = function() {
745
// get next field
746
var pX = this.getGridPosX();
747
var pY= this.getGridPosY();
748
game.getMapContent(pX,pY);
749
var u, d, r, l; // option up, down, right, left
750
751
// get target
752
if (this.dead) { // go Home
753
var tX = this.startPosX / 30;
754
var tY = this.startPosY / 30;
755
}
756
else if (game.ghostMode == 0) { // Scatter Mode
757
var tX = this.gridBaseX;
758
var tY = this.gridBaseY;
759
} else if (game.ghostMode == 1) { // Chase Mode
760
761
switch (this.name) {
762
763
// target: 4 ahead and 4 left of pacman
764
case "pinky":
765
var pdir = pacman.direction;
766
var pdirX = pdir.dirX == 0 ? - pdir.dirY : pdir.dirX;
767
var pdirY = pdir.dirY == 0 ? - pdir.dirX : pdir.dirY;
768
769
var tX = (pacman.getGridPosX() + pdirX*4) % (game.width / pacman.radius +1);
770
var tY = (pacman.getGridPosY() + pdirY*4) % (game.height / pacman.radius +1);
771
break;
772
773
// target: pacman
774
case "blinky":
775
var tX = pacman.getGridPosX();
776
var tY = pacman.getGridPosY();
777
break;
778
779
// target:
780
case "inky":
781
var tX = pacman.getGridPosX() + 2*pacman.direction.dirX;
782
var tY = pacman.getGridPosY() + 2*pacman.direction.dirY;
783
var vX = tX - blinky.getGridPosX();
784
var vY = tY - blinky.getGridPosY();
785
tX = Math.abs(blinky.getGridPosX() + vX*2);
786
tY = Math.abs(blinky.getGridPosY() + vY*2);
787
break;
788
789
// target: pacman, until pacman is closer than 5 grid fields, then back to scatter
790
case "clyde":
791
var tX = pacman.getGridPosX();
792
var tY = pacman.getGridPosY();
793
var dist = Math.sqrt(Math.pow((pX-tX),2) + Math.pow((pY - tY),2));
794
795
if (dist < 5) {
796
tX = this.gridBaseX;
797
tY = this.gridBaseY;
798
}
799
break;
800
801
}
802
}
803
804
805
var oppDir = this.getOppositeDirection(); // ghosts are not allowed to change direction 180�
806
807
var dirs = [{},{},{},{}];
808
dirs[0].field = game.getMapContent(pX,pY-1);
809
dirs[0].dir = up;
810
dirs[0].distance = Math.sqrt(Math.pow((pX-tX),2) + Math.pow((pY -1 - tY),2));
811
812
dirs[1].field = game.getMapContent(pX,pY+1);
813
dirs[1].dir = down;
814
dirs[1].distance = Math.sqrt(Math.pow((pX-tX),2) + Math.pow((pY+1 - tY),2));
815
816
dirs[2].field = game.getMapContent(pX+1,pY);
817
dirs[2].dir = right;
818
dirs[2].distance = Math.sqrt(Math.pow((pX+1-tX),2) + Math.pow((pY - tY),2));
819
820
dirs[3].field = game.getMapContent(pX-1,pY);
821
dirs[3].dir = left;
822
dirs[3].distance = Math.sqrt(Math.pow((pX-1-tX),2) + Math.pow((pY - tY),2));
823
824
// Sort possible directions by distance
825
function compare(a,b) {
826
if (a.distance < b.distance)
827
return -1;
828
if (a.distance > b.distance)
829
return 1;
830
return 0;
831
}
832
var dirs2 = dirs.sort(compare);
833
834
var r = this.dir;
835
var j;
836
837
if (this.dead) {
838
for (var i = dirs2.length-1; i >= 0; i--) {
839
if ((dirs2[i].field != "wall") && !(dirs2[i].dir.equals(this.getOppositeDirection()))) {
840
r = dirs2[i].dir;
841
}
842
}
843
}
844
else {
845
for (var i = dirs2.length-1; i >= 0; i--) {
846
if ((dirs2[i].field != "wall") && (dirs2[i].field != "door") && !(dirs2[i].dir.equals(this.getOppositeDirection()))) {
847
r = dirs2[i].dir;
848
}
849
}
850
}
851
this.directionWatcher.set(r);
852
return r;
853
}
854
this.setRandomDirection = function() {
855
var dir = Math.floor((Math.random()*10)+1)%5;
856
857
switch(dir) {
858
case 1:
859
if (this.getOppositeDirection().equals(up)) this.setDirection(down);
860
else this.setDirection(up);
861
break;
862
case 2:
863
if (this.getOppositeDirection().equals(down)) this.setDirection(up);
864
else this.setDirection(down);
865
break;
866
case 3:
867
if (this.getOppositeDirection().equals(right)) this.setDirection(left);
868
else this.setDirection(right);
869
break;
870
case 4:
871
if (this.getOppositeDirection().equals(left)) this.setDirection(right);
872
else this.setDirection(left);
873
break;
874
}
875
}
876
this.reverseDirection = function() {
877
console.log("reverseDirection: "+this.direction.name+" to "+this.getOppositeDirection().name);
878
this.directionWatcher.set(this.getOppositeDirection());
879
}
880
881
}
882
883
Ghost.prototype = new Figure();
884
885
// Super Class for Pacman & Ghosts
886
function Figure() {
887
this.posX;
888
this.posY;
889
this.speed;
890
this.dirX = right.dirX;
891
this.dirY = right.dirY;
892
this.direction;
893
this.stop = true;
894
this.directionWatcher = new directionWatcher();
895
this.getNextDirection = function() { console.log("Figure getNextDirection");};
896
this.checkDirectionChange = function() {
897
if (this.inGrid() && (this.directionWatcher.get() == null)) this.getNextDirection();
898
if ((this.directionWatcher.get() != null) && this.inGrid()) {
899
//console.log("changeDirection to "+this.directionWatcher.get().name);
900
this.setDirection(this.directionWatcher.get());
901
this.directionWatcher.set(null);
902
}
903
904
}
905
906
907
this.inGrid = function() {
908
if((this.posX % (2*this.radius) === 0) && (this.posY % (2*this.radius) === 0)) return true;
909
return false;
910
}
911
this.getOppositeDirection = function() {
912
if (this.direction.equals(up)) return down;
913
else if (this.direction.equals(down)) return up;
914
else if (this.direction.equals(right)) return left;
915
else if (this.direction.equals(left)) return right;
916
}
917
this.move = function() {
918
919
if (!this.stop) {
920
this.posX += this.speed * this.dirX;
921
this.posY += this.speed * this.dirY;
922
923
// Check if out of canvas
924
if (this.posX >= game.width-this.radius) this.posX = this.speed-this.radius;
925
if (this.posX <= 0-this.radius) this.posX = game.width-this.speed-this.radius;
926
if (this.posY >= game.height-this.radius) this.posY = this.speed-this.radius;
927
if (this.posY <= 0-this.radius) this.posY = game.height-this.speed-this.radius;
928
}
929
}
930
this.stop = function() { this.stop = true;}
931
this.start = function() { this.stop = false;}
932
933
this.getGridPosX = function() {
934
return (this.posX - (this.posX % 30))/30;
935
}
936
this.getGridPosY = function() {
937
return (this.posY - (this.posY % 30))/30;
938
}
939
this.setDirection = function(dir) {
940
this.dirX = dir.dirX;
941
this.dirY = dir.dirY;
942
this.angle1 = dir.angle1;
943
this.angle2 = dir.angle2;
944
this.direction = dir;
945
}
946
this.setPosition = function(x, y) {
947
this.posX = x;
948
this.posY = y;
949
}
950
}
951
952
function pacman() {
953
this.radius = 15;
954
this.posX = 0;
955
this.posY = 6*2*this.radius;
956
this.speed = 5;
957
this.angle1 = 0.25;
958
this.angle2 = 1.75;
959
this.mouth = 1; /* Switches between 1 and -1, depending on mouth closing / opening */
960
this.dirX = right.dirX;
961
this.dirY = right.dirY;
962
this.lives = 3;
963
this.stuckX = 0;
964
this.stuckY = 0;
965
this.frozen = false; // used to play die Animation
966
this.freeze = function () {
967
this.frozen = true;
968
}
969
this.unfreeze = function() {
970
this.frozen = false;
971
}
972
this.getCenterX = function () {
973
return this.posX+this.radius;
974
}
975
this.getCenterY = function () {
976
return this.posY+this.radius;
977
}
978
this.directionWatcher = new directionWatcher();
979
980
this.direction = right;
981
982
this.beastMode = false;
983
this.beastModeTimer = 0;
984
985
this.checkCollisions = function () {
986
987
if ((this.stuckX == 0) && (this.stuckY == 0) && this.frozen == false) {
988
989
// Get the Grid Position of Pac
990
var gridX = this.getGridPosX();
991
var gridY = this.getGridPosY();
992
var gridAheadX = gridX;
993
var gridAheadY = gridY;
994
995
var field = game.getMapContent(gridX, gridY);
996
997
// get the field 1 ahead to check wall collisions
998
if ((this.dirX == 1) && (gridAheadX < 17)) gridAheadX += 1;
999
if ((this.dirY == 1) && (gridAheadY < 12)) gridAheadY += 1;
1000
var fieldAhead = game.getMapContent(gridAheadX, gridAheadY);
1001
1002
1003
/* Check Pill Collision */
1004
if ((field === "pill") || (field === "powerpill")) {
1005
//console.log("Pill found at ("+gridX+"/"+gridY+"). Pacman at ("+this.posX+"/"+this.posY+")");
1006
if (
1007
((this.dirX == 1) && (between(this.posX, game.toPixelPos(gridX)+this.radius-5, game.toPixelPos(gridX+1))))
1008
|| ((this.dirX == -1) && (between(this.posX, game.toPixelPos(gridX), game.toPixelPos(gridX)+5)))
1009
|| ((this.dirY == 1) && (between(this.posY, game.toPixelPos(gridY)+this.radius-5, game.toPixelPos(gridY+1))))
1010
|| ((this.dirY == -1) && (between(this.posY, game.toPixelPos(gridY), game.toPixelPos(gridY)+5)))
1011
|| (fieldAhead === "wall")
1012
)
1013
{ var s;
1014
if (field === "powerpill") {
1015
Sound.play("powerpill");
1016
s = 50;
1017
this.enableBeastMode();
1018
game.startGhostFrightened();
1019
}
1020
else {
1021
Sound.play("waka");
1022
s = 10;
1023
game.pillCount--;
1024
}
1025
game.map.posY[gridY].posX[gridX].type = "null";
1026
game.score.add(s);
1027
}
1028
}
1029
1030
/* Check Wall Collision */
1031
if ((fieldAhead === "wall") || (fieldAhead === "door")) {
1032
this.stuckX = this.dirX;
1033
this.stuckY = this.dirY;
1034
pacman.stop();
1035
// get out of the wall
1036
if ((this.stuckX == 1) && ((this.posX % 2*this.radius) != 0)) this.posX -= 5;
1037
if ((this.stuckY == 1) && ((this.posY % 2*this.radius) != 0)) this.posY -= 5;
1038
if (this.stuckX == -1) this.posX += 5;
1039
if (this.stuckY == -1) this.posY += 5;
1040
}
1041
1042
}
1043
}
1044
this.checkDirectionChange = function() {
1045
if (this.directionWatcher.get() != null) {
1046
//console.log("next Direction: "+directionWatcher.get().name);
1047
1048
if ((this.stuckX == 1) && this.directionWatcher.get() == right) this.directionWatcher.set(null);
1049
else {
1050
// reset stuck events
1051
this.stuckX = 0;
1052
this.stuckY = 0;
1053
1054
1055
// only allow direction changes inside the grid
1056
if ((this.inGrid())) {
1057
//console.log("changeDirection to "+directionWatcher.get().name);
1058
1059
// check if possible to change direction without getting stuck
1060
console.log("x: "+this.getGridPosX()+" + "+this.directionWatcher.get().dirX);
1061
console.log("y: "+this.getGridPosY()+" + "+this.directionWatcher.get().dirY);
1062
var x = this.getGridPosX()+this.directionWatcher.get().dirX;
1063
var y = this.getGridPosY()+this.directionWatcher.get().dirY;
1064
if (x <= -1) x = game.width/(this.radius*2)-1;
1065
if (x >= game.width/(this.radius*2)) x = 0;
1066
if (y <= -1) x = game.height/(this.radius*2)-1;
1067
if (y >= game.heigth/(this.radius*2)) y = 0;
1068
1069
console.log("x: "+x);
1070
console.log("y: "+y);
1071
var nextTile = game.map.posY[y].posX[x].type;
1072
console.log("checkNextTile: "+nextTile);
1073
1074
if (nextTile != "wall") {
1075
this.setDirection(this.directionWatcher.get());
1076
this.directionWatcher.set(null);
1077
}
1078
}
1079
}
1080
}
1081
}
1082
this.setDirection = function(dir) {
1083
if (!this.frozen) {
1084
this.dirX = dir.dirX;
1085
this.dirY = dir.dirY;
1086
this.angle1 = dir.angle1;
1087
this.angle2 = dir.angle2;
1088
this.direction = dir;
1089
}
1090
}
1091
this.enableBeastMode = function() {
1092
this.beastMode = true;
1093
this.beastModeTimer = 240;
1094
//console.log("Beast Mode activated!");
1095
inky.dazzle();
1096
pinky.dazzle();
1097
blinky.dazzle();
1098
clyde.dazzle();
1099
};
1100
this.disableBeastMode = function() {
1101
this.beastMode = false;
1102
//console.log("Beast Mode is over!");
1103
inky.undazzle();
1104
pinky.undazzle();
1105
blinky.undazzle();
1106
clyde.undazzle();
1107
};
1108
this.move = function() {
1109
1110
if (!this.frozen) {
1111
if (this.beastModeTimer > 0) {
1112
this.beastModeTimer--;
1113
//console.log("Beast Mode: "+this.beastModeTimer);
1114
}
1115
if ((this.beastModeTimer == 0) && (this.beastMode == true)) this.disableBeastMode();
1116
1117
this.posX += this.speed * this.dirX;
1118
this.posY += this.speed * this.dirY;
1119
1120
// Check if out of canvas
1121
if (this.posX >= game.width-this.radius) this.posX = 5-this.radius;
1122
if (this.posX <= 0-this.radius) this.posX = game.width-5-this.radius;
1123
if (this.posY >= game.height-this.radius) this.posY = 5-this.radius;
1124
if (this.posY <= 0-this.radius) this.posY = game.height-5-this.radius;
1125
}
1126
else this.dieAnimation();
1127
}
1128
1129
this.eat = function () {
1130
1131
if (!this.frozen) {
1132
if (this.dirX == this.dirY == 0) {
1133
1134
this.angle1 -= this.mouth*0.07;
1135
this.angle2 += this.mouth*0.07;
1136
1137
var limitMax1 = this.direction.angle1;
1138
var limitMax2 = this.direction.angle2;
1139
var limitMin1 = this.direction.angle1 - 0.21;
1140
var limitMin2 = this.direction.angle2 + 0.21;
1141
1142
if (this.angle1 < limitMin1 || this.angle2 > limitMin2)
1143
{
1144
this.mouth = -1;
1145
}
1146
if (this.angle1 >= limitMax1 || this.angle2 <= limitMax2)
1147
{
1148
this.mouth = 1;
1149
}
1150
}
1151
}
1152
}
1153
this.stop = function() {
1154
this.dirX = 0;
1155
this.dirY = 0;
1156
}
1157
this.reset = function() {
1158
this.unfreeze();
1159
this.posX = 0;
1160
this.posY = 6*2*this.radius;
1161
this.setDirection(right);
1162
this.stop();
1163
this.stuckX = 0;
1164
this.stuckY = 0;
1165
//console.log("reset pacman");
1166
}
1167
this.dieAnimation = function() {
1168
this.angle1 += 0.05;
1169
this.angle2 -= 0.05;
1170
if (this.angle1 >= this.direction.angle1+0.7 || this.angle2 <= this.direction.angle2-0.7) {
1171
this.dieFinal();
1172
}
1173
}
1174
this.die = function() {
1175
Sound.play("die");
1176
this.freeze();
1177
this.dieAnimation();
1178
}
1179
this.dieFinal = function() {
1180
this.reset();
1181
pinky.reset();
1182
inky.reset();
1183
blinky.reset();
1184
clyde.reset();
1185
this.lives--;
1186
console.log("pacman died, "+this.lives+" lives left");
1187
if (this.lives <= 0) {
1188
var input = "<div id='highscore-form'><span id='form-validater'></span><input type='text' id='playerName'/><span class='button' id='score-submit'>save</span></div>";
1189
game.showMessage("Game over","Total Score: "+game.score.score+input);
1190
game.gameOver = true;
1191
$('#playerName').focus();
1192
}
1193
game.drawHearts(this.lives);
1194
}
1195
this.getGridPosX = function() {
1196
return (this.posX - (this.posX % 30))/30;
1197
}
1198
this.getGridPosY = function() {
1199
return (this.posY - (this.posY % 30))/30;
1200
}
1201
}
1202
pacman.prototype = new Figure();
1203
var pacman = new pacman();
1204
game.buildWalls();
1205
1206
1207
// Check if a new cache is available on page load.
1208
function checkAppCache() {
1209
console.log('check AppCache');
1210
window.applicationCache.addEventListener('updateready', function(e)
1211
{
1212
console.log("AppCache: updateready");
1213
if (window.applicationCache.status == window.applicationCache.UPDATEREADY) {
1214
1215
// Browser downloaded a new app cache.
1216
// Swap it in and reload the page to get the new hotness.
1217
window.applicationCache.swapCache();
1218
if (confirm('A new version of this site is available. Load it?')) {
1219
window.location.reload();
1220
}
1221
1222
} else {
1223
// Manifest didn't change. Nothing new to server.
1224
}
1225
}, false);
1226
1227
window.applicationCache.addEventListener('cached', function(e)
1228
{
1229
console.log("AppCache: cached");
1230
}, false);
1231
1232
}
1233
1234
1235
// Action starts here:
1236
1237
function hideAdressbar() {
1238
console.log("hide adressbar");
1239
$("html").scrollTop(1);
1240
$("body").scrollTop(1);
1241
}
1242
1243
$(document).ready(function() {
1244
1245
$.ajaxSetup({ mimeType: "application/json" });
1246
1247
$.ajaxSetup({beforeSend: function(xhr){
1248
if (xhr.overrideMimeType){
1249
xhr.overrideMimeType("application/json");
1250
//console.log("mimetype set to json");
1251
}
1252
}
1253
});
1254
1255
// Hide address bar
1256
hideAdressbar();
1257
1258
if (window.applicationCache != null) checkAppCache();
1259
1260
/* -------------------- EVENT LISTENERS -------------------------- */
1261
1262
// Listen for resize changes
1263
/*window.addEventListener("resize", function() {
1264
// Get screen size (inner/outerWidth, inner/outerHeight)
1265
// deactivated because of problems
1266
if ((window.outerHeight < window.outerWidth) && (window.outerHeight < 720)) {
1267
game.showMessage("Rotate Device","Your screen is too small to play in landscape view.");
1268
console.log("rotate your device to portrait!");
1269
}
1270
}, false);*/
1271
1272
1273
// --------------- Controls
1274
1275
1276
// Keyboard
1277
window.addEventListener('keydown',doKeyDown,true);
1278
1279
$('#canvas-container').click(function() {
1280
if (!(game.gameOver == true)) game.pauseResume();
1281
});
1282
1283
$('body').on('click', '#score-submit', function(){
1284
console.log("submit highscore pressed");
1285
if ($('#playerName').val() === "" || $('#playerName').val() === undefined) {
1286
$('#form-validater').html("Please enter a name<br/>");
1287
} else {
1288
$('#form-validater').html("");
1289
addHighscore();
1290
}
1291
});
1292
1293
$('body').on('click', '#show-highscore', function(){
1294
game.showContent('highscore-content');
1295
getHighscore();
1296
});
1297
1298
// Hammerjs Touch Events
1299
/*Hammer('#canvas-container').on("tap", function(event) {
1300
if (!(game.gameOver == true)) game.pauseResume();
1301
});*/
1302
Hammer('.container').on("swiperight", function(event) {
1303
if ($('#game-content').is(":visible")) {
1304
event.gesture.preventDefault();
1305
pacman.directionWatcher.set(right);
1306
}
1307
});
1308
Hammer('.container').on("swipeleft", function(event) {
1309
if ($('#game-content').is(":visible")) {
1310
event.gesture.preventDefault();
1311
pacman.directionWatcher.set(left);
1312
}
1313
});
1314
Hammer('.container').on("swipeup", function(event) {
1315
if ($('#game-content').is(":visible")) {
1316
event.gesture.preventDefault();
1317
pacman.directionWatcher.set(up);
1318
}
1319
});
1320
Hammer('.container').on("swipedown", function(event) {
1321
if ($('#game-content').is(":visible")) {
1322
event.gesture.preventDefault();
1323
pacman.directionWatcher.set(down);
1324
}
1325
});
1326
1327
// Mobile Control Buttons
1328
$(document).on('touchend mousedown','#up',function(event) {
1329
event.preventDefault();
1330
pacman.directionWatcher.set(up);
1331
});
1332
$(document).on('touchend mousedown','#down',function(event) {
1333
event.preventDefault();
1334
pacman.directionWatcher.set(down);
1335
});
1336
$(document).on('touchend mousedown','#left',function(event) {
1337
event.preventDefault();
1338
pacman.directionWatcher.set(left);
1339
});
1340
$(document).on('touchend mousedown','#right',function(event) {
1341
event.preventDefault();
1342
pacman.directionWatcher.set(right);
1343
});
1344
1345
// Menu
1346
$(document).on('click','.button#newGame',function(event) {
1347
game.newGame();
1348
});
1349
$(document).on('click','.button#highscore',function(event) {
1350
game.showContent('highscore-content');
1351
getHighscore();
1352
});
1353
$(document).on('click','.button#instructions',function(event) {
1354
game.showContent('instructions-content');
1355
});
1356
$(document).on('click','.button#info',function(event) {
1357
game.showContent('info-content');
1358
});
1359
// back button
1360
$(document).on('click','.button#back',function(event) {
1361
game.showContent('game-content');
1362
});
1363
// toggleSound
1364
$(document).on('click','.controlSound',function(event) {
1365
game.toggleSound();
1366
});
1367
// get latest
1368
$(document).on('click', '#updateCode', function(event) {
1369
console.log('check for new version');
1370
event.preventDefault();
1371
window.applicationCache.update();
1372
});
1373
1374
// checkAppCache();
1375
1376
canvas = $("#myCanvas").get(0);
1377
context = canvas.getContext("2d");
1378
1379
1380
1381
/* --------------- GAME INITIALISATION ------------------------------------
1382
1383
TODO: put this into Game object and change code to accept different setups / levels
1384
1385
-------------------------------------------------------------------------- */
1386
1387
game.init(0);
1388
logger.disableLogger();
1389
1390
renderContent();
1391
});
1392
1393
function renderContent()
1394
{
1395
//context.save()
1396
1397
// Refresh Score
1398
game.score.refresh(".score");
1399
1400
// Pills
1401
context.beginPath();
1402
context.fillStyle = "White";
1403
context.strokeStyle = "White";
1404
1405
var dotPosY;
1406
$.each(game.map.posY, function(i, item) {
1407
dotPosY = this.row;
1408
$.each(this.posX, function() {
1409
if (this.type == "pill") {
1410
context.arc(game.toPixelPos(this.col-1)+pacman.radius,game.toPixelPos(dotPosY-1)+pacman.radius,game.pillSize,0*Math.PI,2*Math.PI);
1411
context.moveTo(game.toPixelPos(this.col-1), game.toPixelPos(dotPosY-1));
1412
}
1413
else if (this.type == "powerpill") {
1414
context.arc(game.toPixelPos(this.col-1)+pacman.radius,game.toPixelPos(dotPosY-1)+pacman.radius,game.powerpillSizeCurrent,0*Math.PI,2*Math.PI);
1415
context.moveTo(game.toPixelPos(this.col-1), game.toPixelPos(dotPosY-1));
1416
}
1417
});
1418
});
1419
console.log("pps: " + game.nextPowerPillSize());
1420
context.fill();
1421
1422
// Walls
1423
context.drawImage(canvas_walls, 0, 0);
1424
1425
1426
if (game.running == true) {
1427
// Ghosts
1428
pinky.draw(context);
1429
blinky.draw(context);
1430
inky.draw(context);
1431
clyde.draw(context);
1432
1433
1434
// Pac Man
1435
context.beginPath();
1436
context.fillStyle = "Yellow";
1437
context.strokeStyle = "Yellow";
1438
context.arc(pacman.posX+pacman.radius,pacman.posY+pacman.radius,pacman.radius,pacman.angle1*Math.PI,pacman.angle2*Math.PI);
1439
context.lineTo(pacman.posX+pacman.radius, pacman.posY+pacman.radius);
1440
context.stroke();
1441
context.fill();
1442
}
1443
1444
}
1445
1446
function renderGrid(gridPixelSize, color)
1447
{
1448
context.save();
1449
context.lineWidth = 0.5;
1450
context.strokeStyle = color;
1451
1452
// horizontal grid lines
1453
for(var i = 0; i <= canvas.height; i = i + gridPixelSize)
1454
{
1455
context.beginPath();
1456
context.moveTo(0, i);
1457
context.lineTo(canvas.width, i);
1458
context.closePath();
1459
context.stroke();
1460
}
1461
1462
// vertical grid lines
1463
for(var i = 0; i <= canvas.width; i = i + gridPixelSize)
1464
{
1465
context.beginPath();
1466
context.moveTo(i, 0);
1467
context.lineTo(i, canvas.height);
1468
context.closePath();
1469
context.stroke();
1470
}
1471
1472
context.restore();
1473
}
1474
1475
function animationLoop()
1476
{
1477
canvas.width = canvas.width;
1478
//renderGrid(pacman.radius, "red");
1479
renderContent();
1480
1481
if (game.dieAnimation == 1) pacman.dieAnimation();
1482
if (game.pause != true){
1483
// Make changes before next loop
1484
pacman.move();
1485
pacman.eat();
1486
pacman.checkDirectionChange();
1487
pacman.checkCollisions(); // has to be the LAST method called on pacman
1488
1489
1490
1491
blinky.move();
1492
inky.move();
1493
pinky.move();
1494
clyde.move();
1495
1496
game.checkGhostMode();
1497
}
1498
1499
// All dots collected?
1500
game.check();
1501
1502
1503
//requestAnimationFrame(animationLoop);
1504
setTimeout(animationLoop, game.refreshRate);
1505
1506
1507
}
1508
1509
1510
1511
function doKeyDown(evt){
1512
1513
switch (evt.keyCode)
1514
{
1515
case 38: // UP Arrow Key pressed
1516
evt.preventDefault();
1517
case 87: // W pressed
1518
pacman.directionWatcher.set(up);
1519
break;
1520
case 40: // DOWN Arrow Key pressed
1521
evt.preventDefault();
1522
case 83: // S pressed
1523
pacman.directionWatcher.set(down);
1524
break;
1525
case 37: // LEFT Arrow Key pressed
1526
evt.preventDefault();
1527
case 65: // A pressed
1528
pacman.directionWatcher.set(left);
1529
break;
1530
case 39: // RIGHT Arrow Key pressed
1531
evt.preventDefault();
1532
case 68: // D pressed
1533
pacman.directionWatcher.set(right);
1534
break;
1535
case 78: // N pressed
1536
if (!$('#playerName').is(':focus')) {
1537
game.pause = 1;
1538
game.newGame();
1539
}
1540
break;
1541
case 77: // M pressed
1542
game.toggleSound();
1543
break;
1544
case 8: // Backspace pressed -> show Game Content
1545
case 27: // ESC pressed -> show Game Content
1546
if (!$('#playerName').is(':focus')) {
1547
evt.preventDefault();
1548
game.showContent('game-content');
1549
}
1550
break;
1551
case 32: // SPACE pressed -> pause Game
1552
evt.preventDefault();
1553
if (!(game.gameOver == true)
1554
&& $('#game-content').is(':visible')
1555
) game.pauseResume();
1556
break;
1557
}
1558
}
1559
}
1560
1561
geronimo();
1562