-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathscript.js
349 lines (294 loc) · 12.5 KB
/
script.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
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
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
let cnv = document.querySelector("canvas"); //pegando o canvas em uma variavel
let ctx = cnv.getContext("2d"); //variavel que armazena o contexto de renderização do canvas
let width = cnv.width //largura canvas
let height = cnv.height //altura canvas
var x; //variavel que vai se usada como eixo x
var y; //variavel que vai se usada como eixo y
let tileSize = 164; //variavel de controle
let tileSrcSize = 96;
//somzeira insana infinita
const som = new Audio("8bits.mp3")
som.loop = -1
//imagem que na teoria tem uma função ali, mas n boto fé nao, tive que usar um setInterval()
let img = new Image()
img.src = "img.png"
img.addEventListener("load", function(){
//primeira chamada do labirinto
requestAnimationFrame(loop, cnv)
}, false)
//teclas de movimentação
let left = 37
let up = 38
let right = 39
let down = 40
//variaveis de controle movimentação
let mvLeft = false
let mvUp = false
let mvRight = false
let mvDown = false
//personagem
class player{
constructor(){
this.px = tileSize + 2;
this.py = tileSize + 2;
this.width = 24;
this.height = 32;
this.speed = 2;
this.srcX = 0;
this.srcY = tileSrcSize;
this.countAnim = 0;
}
}
//chamando o personagem em uma variavel
let play = new player()
let walls = [] //paredes onde o personagem vai colidir;
//labirinto
let maze = [
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,0,1,1,1,1,1,1,1,1,1,1],
[1,0,1,0,0,1,1,0,0,0,0,1,0,0,0,0,0,0,1,0,1,1,1,0,1,0,0,0,0,0,0,0,0,1],
[1,0,0,0,0,0,0,0,1,1,0,1,0,1,1,1,0,0,1,0,1,0,0,0,1,1,0,1,0,1,0,1,0,1],
[1,0,0,1,1,1,1,0,0,1,0,0,0,0,0,1,0,1,1,0,1,1,1,0,0,1,1,1,0,1,0,1,0,1],
[1,0,0,1,0,0,0,0,0,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1],
[1,0,0,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,0,1,0,1,0,1,0,1],
[1,0,0,0,1,1,0,1,1,1,1,1,0,1,1,1,1,1,1,1,0,0,0,0,0,1,1,1,0,1,0,1,0,1],
[1,0,1,0,0,1,0,0,0,0,0,1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1],
[1,0,1,1,1,1,0,1,1,1,1,1,0,1,0,1,0,1,0,1,0,1,0,0,1,1,1,1,1,0,0,1,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,1,0,0,1,0,1],
[1,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,0,1,0,1,0,1,0,1,0,1,0,0,1,0,0,1,0,1],
[1,0,0,0,0,0,1,0,1,0,0,0,0,0,0,1,0,1,0,0,0,1,0,0,0,1,1,0,0,0,1,1,1,1],
[1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,1,1,0,0,0,0,0,1,0,1],
[1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,1,1,1,0,0,0,1,0,1],
[1,0,1,0,1,0,0,0,1,0,1,1,1,1,1,1,0,1,1,1,1,1,1,0,0,1,0,1,0,1,1,1,0,1],
[1,0,1,0,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,0,1],
[1,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,1],
[1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,0,1,1,1,0,1,1,1,1,0,0,0,0,1,0,1,0,1],
[1,1,1,1,1,1,1,1,1,0,1,1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,0,1,0,1,0,1,0,1],
[1,0,0,0,0,0,0,0,1,0,0,0,0,1,0,1,0,1,0,1,0,1,0,1,1,1,1,1,0,1,0,1,0,1],
[1,0,1,1,1,1,1,0,1,0,1,0,0,1,0,0,0,1,0,0,0,1,0,1,0,0,0,1,0,1,0,1,0,1],
[1,0,1,0,0,0,1,0,1,0,1,0,0,1,1,1,1,1,0,1,0,1,0,1,0,1,1,1,1,1,1,1,0,1],
[1,0,1,0,1,0,1,0,1,0,1,0,0,0,0,0,0,1,0,1,0,1,0,1,0,0,1,0,1,0,0,0,0,1],
[1,0,1,0,1,1,1,0,1,1,1,0,1,1,1,1,1,1,1,1,0,1,0,1,1,0,1,0,1,0,1,1,0,1],
[1,0,1,0,1,0,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,1,0,1,0,0,1],
[1,0,1,0,1,1,1,1,1,1,1,1,1,1,1,0,1,0,1,1,1,0,0,1,1,1,1,0,1,0,1,0,1,1],
[1,0,0,0,0,0,0,0,0,0,1,0,0,0,1,0,1,0,1,0,1,0,0,0,0,0,1,0,1,0,1,0,0,1],
[1,0,1,1,1,1,0,1,1,0,1,0,1,1,1,0,1,0,1,0,0,0,1,1,1,1,1,0,1,1,1,1,0,1],
[1,0,1,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
];
const total_width = maze[0].length * tileSize;
const total_height = maze.length * tileSize;
//pegando os elementos que sao o muro
for(let row in maze){
for(let column in maze[row]){
let tile = maze[row][column];
if(tile === 1){
let wall = {
x: tileSize*column,
y: tileSize*row,
width: tileSize,
height: tileSize
};
walls.push(wall)
}
}
}
//class camera
class Cam{
constructor(){
this.posX = 0
this.posY = 0
this.width = width
this.height = height
this.leftMovCam()
this.topMovCam()
this.rightMovCam()
this.bottomMovCam()
}
//move camera pra esquerda quando necessario
leftMovCam = () => {
return this.posX + (this.width*0.25)
}
//move camera para o topo quando necessario
topMovCam = () => {
return this.posY + (this.height*0.25)
}
//move camera pra direita quando necessario
rightMovCam = () => {
return this.posX + (this.width*0.75)
}
//move camera para baixo quando necessario
bottomMovCam = () => {
return this.posY + (this.height*0.75)
}
}
let camera = new Cam() //crio e controlo a camera
//função que controla a camera de acordo com a posição do personagem
controllForCam = () => {
//se a posição do jogar em X for menor que a posição da cameca na função leftMovCam(), a
//camera ira se ajustar, pois posição camera em X recebe posição do personagem em X menos
//25% da largura da camera, a mesma logica se aplica aos outros if, digo, a logica de
//ajustar a camera conforme o player se move.
if(play.px < camera.leftMovCam()) {
camera.posX = play.px - (camera.width * 0.25)
}
if(play.py < camera.topMovCam()) {
camera.posY = play.py - (camera.height * 0.25)
}
if(play.px + play.width > camera.rightMovCam()){
camera.posX = play.px + play.width - (camera.width * 0.75)
}
if(play.py + play.height > camera.bottomMovCam()){
camera.posY = play.py + play.height - (camera.height * 0.75)
}
camera.posX = Math.max(0, Math.min(total_width - camera.width, camera.posX));
camera.posY = Math.max(0, Math.min(total_height - camera.height, camera.posY));
}
//função que controla a colusão com do player com os objetos
//entra 2 objetos, o jogador e os blocos
blockRectangle = (objA, objB) => {
//pega a metade de cada um em cada eixo
let distX = (objA.px + objA.width/2) - (objB.x + objB.width/2);
let distY = (objA.py + objA.height/2) - (objB.y + objB.height/2);
//pega a largura e altura de cada objeto e divide por 2
let sumWidth = (objA.width + objB.width)/2
let sumHeight = (objA.height + objB.height)/2
//pega o calor da distancia dos eixos e coloca nas variaveis
if(Math.abs(distX) < sumWidth && Math.abs(distY) < sumHeight){
let overlapX = sumWidth - Math.abs(distX);
let overlapY = sumHeight - Math.abs(distY)
//se valor de eixo X for maior que eixo Y a equação fica valendo
if(overlapX > overlapY){
//caso a posição y do objeto seja maior do que 0 py recebe - overlapY que é a
//diferença de distancia entre eles, assim criando algo parecido com bloqueio de movimento.
objA.py = distY > 0 ? objA.py + overlapY : objA.py - overlapY
}
else{
objA.px = distX > 0 ? objA.px + overlapX : objA.px - overlapX
}
}
}
//testando para ver se é 1 muro
parede = () => {
for( let i in walls){
let parede = walls[i];
blockRectangle(play, parede)
}
}
//função de quando a gente clica para andar
function keydownHandler(e) {
var key = e.keyCode
switch(key){
case left:
mvLeft = true;
break;
case up:
mvUp = true;
break;
case right:
mvRight = true;
break;
case down:
mvDown = true;
break;
}
}
//função que o personagem para de andar al saltar 1 tecla, mv recebe false, fazendo o movimento parar.
function keyupHandler(e) {
var key = e.keyCode
switch(key){
case left:
mvLeft = false;
break;
case up:
mvUp = false;
break;
case right:
mvRight = false;
break;
case down:
mvDown = false;
break;
}
}
// evento de pegar uma tecla e presionar para andar
window.addEventListener("keydown", keydownHandler, false)
// evento que a maquina entende que parou de precionar a tecla
window.addEventListener("keyup", keyupHandler, false)
//função usada para atualizar os elementos do jogo
upadate = () => {
//caso mvLeft seja true, e mvRight seja falso mas tambem seja o inverso disso, o
if(mvLeft && !mvRight){
play.px -= play.speed
//aqui pega os quadros, se olha bem a imagem é como uma matriz bidemensional
play.srcY = tileSrcSize + play.height * 2
}
else if(mvRight && !mvLeft){
play.px += play.speed
//aqui ele pega ao virar para direita a imagem da linha 3, que na verdade é a linha 4,
//mas como uma matriz começa do 0 ent...
play.srcY = tileSrcSize + play.height * 3
}
if(mvUp && !mvDown){
play.py -= play.speed
play.srcY = tileSrcSize + play.height * 1
}
else if(mvDown && !mvUp){
play.py += play.speed
play.srcY = tileSrcSize + play.height * 0
}
//toda vez que uma destas variaveis for true inclementa +1 em play.countAnim;
if(mvLeft || mvRight || mvUp || mvDown){
play.countAnim++;
//se play.countAnim for maior que 40 da merda, a animação buga, por que tem somente
//8 imagems
if(play.countAnim >= 40){
play.countAnim = 0
}
//aqui ele pega na coloca e anima o passo, por isso é o countAnim/5 sendo um numero
//inteiro, ai multiplicamos pelo play.width que conseguimos a movimentação desejada
play.srcX = Math.floor(play.countAnim/5) * play.width
}
parede()
controllForCam()
}
//função usada para renderizar os elementos da tela
render = () => {
//limpa os quadros do canva a cada quadro, para fazer o movimento
ctx.clearRect(0,0, width, height);
ctx.save()
//atualiza as posições da camera
ctx.translate(-camera.posX, -camera.posY)
//nos 2 for() eu pego os indices e armazeno os elementos em uma variavel chamada tile,
//após isso verifico com um if se um dos elementos for igual a 1 atraves da variavel tile,
//sendo igual eu armazeno os elementos da coluna que sao igual a 1 na variavel x, e os elementos
//da linha na variavel y, logo após eu renderizo.
for(let row in maze){
for(let column in maze[row]){
let tile = maze[row][column];
var x = column*tileSize
var y = row*tileSize
//ctx.fillRect(x,y,tileSize,tileSize) nao uso mais
ctx.drawImage(
img,
tile * tileSrcSize, 0, tileSrcSize, tileSrcSize,
x, y, tileSize, tileSize
)
}
}
//ctx.fillStyle = "#00f"; nao uso mais, era pra dar cor pro personagem
//ctx.fillRect(play.px,play.py, play.width, play.height) nao uso mais
ctx.drawImage(
img,
play.srcX, play.srcY, play.width, play.height,
play.px, play.py, play.width, play.height
)
ctx.restore()
}
//função que fica se repetindo chamando as outras funções
loop = () => {
som.play()
upadate();
render();
requestAnimationFrame(render, cnv)
}
const start = setInterval(loop, 10)