-
Notifications
You must be signed in to change notification settings - Fork 0
/
movimentacao.c
296 lines (271 loc) · 10.7 KB
/
movimentacao.c
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
#include "main.h"
int moveHero(HEROI* heroi, char mapa[HEIGHT][WIDTH], CHAVE chave, SAIDA* saida)
{
putchxy(heroi->x, heroi->y, CHAR_ESPACO); //Apaga posicao atual do heroi
switch(heroi->direcao)
{
case PARADO:
break;
case CIMA:
if (mapa[heroi->y-1][heroi->x] != '#')
heroi->y--;
break;
case BAIXO:
if (mapa[heroi->y+1][heroi->x] != '#')
heroi->y++;
break;
case ESQUERDA:
if (mapa[heroi->y][heroi->x-1] != '#')
heroi->x--;
break;
case DIREITA:
if (mapa[heroi->y][heroi->x+1] != '#')
heroi->x++;
break;
}
colisaoPontos(heroi, mapa, chave, saida);
heroi->direcao = PARADO; //Reseta a direcao do heroi, já que já usamos a anterior
heroi->ciclos = CICLOS_HEROI; //Coloca seus ciclos de volta no maximo, para dar o tempo certo da sua movimentação
putchxy(heroi->x, heroi->y, CHAR_HEROI); //Printa o heroi na sua nova posição
return checaVitoria(heroi, saida); //Retorna se ganhou ou não
}
void moveTiro(TIRO* tiro, INIMIGOS* inimigos, char mapa[HEIGHT][WIDTH])
{
int i; // Variavel contadora
if(tiro->t_restante != 12)
{
putchxy(tiro->x, tiro->y, CHAR_ESPACO); //Apaga a posicao atual do tiro, apenas se não é a primeira vez que ele é desenhado
}
tiro->t_restante--; //Move o tiro uma posicao pra frente
switch(tiro->direcao)
{
case PARADO:
break;
case CIMA:
if (mapa[tiro->y-1][tiro->x] != '#' && mapa[tiro->y-1][tiro->x] != '0')
tiro->y--;
else
tiro->t_restante = 0; //Se acertou a parede ou refem, zera a distancia do tiro
break;
case BAIXO:
if (mapa[tiro->y+1][tiro->x] != '#' && mapa[tiro->y+1][tiro->x] != '0')
tiro->y++;
else
tiro->t_restante = 0; //Se acertou a parede ou refem, zera a distancia do tiro
break;
case ESQUERDA:
if (mapa[tiro->y][tiro->x-1] != '#' && mapa[tiro->y][tiro->x-1] != '0')
tiro->x--;
else
tiro->t_restante = 0; //Se acertou a parede ou refem, zera a distancia do tiro
break;
case DIREITA:
if (mapa[tiro->y][tiro->x+1] != '#' && mapa[tiro->y][tiro->x+1] != '0')
tiro->x++;
else
tiro->t_restante = 0; //Se acertou a parede ou refem, zera a distancia do tiro
break;
}
for(i=0; i<inimigos->qtde; i++) //Verifica se bala acertou inimigo
{
if(tiro->x == inimigos->listaInimigos[i].x && tiro->y == inimigos->listaInimigos[i].y)
{
inimigos->listaInimigos[i].t_sono = CICLOS_SONO;
tiro->t_restante = 0; // Se acertou o inimigo, zera a distancia do tiro
break; //Não precisa verificar os outros inimigos, apenas um deles
}
}
//Printa a posicao atual do tiro
if(tiro->t_restante)
{
if(tiro->direcao == CIMA || tiro->direcao == BAIXO)
putchxy(tiro->x, tiro->y, CHAR_TIRO_V);
else
putchxy(tiro->x, tiro->y, CHAR_TIRO_H);
}
return;
}
void moveInimigos(INIMIGO* inimigo, char mapa[HEIGHT][WIDTH])
{
visaoInimigo(APAGA, inimigo->x, inimigo->y, inimigo->direcao == PARADO ? inimigo->u_direcao : inimigo->direcao, mapa); //Apaga a visão anterior
if(!inimigo->t_sono) //Se o inimigo não está dormindo
{
putchxy(inimigo->x, inimigo->y, CHAR_ESPACO); //Apaga a posição atual
if(!inimigo->passos_restantes) //Se o inimigo não tem mais passos para andar, gera uma nova direção
{
if(inimigo->direcao != PARADO) // Se não estava parado, "lembra" da ultima direção andada
inimigo->u_direcao = inimigo->direcao;
inimigo->direcao = rand() % 5; // Escolhe uma das 5 possiveis direções
inimigo->passos_restantes = 2 + (rand() % 3); // Anda entre 2 e 4 passos
}
switch(inimigo->direcao) // Verifica para qual lado inimigo precisa se movimentar
{
case PARADO: // Caso esteja parado, vai printar pra ultima direção que estava virado
switch(inimigo->u_direcao)
{
case CIMA:
putchxy(inimigo->x, inimigo->y, CHAR_INIMIGO_C); //Printa o heroi na sua nova posição
break;
case BAIXO:
putchxy(inimigo->x, inimigo->y, CHAR_INIMIGO_B); //Printa o heroi na sua nova posição
break;
case ESQUERDA:
putchxy(inimigo->x, inimigo->y, CHAR_INIMIGO_E); //Printa o heroi na sua nova posição
break;
case DIREITA:
putchxy(inimigo->x, inimigo->y, CHAR_INIMIGO_D); //Printa o heroi na sua nova posição
break;
}
break;
case CIMA:
if (mapa[inimigo->y-1][inimigo->x] != '#' && mapa[inimigo->y-1][inimigo->x] != '0'&& mapa[inimigo->y-1][inimigo->x] != 'K') //Checa colisão
inimigo->y--;
else
inimigo->passos_restantes = 1; //Seto para 1, pois irei reduzir ao final do loop em 1, fazendo com que nao avance novamente
putchxy(inimigo->x, inimigo->y, CHAR_INIMIGO_C); //Printa o heroi na sua nova posição
break;
case BAIXO:
if (mapa[inimigo->y+1][inimigo->x] != '#' && mapa[inimigo->y+1][inimigo->x] != '0'&& mapa[inimigo->y+1][inimigo->x] != 'K')
inimigo->y++;
else
inimigo->passos_restantes = 1;
putchxy(inimigo->x, inimigo->y, CHAR_INIMIGO_B);
break;
case ESQUERDA:
if (mapa[inimigo->y][inimigo->x-1] != '#' && mapa[inimigo->y][inimigo->x-1] != '0'&& mapa[inimigo->y][inimigo->x-1] != 'K')
inimigo->x--;
else
inimigo->passos_restantes = 1;
putchxy(inimigo->x, inimigo->y, CHAR_INIMIGO_E);
break;
case DIREITA:
if (mapa[inimigo->y][inimigo->x+1] != '#' && mapa[inimigo->y][inimigo->x+1] != '0'&& mapa[inimigo->y][inimigo->x+1] != 'K')
inimigo->x++;
else
inimigo->passos_restantes = 1;
putchxy(inimigo->x, inimigo->y, CHAR_INIMIGO_D);
break;
}
visaoInimigo(MOSTRA, inimigo->x, inimigo->y, inimigo->direcao == PARADO ? inimigo->u_direcao : inimigo->direcao, mapa); //Reconstroi a visao do inimigo
inimigo->passos_restantes--;
}
else // Se inimigo estiver dormindo
{
putchxy(inimigo->x, inimigo->y, 'Z'); //Printa o caracter de sono
inimigo->t_sono-=4;
}
inimigo->ciclos = CICLOS_INIMIGO;
return;
}
int visaoInimigo(int status, int x, int y, int direcao, char mapa[HEIGHT][WIDTH])
{
int avistado = 0; //Flag que retorna se houve colisão do campo de visão com o herói
int i, j, offseti, offsetj; //Contadores
int visionCollision[3] = {0}; //Flag para poder fazer campo de visão não atravessar a parede
switch(direcao)
{
case CIMA:
for(i=-1; i<=1; i++)
{
for(j=0; j<=3; j++)
{
offseti = x-i;
offsetj = y-j;
if (offseti >= 0 && offsetj >= 0) //Garante que esteja dentro dos limites da matriz
{
if( (i || j) && !visionCollision[i+1])
{
if (mapa[offsetj][offseti] != '#')
{
if(mapa[offsetj][offseti] != 'K' && mapa[offsetj][offseti] != '0')
{
putchxy(offseti, offsetj, (status == MOSTRA ? CHAR_VISAO : CHAR_ESPACO)); //Operador ternario decide se apaga ou mostra o campo de visão
}
}
else
{
visionCollision[i+1] = 1;
}
}
}
}
}
break;
case BAIXO:
for(i=-1; i<=1; i++)
{
for(j=0; j<=3; j++)
{
offseti = x+i;
offsetj = y+j;
if (offseti < WIDTH && offsetj < HEIGHT) //Garante que esteja dentro dos limites da matriz
{
if( (i || j) && !visionCollision[i+1])
{
if (mapa[offsetj][offseti] != '#')
{
if(mapa[offsetj][offseti] != 'K' && mapa[offsetj][offseti] != '0')
putchxy(offseti, offsetj, (status == MOSTRA ? CHAR_VISAO : CHAR_ESPACO)); //Operador ternario decide se apaga ou mostra o campo de visão
}
else
{
visionCollision[i+1] = 1;
}
}
}
}
}
break;
case ESQUERDA:
for(i=0; i<=3; i++)
{
for(j=-1; j<=1; j++)
{
offseti = x-i;
offsetj = y-j;
if (offseti >= 0 && offsetj >= 0) //Garante que esteja dentro dos limites da matriz
{
if( (i || j) && !visionCollision[j+1])
{
if (mapa[offsetj][offseti] != '#')
{
if(mapa[offsetj][offseti] != 'K' && mapa[offsetj][offseti] != '0')
putchxy(offseti, offsetj, (status == MOSTRA ? CHAR_VISAO : CHAR_ESPACO)); //Operador ternario decide se apaga ou mostra o campo de visão
}
else
{
visionCollision[j+1] = 1;
}
}
}
}
}
break;
case DIREITA:
for(i=0; i<=3; i++)
{
for(j=-1; j<=1; j++)
{
offseti = x+i;
offsetj = y+j;
if (offseti < WIDTH && offsetj < HEIGHT) //Garante que esteja dentro dos limites da matriz
{
if( (i || j) && !visionCollision[j+1])
{
if (mapa[offsetj][offseti] != '#')
{
if(mapa[offsetj][offseti] != 'K' && mapa[offsetj][offseti] != '0')
putchxy(offseti, offsetj, (status == MOSTRA ? CHAR_VISAO : CHAR_ESPACO)); //Operador ternario decide se apaga ou mostra o campo de visão
}
else
{
visionCollision[j+1] = 1;
}
}
}
}
}
break;
}
return avistado;
}