-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathtank_survivor~
More file actions
663 lines (565 loc) · 25.1 KB
/
tank_survivor~
File metadata and controls
663 lines (565 loc) · 25.1 KB
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
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
#lang racket
(require 2htdp/universe 2htdp/image lang/posn 2htdp/batch-io)
;=============
;Estructuras
;=============
;MUNDO
(define-struct world (jugador1 jugador2 balas paredes enemigos puntaje) #:transparent)
;TANQUE
; (estado) = enemigo o amigo
(define-struct tanque (estado imagen posn direccion velocidad vida) #:transparent)
;IMAGEN_DIRECCION_TANQUE
(define-struct img_tanque (arriba abajo izquierda derecha))
;BALA
;(estado) delimita si lo dispara un enemigo o un aliado
(define-struct bala (posn direccion estado) #:transparent)
; PARED
(define-struct pared (posn))
;PUNTAJE
(define-struct puntaje (nombreJug1 nombreJug2 valor))
;PODER
; (denotador) en que puntaje se activa
; (habilidad) texto que se muestra cuando el poder esta activo
(define-struct poder (denotador habilidad jugador))
;=============
;Graficos
;=============
; Dimensiones de la ventana
(define ANCHO_JUEGO 650)
(define ALTO_JUEGO 650)
(define ANCHO_TOTAL 850)
; fondo del juego
(define FONDO_JUEGO (bitmap "imagenes/bg.png"))
;jugador1
(define ARRIBA_JUGADOR1 (bitmap "imagenes/arriba_jugador1.png"))
(define ABAJO_JUGADOR1 (bitmap "imagenes/abajo_jugador1.png"))
(define IZQUIERDA_JUGADOR1 (bitmap "imagenes/izq_jugador1.png"))
(define DERECHA_JUGADOR1 (bitmap "imagenes/der_jugador1.png"))
;jugador2
(define ARRIBA_JUGADOR2 (bitmap "imagenes/arriba_jugador2.png"))
(define ABAJO_JUGADOR2 (bitmap "imagenes/abajo_jugador2.png"))
(define IZQUIERDA_JUGADOR2 (bitmap "imagenes/izq_jugador2.png"))
(define DERECHA_JUGADOR2 (bitmap "imagenes/der_jugador2.png"))
;Imagen para cuando un tanque se queda sin vidas
(define TANQUE_MUERTO (bitmap "imagenes/jugador_muerto.png"))
;Enemigos
(define ARRIBA_ENEMIGO (bitmap "imagenes/arriba_enemigo.png"))
(define ABAJO_ENEMIGO (bitmap "imagenes/abajo_enemigo.png"))
(define IZQUIERDA_ENEMIGO (bitmap "imagenes/izq_enemigo.png"))
(define DERECHA_ENEMIGO (bitmap "imagenes/der_enemigo.png"))
; grafica de cada bala
(define BALA_JUG (bitmap "imagenes/bala_jugador.png"))
(define BALA_ENE (bitmap "imagenes/bala_enemigo.png"))
; grafica de cada pared
(define PAREDES_IMAGES (list (bitmap "imagenes/pared1.png")
(bitmap "imagenes/pared2.png")
(bitmap "imagenes/pared3.png")))
;Archivo de records
(define ARCH_RECORDS "records.csv")
;=============
;Constantes
;=============
;Valor tick
(define VALOR_TICK 1/20)
;velocidades
(define VELOCIDAD_JUG1 25)
(define VELOCIDAD_JUG2 25)
(define VELOCIDAD_ENEMIGOS 5)
(define VELOCIDAD_BALA 10)
;rango de disparo del enemigo
(define RANGO_ENEMIGO 20)
;estados
(define EST_JUGADOR 0)
(define EST_ENEMIGO 1)
;vidas
(define VIDAS_JUGADOR 3)
(define VIDAS_ENEMIGO 1)
; Spawns de los enemigos
(define SPAWNS_ENEMIGOS (list (make-posn 25 25)
(make-posn 625 25)
(make-posn 325 25)))
;Instancia del JUGADOR1
(define IMGES_JUGADOR1 (make-img_tanque ARRIBA_JUGADOR1 ABAJO_JUGADOR1 IZQUIERDA_JUGADOR1 DERECHA_JUGADOR1))
(define JUGADOR1 (make-tanque EST_JUGADOR IMGES_JUGADOR1 (make-posn 625 625) "up" VELOCIDAD_JUG1 VIDAS_JUGADOR))
;Instancia del JUGADOR2
(define IMGES_JUGADOR2 (make-img_tanque ARRIBA_JUGADOR2 ABAJO_JUGADOR2 IZQUIERDA_JUGADOR2 DERECHA_JUGADOR2))
(define JUGADOR2 (make-tanque EST_JUGADOR IMGES_JUGADOR2 (make-posn 25 625) "right" VELOCIDAD_JUG2 VIDAS_JUGADOR))
;Instancia de los ENEMIGOS
(define IMGES_ENEMIGO (make-img_tanque ARRIBA_ENEMIGO ABAJO_ENEMIGO IZQUIERDA_ENEMIGO DERECHA_ENEMIGO))
(define ENEMIGOS
(list
(make-tanque EST_ENEMIGO IMGES_ENEMIGO (make-posn 25 25) "down" VELOCIDAD_ENEMIGOS VIDAS_ENEMIGO)
(make-tanque EST_ENEMIGO IMGES_ENEMIGO (make-posn 625 25) "down" VELOCIDAD_ENEMIGOS VIDAS_ENEMIGO)
(make-tanque EST_ENEMIGO IMGES_ENEMIGO (make-posn 325 25) "down" VELOCIDAD_ENEMIGOS VIDAS_ENEMIGO)))
;balas
(define BALAS empty)
; paredes
(define PAREDES
(list
(make-pared (make-posn 75 75))
(make-pared (make-posn 75 125))
(make-pared (make-posn 75 175))
(make-pared (make-posn 75 225))
(make-pared (make-posn 175 75))
(make-pared (make-posn 175 125))
(make-pared (make-posn 175 175))
(make-pared (make-posn 175 225))
(make-pared (make-posn 275 75))
(make-pared (make-posn 275 125))
(make-pared (make-posn 275 175))
(make-pared (make-posn 375 75))
(make-pared (make-posn 375 125))
(make-pared (make-posn 375 175))
(make-pared (make-posn 475 75))
(make-pared (make-posn 475 125))
(make-pared (make-posn 475 175))
(make-pared (make-posn 475 225))
(make-pared (make-posn 575 75))
(make-pared (make-posn 575 125))
(make-pared (make-posn 575 175))
(make-pared (make-posn 575 225))
(make-pared (make-posn 275 275))
(make-pared (make-posn 375 275))
(make-pared (make-posn 275 375))
(make-pared (make-posn 275 425))
(make-pared (make-posn 275 475))
(make-pared (make-posn 375 375))
(make-pared (make-posn 375 425))
(make-pared (make-posn 375 475))
(make-pared (make-posn 325 395))
(make-pared (make-posn 175 325))
(make-pared (make-posn 125 325))
(make-pared (make-posn 175 425))
(make-pared (make-posn 175 475))
(make-pared (make-posn 175 525))
(make-pared (make-posn 175 575))
(make-pared (make-posn 75 425))
(make-pared (make-posn 75 475))
(make-pared (make-posn 75 525))
(make-pared (make-posn 75 575))
(make-pared (make-posn 575 425))
(make-pared (make-posn 575 475))
(make-pared (make-posn 575 525))
(make-pared (make-posn 575 575))
(make-pared (make-posn 475 425))
(make-pared (make-posn 475 475))
(make-pared (make-posn 475 525))
(make-pared (make-posn 475 575))
(make-pared (make-posn 475 325))
(make-pared (make-posn 525 325))))
;enlistar records dividiendolo por el espacio
(define recordsList (string-split (read-file ARCH_RECORDS) "\n"))
;Funcion para crear una instancia de la estructura a partir del primer elemento del archivo
(define (crearPuntaje l) (make-puntaje (first l) (first (rest l)) (first (rest (rest l)))))
; Creamos una lista de instancias de puntaje
(define (puntaje-by-line lines)
(if (empty? lines)
empty
(cons (crearPuntaje (string-split (first lines) ","))
(puntaje-by-line (rest lines)))))
(define (PintarRecords lista)
(cond
[(empty? lista) empty]
[else (cons (text (string-append (puntaje-nombreJug1 (first lista)) "-"
(puntaje-nombreJug2 (first lista)) "->"
(puntaje-valor (first lista))) 18 "white")
(PintarRecords (rest lista)))]))
;interfaz de la derecha para las estadisticas devuelve una lista de imagenes
(define (panelEstadisImages mundo)
(define vidasJugador1 (tanque-vida (world-jugador1 mundo)))
(define vidasJugador2 (tanque-vida (world-jugador2 mundo)))
(define puntuacion (world-puntaje mundo))
(append (list (text (string-append "Jugador1: " (number->string vidasJugador1)) 20 "red"))
(list (text (string-append "Jugador2: " (number->string vidasJugador2)) 20 "green"))
(list (text (string-append "Puntaje: " (number->string puntuacion)) 20 "blue"))
(list (text "RECORDS: " 20 "blue"))
(PintarRecords (puntaje-by-line recordsList))))
; Interfaz de la derecha devuelve una lista de posiciones
(define (panelEstadisPosn mundo)
(append (list (make-posn 750 75))
(list (make-posn 750 150))
(list (make-posn 750 225))
(list (make-posn 750 300))
(list (make-posn 750 350))
(list (make-posn 750 400))
(list (make-posn 750 450))))
;Función que pinta todo
(define (pintarMundo mundo)
(define panelImages (panelEstadisImages mundo))
(define panelPosn (panelEstadisPosn mundo))
(define elementos (append (list (world-jugador1 mundo))
(list (world-jugador2 mundo))
(world-balas mundo)
(world-paredes mundo)
(world-enemigos mundo)))
(define imagenes (append (getImagenes elementos) panelImages))
(define posiciones (append (getPosn elementos) panelPosn))
(place-images imagenes posiciones FONDO_JUEGO))
; enlistar images del world
(define (getImagenes elementos)
(cond
[(empty? elementos) empty]
[else (append (list (elm-get-imagen (first elementos))) (getImagenes (rest elementos)))]))
; enlistar posiciones del world
(define (getPosn elementos)
(cond
[(empty? elementos) empty]
[else (append (list (elm-get-posn (first elementos))) (getPosn (rest elementos)))]))
; ========
; LOGICA
; ========
; GET RANDOM ELEMENT FROM LIST
(define (random-element list)
(list-ref list (random (length list))))
; pintar paredes random
(define getParedesImage (random-element PAREDES_IMAGES))
; get Imagen por objeto
(define (elm-get-imagen elem)
(cond
[(tanque? elem) (getImageTanque elem)]
[(bala? elem) (getImageBala elem)]
[(pared? elem) getParedesImage]))
; get Posn por objeto
(define (elm-get-posn elem)
(cond
[(tanque? elem) (tanque-posn elem)]
[(bala? elem) (bala-posn elem)]
[(pared? elem) (pared-posn elem)]))
; get Estado por objeto
(define (elm-get-estado elem)
(cond
[(tanque? elem) (tanque-estado elem)]
[(bala? elem) (bala-estado elem)]))
; get direccion por objeto
(define (elm-get-direccion elem)
(cond
[(tanque? elem) (cond
[(string=? (tanque-direccion elem) "w") "up"]
[(string=? (tanque-direccion elem) "s") "down"]
[(string=? (tanque-direccion elem) "a") "left"]
[(string=? (tanque-direccion elem) "d") "right"]
[else (tanque-direccion elem)]) ]
[(bala? elem) (bala-direccion elem)]))
; get tamaño por objeto
(define (elm-getImg-w elem)
(cond
[(tanque? elem) (/ (image-width ARRIBA_JUGADOR1) 2)]
[(bala? elem) (/ (image-width BALA_JUG) 2)]
[(pared? elem) (/ (image-width getParedesImage) 2)]))
; acomodar que imagen va dependiendo de la direccion
(define (getImageTanque tanque)
(if (equal? (tanque-vida tanque) 0)
TANQUE_MUERTO
(cond
[(equal? (elm-get-direccion tanque) "up") (img_tanque-arriba (tanque-imagen tanque))]
[(equal? (elm-get-direccion tanque) "left") (img_tanque-izquierda (tanque-imagen tanque))]
[(equal? (elm-get-direccion tanque) "right") (img_tanque-derecha (tanque-imagen tanque))]
[(equal? (elm-get-direccion tanque) "down") (img_tanque-abajo (tanque-imagen tanque))])))
; acomodar que imagen va dependiendo del estado de la bala
(define (getImageBala bala)
(cond
[(equal? (elm-get-estado bala) 0) BALA_JUG]
[(equal? (elm-get-estado bala) 1) BALA_ENE]))
; Contrato:
; distancia: punto punto -> number
; Proposito:
; Es una función auxiliar que se utiliza para calcular la distancia entre
; dos puntos del plano cartesiano.
(define (distancia p1 p2) (sqrt (+ (sqr (- (posn-x p1) (posn-x p2)))
(sqr (- (posn-y p1) (posn-y p2))))))
;Colision con algun elemento
(define (colisiona? obj1 obj2)
(cond
[(< (distancia (elm-get-posn obj1) (elm-get-posn obj2))
(+ (elm-getImg-w obj1) (elm-getImg-w obj2))) #true]
[else #false]))
;Colisiona con pared o enemigo en su siguiente mov
(define (colisionanTanquesObjeto? tanque1 tanque2 objeto)
(cond
[(empty? objeto) #false]
[(or (colisiona? tanque1 (first objeto)) (colisiona? tanque2 (first objeto))) #true]
[else (colisionanTanquesObjeto? tanque1 tanque2 (rest objeto))]))
; devuelve eltanque si en su siguente movimiento se sale
(define (cambiarPosnJugador tanque tecla identificador)
(define estado (tanque-estado tanque))
(define imagen (tanque-imagen tanque))
(define direccion (tanque-direccion tanque))
(define posn (tanque-posn tanque))
(define x (posn-x (tanque-posn tanque)))
(define y (posn-y (tanque-posn tanque)))
(define velocidad (tanque-velocidad tanque))
(define vida (tanque-vida tanque))
(cond
[(= identificador 1)
(cond
[(string=? tecla "up")
(cond
[(string=? tecla direccion) (make-tanque estado imagen (make-posn x (- y velocidad)) "up" velocidad vida)]
[else (make-tanque estado imagen posn "up" velocidad vida)])]
[(string=? tecla "down")
(cond
[(string=? tecla direccion) (make-tanque estado imagen (make-posn x (+ y velocidad)) "down" velocidad vida)]
[else (make-tanque estado imagen posn "down" velocidad vida)])]
[(string=? tecla "left")
(cond
[(string=? tecla direccion) (make-tanque estado imagen (make-posn (- x velocidad) y) "left" velocidad vida)]
[else (make-tanque estado imagen posn "left" velocidad vida)])]
[(string=? tecla "right")
(cond
[(string=? tecla direccion) (make-tanque estado imagen (make-posn (+ x velocidad) y) "right" velocidad vida)]
[else (make-tanque estado imagen posn "right" velocidad vida)])]
[else tanque])]
[(= identificador 2)
(cond
[(string=? tecla "w")
(cond
[(string=? tecla direccion) (make-tanque estado imagen (make-posn x (- y velocidad)) "w" velocidad vida)]
[else (make-tanque estado imagen posn "w" velocidad vida)])]
[(string=? tecla "s")
(cond
[(string=? tecla direccion) (make-tanque estado imagen (make-posn x (+ y velocidad)) "s" velocidad vida)]
[else (make-tanque estado imagen posn "s" velocidad vida)])]
[(string=? tecla "a")
(cond
[(string=? tecla direccion) (make-tanque estado imagen (make-posn (- x velocidad) y) "a" velocidad vida)]
[else (make-tanque estado imagen posn "a" velocidad vida)])]
[(string=? tecla "d")
(cond
[(string=? tecla direccion) (make-tanque estado imagen (make-posn (+ x velocidad) y) "d" velocidad vida)]
[else (make-tanque estado imagen posn "d" velocidad vida)])]
[else tanque])]))
; MOVER TANQUES ALIADOS
(define (moverTanquesAliados mundo tecla)
(define jugador1 (world-jugador1 mundo))
(define jugador1_nuevo (cambiarPosnJugador jugador1 tecla 1))
(define jugador2 (world-jugador2 mundo))
(define jugador2_nuevo (cambiarPosnJugador jugador2 tecla 2))
(define balas (world-balas mundo))
(define paredes (world-paredes mundo))
(define enemigos (world-enemigos mundo))
(define puntaje (world-puntaje mundo))
(cond
[(or (colisionanObjetoLimite? jugador1_nuevo)
(colisionanObjetoLimite? jugador2_nuevo)
(colisionanTanquesObjeto? jugador1_nuevo jugador2_nuevo paredes)
(colisionanTanquesObjeto? jugador1_nuevo jugador2_nuevo enemigos)
(colisiona? jugador1_nuevo jugador2_nuevo))
(make-world jugador1 jugador2 balas paredes enemigos puntaje)]
[else
(cond
[(equal? (tanque-vida jugador1) 0)
(make-world jugador1 jugador2_nuevo balas paredes enemigos puntaje)]
[(equal? (tanque-vida jugador2) 0)
(make-world jugador1_nuevo jugador2 balas paredes enemigos puntaje)]
[else (make-world jugador1_nuevo jugador2_nuevo balas paredes enemigos puntaje)])
]))
; Mover la lista completa de objetos (enemigos o balas)
(define (mover_list_objetos objetos fun_mov)
(cond
[(empty? objetos) empty]
[else (cons (fun_mov (first objetos)) (mover_list_objetos (rest objetos) fun_mov))]))
;Eliminar enemigo de la lista al colisionar
(define (eliminarEnemigo enemigos balas)
(cond
[(empty? enemigos) empty]
[(colisionanEnemigoOBalaObjeto? (first enemigos) balas)
(append (list (make-tanque (tanque-estado (first enemigos))
(tanque-imagen (first enemigos))
(random-element SPAWNS_ENEMIGOS)
(tanque-direccion (first enemigos))
(tanque-velocidad (first enemigos))
(tanque-vida (first enemigos))))
(eliminarEnemigo (rest enemigos) balas))]
[else (append (list (first enemigos)) (eliminarEnemigo (rest enemigos) balas))]))
;Colisiona un objeto (enemigo o bala) con un objeto en su siguiente mov
(define (colisionanEnemigoOBalaObjeto? enem_bala objeto)
(define est-enem_bala (elm-get-estado enem_bala))
(cond
[(empty? objeto) #false]
[(colisiona? enem_bala (first objeto))
(cond
[(tanque? (first objeto))
(cond
[(equal? est-enem_bala (tanque-estado (first objeto))) #false]
[(not (equal? est-enem_bala (tanque-estado (first objeto)))) #true])]
[(bala? (first objeto))
(cond
[(equal? est-enem_bala (bala-estado (first objeto))) #false]
[(not (equal? est-enem_bala (bala-estado (first objeto)))) #true])]
[(pared? (first objeto)) #true])]
[else (colisionanEnemigoOBalaObjeto? enem_bala (rest objeto))]))
;Cambiar posn del enemigo
(define (cambiarPosnEnemigo enemigo)
(define direccion (tanque-direccion enemigo))
(define posn (tanque-posn enemigo))
(define x (posn-x (tanque-posn enemigo)))
(define y (posn-y (tanque-posn enemigo)))
(define estado (tanque-estado enemigo))
(define velocidad (tanque-velocidad enemigo))
(define imagen (tanque-imagen enemigo))
(define ancho-imagen (elm-getImg-w enemigo))
(define vida (tanque-vida enemigo))
(cond
[(string=? direccion "up")
(make-tanque estado imagen (make-posn x (- y velocidad)) direccion velocidad vida)]
[(string=? direccion "down")
(make-tanque estado imagen (make-posn x (+ y velocidad)) direccion velocidad vida)]
[(string=? direccion "left")
(make-tanque estado imagen (make-posn (- x velocidad) y) direccion velocidad vida)]
[(string=? direccion "right")
(make-tanque estado imagen (make-posn (+ x velocidad) y) direccion velocidad vida)]))
; Cambiar direccion enemigo a random
(define (cambiarDireccionEnemigo enemigo)
(define randomdireccion (random-element (list "up" "down" "left" "right")))
(define posn (tanque-posn enemigo))
(define estado (tanque-estado enemigo))
(define velocidad (tanque-velocidad enemigo))
(define imagen (tanque-imagen enemigo))
(define vida (tanque-vida enemigo))
(make-tanque estado imagen posn randomdireccion velocidad vida))
; Funcion que mueve enemigo dependiendo de la direccion
(define (enemigo_movimiento enemigo)
(define sgte_mov_enemigo (cambiarPosnEnemigo enemigo))
(if (or (colisionanObjetoLimite? sgte_mov_enemigo))
(cambiarDireccionEnemigo enemigo)
sgte_mov_enemigo))
;Cambiar direccion del enemigo si colisiona con algo
(define (movimientoEnemigoFinal enemigos jugador1 jugador2 paredes)
(cond
[(empty? enemigos) empty]
[(or (colisionanEnemigoOBalaObjeto? (cambiarPosnEnemigo (first enemigos)) (list jugador1))
(colisionanEnemigoOBalaObjeto? (cambiarPosnEnemigo (first enemigos)) (list jugador2))
(colisionanEnemigoOBalaObjeto? (cambiarPosnEnemigo (first enemigos)) paredes))
(cons (cambiarDireccionEnemigo (first enemigos)) (movimientoEnemigoFinal (rest enemigos) jugador1 jugador2 paredes))]
[else (append (list (first enemigos)) (movimientoEnemigoFinal (rest enemigos) jugador1 jugador2 paredes))]))
;Colisiona un objeto (enemigo o bala) con un limite
(define (colisionanObjetoLimite? objeto)
(define direccion (elm-get-direccion objeto))
(define x (posn-x (elm-get-posn objeto)))
(define y (posn-y (elm-get-posn objeto)))
(define ancho-imagen (elm-getImg-w objeto))
(cond
[(string=? direccion "up") (if (< y (+ 0 ancho-imagen)) #true #false)]
[(string=? direccion "down") (if (> y (- ALTO_JUEGO ancho-imagen)) #true #false)]
[(string=? direccion "left") (if (< x (+ 0 ancho-imagen)) #true #false)]
[(string=? direccion "right") (if (> x (- ANCHO_JUEGO ancho-imagen)) #true #false)]))
;Eliminar Bala de la lista al colisionar
(define (eliminarBala balas jugador1 jugador2 paredes enemigos)
(cond
[(empty? balas) empty]
[(or (colisionanObjetoLimite? (first balas))
(colisionanEnemigoOBalaObjeto? (first balas) (list jugador1))
(colisionanEnemigoOBalaObjeto? (first balas) (list jugador2))
(colisionanEnemigoOBalaObjeto? (first balas) paredes)
(colisionanEnemigoOBalaObjeto? (first balas) enemigos))
(eliminarBala (rest balas) jugador1 jugador2 paredes enemigos)]
[else (append (list (first balas)) (eliminarBala (rest balas) jugador1 jugador2 paredes enemigos))]))
;Agregar bala a la lista
(define (agregarBala tanque balas)
(define posn (tanque-posn tanque))
(define direccion (elm-get-direccion tanque))
(define estadoTanque (tanque-estado tanque))
(cons (make-bala posn direccion estadoTanque) balas))
; Funcion que mueve bala dependiendo de la direccion
(define (bala_movimiento bala)
(define direccion (bala-direccion bala))
(define x (posn-x (bala-posn bala)))
(define y (posn-y (bala-posn bala)))
(define estado (bala-estado bala))
(define ancho-imagen (elm-getImg-w bala))
(cond
[(string=? direccion "up") (make-bala (make-posn x (- y VELOCIDAD_BALA)) direccion estado)]
[(string=? direccion "down") (make-bala (make-posn x (+ y VELOCIDAD_BALA)) direccion estado)]
[(string=? direccion "left") (make-bala (make-posn (- x VELOCIDAD_BALA) y) direccion estado)]
[(string=? direccion "right") (make-bala (make-posn (+ x VELOCIDAD_BALA) y) direccion estado)]))
;Enemigos disparan balas
(define (dispararBalaEnemigo balas enemigos)
(cond
[(empty? enemigos) balas]
[(= 1 (random RANGO_ENEMIGO))
(dispararBalaEnemigo (agregarBala (first enemigos) balas) (rest enemigos))]
[else (dispararBalaEnemigo balas (rest enemigos))]))
; Jugador1 dispara bala
(define (dispararBalaJugador1 mundo)
(define jugador1 (world-jugador1 mundo))
(define jugador2 (world-jugador2 mundo))
(define balas_agregadas (agregarBala jugador1 (world-balas mundo)))
(define paredes (world-paredes mundo))
(define enemigos (world-enemigos mundo))
(define puntaje (world-puntaje mundo))
(make-world jugador1 jugador2 balas_agregadas paredes enemigos puntaje))
; Jugador2 dispara bala
(define (dispararBalaJugador2 mundo)
(define jugador1 (world-jugador1 mundo))
(define jugador2 (world-jugador2 mundo))
(define balas_agregadas (agregarBala jugador2 (world-balas mundo)))
(define paredes (world-paredes mundo))
(define enemigos (world-enemigos mundo))
(define puntaje (world-puntaje mundo))
(make-world jugador1 jugador2 balas_agregadas paredes enemigos puntaje))
;Restar vida jugador
(define (restarVidaJugador jugador balas)
(define estado (tanque-estado jugador))
(define imagen (tanque-imagen jugador))
(define direccion (tanque-direccion jugador))
(define posn (tanque-posn jugador))
(define velocidad (tanque-velocidad jugador))
(define vida (tanque-vida jugador))
(cond
[(and (> vida 0) (colisionanEnemigoOBalaObjeto? jugador balas))
(make-tanque estado imagen posn direccion velocidad (- vida 1))]
[else jugador]))
;Aumentar Puntaje
(define (aumentarPuntaje puntaje_ant balas enemigos)
(cond
[(or (empty? balas) (empty? enemigos)) puntaje_ant]
[(or (colisionanEnemigoOBalaObjeto? (first enemigos) balas)
(colisionanEnemigoOBalaObjeto? (first balas) enemigos)) (+ 100 puntaje_ant)]
[else puntaje_ant]))
;Cambiar mundo por KEY
(define (actMundoTeclado mundo tecla)
(cond
[(string=? tecla " ") (dispararBalaJugador2 mundo)]
[(string=? tecla "p") (dispararBalaJugador1 mundo)]
[else (moverTanquesAliados mundo tecla)]))
; Cambiar mundo por TICK
(define (actMundoTick mundo)
(define jugador1 (world-jugador1 mundo))
(define jugador2 (world-jugador2 mundo))
(define balas (world-balas mundo))
(define paredes (world-paredes mundo))
(define enemigos (world-enemigos mundo))
(define puntaje (world-puntaje mundo))
(define balas_acts (mover_list_objetos balas bala_movimiento))
(define balas_remov (eliminarBala balas_acts jugador1 jugador2 paredes enemigos))
(define enem_acts (mover_list_objetos enemigos enemigo_movimiento))
(define enems_remov (eliminarEnemigo enem_acts balas_acts))
(define enems_final (movimientoEnemigoFinal enems_remov jugador1 jugador2 paredes))
(define balas_nuevas (dispararBalaEnemigo balas_remov enems_final))
(define aum_puntaje (aumentarPuntaje puntaje balas_acts enems_final))
(define jugador1_sin_vidas (restarVidaJugador jugador1 balas_acts))
(define jugador2_sin_vidas (restarVidaJugador jugador2 balas_acts))
(make-world jugador1_sin_vidas jugador2_sin_vidas balas_nuevas paredes enems_final aum_puntaje))
;TERMINAR JUEGO
(define (finJuego? mundo)
(define vidas_jug1 (tanque-vida (world-jugador1 mundo)))
(define vidas_jug2 (tanque-vida (world-jugador2 mundo)))
(cond
[(and (= vidas_jug1 0) (= vidas_jug2 0)) #true]
[else #false]))
(define (gameover-scene mundo)
(overlay/align "middle" "middle"
(above (text "GAME OVER." 20 "red")
(text "¡Gracias por jugar!" 20 "red")
(text "Puntaje Final:" 20 "yellow")
(text (number->string (world-puntaje mundo)) 20 "yellow"))
(empty-scene ANCHO_TOTAL ALTO_JUEGO "black")))
;================
; SE PRENDE ESTO
;================
(big-bang (make-world JUGADOR1 JUGADOR2 BALAS PAREDES ENEMIGOS 0)
(to-draw pintarMundo)
(on-key actMundoTeclado)
(on-tick actMundoTick VALOR_TICK)
(stop-when finJuego? gameover-scene)
(name "Tank Survivor v1.2"))