-
Notifications
You must be signed in to change notification settings - Fork 0
/
ghost.js
157 lines (143 loc) · 4.71 KB
/
ghost.js
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
let ghosts = [
{
x: 10 + pillDistance * 6,
y: 10 + pillDistance * 6,
direction: 4,
active: true,
clipX: 120,
clipY: 0,
steps: 0
},
{
x: 10 + pillDistance * 7,
y: 10 + pillDistance * 6,
direction: 1,
active: true,
clipX: 120,
clipY: 0,
steps: 0
}
];
const ghost_speed = 3;
let imageObj = new Image();
imageObj.src = "minos.png";
// Create ghosts.
function createGhosts() {
// Set ghosts position.
updateGhosts();
// Render ghosts.
ghosts.forEach(ghost => {
if (ghost.active) {
let canvasGhost = document.createElement("canvas");
let ghostContext = canvasGhost.getContext("2d");
canvasGhost.width = canvasGhost.height = objectSize;
/*if (bluePillIsActive) {
ghostContext.drawImage(imageObj, 0, 498, 100, 100, 0, 0, 30, 30);
canvasContext.drawImage(ghostContext.canvas, ghost.x, ghost.y);
} else {*/
// Get image of ghost from sprite.
ghost.clipX = 120;
switch (ghost.direction) {
case 1:
ghost.clipY = 40;
break;
case 2:
ghost.clipY = 120;
break;
case 3:
ghost.clipY = 0;
break;
case 4:
ghost.clipY = 80;
break;
}
if (ghost.steps % 9 >= 6) {
ghost.clipX = 160;
} else if (ghost.steps % 9 >= 3) {
ghost.clipX = 200;
}
ghostContext.drawImage(imageObj, ghost.clipX, ghost.clipY, 40, 40, 0, 0, 30, 30);
canvasContext.drawImage(ghostContext.canvas, ghost.x, ghost.y);
ghost.steps += 1;
//}
}
});
}
/**
* Calculate ghost next direction.
*/
function updateGhosts() {
ghosts.forEach(ghost => {
if (ghost.active) {
if (!detectWallCollisionOnDirection(ghost.x, ghost.y, ghost.direction)) {
switch (ghost.direction) {
case 1:
ghost.y -= ghost_speed;
break;
case 2:
ghost.x += ghost_speed;
break;
case 3:
ghost.y += ghost_speed;
break;
case 4:
ghost.x -= ghost_speed;
break;
}
} else {
ghost.direction = calculateNextDirectionBasedOnPacmanPosition(ghost);
}
}
});
}
function calculateNextDirectionBasedOnPacmanPosition(ghost) {
const dx = pacman.x - ghost.x;
const dy = pacman.y - ghost.y;
// The preferred axis will be x if true, y if false.
preferredAxis = Math.abs(dx) >= Math.abs(dy);
// Create an order of choices array. The first value is the choice based on
// preferred axis and distance and the second is the direction, the ghost,
// should choose.
let choices = [
[!preferredAxis && dx == 0, 1],
[preferredAxis && dy == 0, 2],
[!preferredAxis && dx == 0, 3],
[preferredAxis && dy == 0, 4],
[!preferredAxis && dy <= 0, 1],
[preferredAxis && dx >= 0, 2],
[!preferredAxis && dy >= 0, 3],
[preferredAxis && dx <= 0, 4],
[preferredAxis && dy <= 0, 1],
[!preferredAxis && dx >= 0, 2],
[preferredAxis && dy >= 0, 3],
[preferredAxis && dx <= 0, 4]
];
// Reverse array of choices if super pill is active.
choices = superPillActive ? choices.reverse() : choices;
for (var i = 0; i < choices.length; i++) {
if (choices[i][0] && !detectWallCollisionOnDirection(ghost.x, ghost.y, choices[i][1])) {
return choices[i][1];
}
}
// If no choice found.
return Math.floor(Math.random() * 4 + 1);
}
function detectGhostPacmanCollision() {
// If ghosts are not blue, the game is lost and it resets, if ghosts are blue,
// the ghost is set inactive for some seconds.
ghosts.forEach(ghost => {
if (detectObjectsCollision(pacman.x, pacman.y, objectSize, objectSize, ghost.x, ghost.y, objectSize, objectSize, 10)) {
if (superPillActive) {
// Disable ghost.
ghost.active = false;
ghost.x = 10 + pillDistance * 7;
ghost.y = 10 + pillDistance * 6;
setTimeout(function() {
ghost.active = true;
}, 6000);
} else {
defeat = true;
}
}
});
}