Package pilas :: Module habilidades
[hide private]
[frames] | no frames]

Source Code for Module pilas.habilidades

  1  # -*- encoding: utf-8 -*- 
  2  # Pilas engine - A video game framework. 
  3  # 
  4  # Copyright 2010 - Hugo Ruscitti 
  5  # License: LGPLv3 (see http://www.gnu.org/licenses/lgpl.html) 
  6  # 
  7  # Website - http://www.pilas-engine.com.ar 
  8   
  9  import random 
 10  import pilas 
 11  import math 
 12   
13 -class Habilidad(object):
14 """Representa una habilidad que un actor puede aprender.""" 15
16 - def __init__(self, receptor):
17 self.receptor = receptor
18
19 - def actualizar(self):
20 pass
21
22 - def eliminar(self):
23 pass
24 25
26 -class RebotarComoPelota(Habilidad):
27 """Le indica al actor que rebote y colisiones como una pelota. 28 29 >>> un_actor = pilas.actores.Aceituna() 30 >>> un_actor.aprender(pilas.habilidades.RebotarComoPelota) 31 """ 32
33 - def __init__(self, receptor):
34 Habilidad.__init__(self, receptor) 35 error = random.randint(-10, 10) / 10.0 36 37 circulo = pilas.fisica.Circulo(receptor.x + error, 38 receptor.y + error, 39 receptor.radio_de_colision) 40 receptor.aprender(pilas.habilidades.Imitar, circulo) 41 self.circulo = circulo 42 receptor.impulsar = self.impulsar 43 receptor.empujar = self.empujar
44
45 - def eliminar(self):
46 self.circulo.eliminar()
47
48 - def impulsar(self, dx, dy):
49 self.circulo.impulsar(dx, dy)
50
51 - def empujar(self, dx, dy):
52 self.circulo.empujar(dx, dy)
53 54
55 -class RebotarComoCaja(Habilidad):
56 """Le indica al actor que rebote y colisiones como una caja cuadrada. 57 58 >>> un_actor = pilas.actores.Aceituna() 59 >>> un_actor.aprender(pilas.habilidades.RebotarComoPelota) 60 """ 61
62 - def __init__(self, receptor):
63 Habilidad.__init__(self, receptor) 64 error = random.randint(-10, 10) / 10.0 65 rectangulo = pilas.fisica.Rectangulo(receptor.x + error, 66 receptor.y + error, 67 receptor.radio_de_colision*2 - 4, 68 receptor.radio_de_colision*2 - 4, 69 ) 70 receptor.aprender(pilas.habilidades.Imitar, rectangulo) 71 self.rectangulo = rectangulo
72
73 - def eliminar(self):
74 self.rectangulo.eliminar()
75 76
77 -class ColisionableComoPelota(RebotarComoPelota):
78 """Le indica al actor que colisione como una pelota, pero que no rebote. 79 80 >>> un_actor = pilas.actores.Aceituna() 81 >>> un_actor.aprender(pilas.habilidades.ColisionableComoPelota) 82 """ 83
84 - def __init__(self, receptor):
85 RebotarComoPelota.__init__(self, receptor)
86
87 - def actualizar(self):
88 self.figura.body.position.x = self.receptor.x 89 self.figura.body.position.y = self.receptor.y
90
91 - def eliminar(self):
92 pilas.fisica.fisica.eliminar(self.figura)
93 94
95 -class SeguirAlMouse(Habilidad):
96 "Hace que un actor siga la posición del mouse en todo momento." 97
98 - def __init__(self, receptor):
101
102 - def mover(self, evento):
103 self.receptor.x = evento.x 104 self.receptor.y = evento.y
105 106
107 -class RotarConMouse(Habilidad):
108 """"Hace que un actor rote con respecto a la posicion del mouse. 109 110 Ejemplo: 111 112 >>> actor.aprender(pilas.habilidades.RotarConMouse, 113 lado_seguimiento=pilas.habilidades.RotarConMouse.ABAJO) 114 115 """ 116 ARRIBA = 270 117 ABAJO = 90 118 IZQUIERDA = 180 119 DERECHA = 0 120
121 - def __init__(self, receptor, lado_seguimiento=ARRIBA):
122 """Inicializa la Habilidad 123 124 :param receptor: La referencia al actor. 125 :param lado_seguimiento: Establece el lado del actor que rotará para estar encarado hacia el puntero del mouse. 126 """ 127 Habilidad.__init__(self, receptor) 128 pilas.escena_actual().mueve_mouse.conectar(self.se_movio_el_mouse) 129 pilas.escena_actual().actualizar.conectar(self.rotar) 130 self.lado_seguimiento = lado_seguimiento 131 132 self.raton_x = receptor.x 133 self.raton_y = receptor.y
134
135 - def se_movio_el_mouse(self, evento):
136 self.raton_x = evento.x 137 self.raton_y = evento.y
138
139 - def rotar(self, evento):
140 141 receptor = (self.receptor.x, self.receptor.y) 142 raton = (self.raton_x, self.raton_y) 143 144 angulo = pilas.utils.obtener_angulo_entre(receptor, raton) 145 146 self.receptor.rotacion = -(angulo) - self.lado_seguimiento
147 148
149 -class MirarAlActor(Habilidad):
150 """"Hace que un actor rote para mirar hacia otro actor. 151 """ 152 ARRIBA = 270 153 ABAJO = 90 154 IZQUIERDA = 180 155 DERECHA = 0 156
157 - def __init__(self, receptor, actor_a_seguir, lado_seguimiento=ARRIBA):
158 """Inicializa la habilidad. 159 160 :param receptor: Actor que aprenderá la habilidad. 161 :param actor_a_seguir : Actor al que se desea seguir con la mirada. 162 :param lado_seguimiento: Establece el lado del actor que rotará para estar encarado hacia el actor que desea vigilar. 163 """ 164 Habilidad.__init__(self, receptor) 165 pilas.escena_actual().actualizar.conectar(self.rotar) 166 self.lado_seguimiento = lado_seguimiento 167 168 self.actor_a_seguir = actor_a_seguir
169
170 - def rotar(self, evento):
171 receptor = (self.receptor.x, self.receptor.y) 172 actor_a_seguir = (self.actor_a_seguir.x, self.actor_a_seguir.y) 173 174 angulo = pilas.utils.obtener_angulo_entre(receptor, actor_a_seguir) 175 176 self.receptor.rotacion = -(angulo) - self.lado_seguimiento
177 178
179 -class AumentarConRueda(Habilidad):
180 "Permite cambiar el tamaño de un actor usando la ruedita scroll del mouse." 181
182 - def __init__(self, receptor):
185
186 - def cambiar_de_escala(self, evento):
187 self.receptor.escala += (evento.delta / 4.0)
188 189
190 -class SeguirClicks(Habilidad):
191 "Hace que el actor se coloque la posición del cursor cuando se hace click." 192
193 - def __init__(self, receptor):
196
197 - def moverse_a_este_punto(self, evento):
198 if (evento.boton == 1): 199 self.receptor.x = [evento.x], 0.5 200 self.receptor.y = [evento.y], 0.5
201 202
203 -class Arrastrable(Habilidad):
204 """Hace que un objeto se pueda arrastrar con el puntero del mouse. 205 206 Cuando comienza a mover al actor se llama al metodo ''comienza_a_arrastrar'' 207 y cuando termina llama a ''termina_de_arrastrar''. Estos nombres 208 de metodos se llaman para que puedas personalizar estos eventos, dado 209 que puedes usar polimorfismo para redefinir el comportamiento 210 de estos dos metodos. Observa un ejemplo de esto en 211 el ejemplo ``pilas.ejemplos.Piezas``. 212 213 """ 214
215 - def __init__(self, receptor):
218
219 - def cuando_intenta_arrastrar(self, evento):
220 "Intenta mover el objeto con el mouse cuando se pulsa sobre el." 221 if (evento.boton == 1): 222 if self.receptor.colisiona_con_un_punto(evento.x, evento.y): 223 pilas.escena_actual().termina_click.conectar(self.cuando_termina_de_arrastrar, id='cuando_termina_de_arrastrar') 224 pilas.escena_actual().mueve_mouse.conectar(self.cuando_arrastra, id='cuando_arrastra') 225 self.comienza_a_arrastrar()
226
227 - def cuando_arrastra(self, evento):
228 "Arrastra el actor a la posicion indicada por el puntero del mouse." 229 if self._el_receptor_tiene_fisica(): 230 pilas.escena_actual().fisica.cuando_mueve_el_mouse(evento.x, evento.y) 231 else: 232 self.receptor.x += evento.dx 233 self.receptor.y += evento.dy
234
235 - def cuando_termina_de_arrastrar(self, evento):
236 "Suelta al actor porque se ha soltado el botón del mouse." 237 pilas.escena_actual().mueve_mouse.desconectar_por_id(id='cuando_arrastra') 238 self.termina_de_arrastrar() 239 pilas.escena_actual().termina_click.desconectar_por_id(id='cuando_termina_de_arrastrar')
240
241 - def comienza_a_arrastrar(self):
244
245 - def termina_de_arrastrar(self):
248
250 return hasattr(self.receptor, 'figura')
251 252
253 -class MoverseConElTeclado(Habilidad):
254 """Hace que un actor cambie de posición con pulsar el teclado.""" 255 CUATRO_DIRECCIONES = 4 256 OCHO_DIRECCIONES = 8 257 258
259 - def __init__(self, receptor, control=None, direcciones=OCHO_DIRECCIONES, velocidad_maxima=4, 260 aceleracion=1, deceleracion=0.1, con_rotacion=False, velocidad_rotacion=1, marcha_atras=True):
261 """Inicializa la habilidad. 262 263 :param receptor: Referencia al actor que aprenderá la habilidad. 264 :param control: Control al que va a responder para mover el Actor. 265 :param direcciones: Establece si puede mover en cualquier direccion o unicamente en 4 direcciones arriba, abajo, izquierda y derecha. El parametro con_rotacion establece las direcciones a OCHO_DIRECCIONES siempre. 266 :param velocidad_maxima: Velocidad maxima en pixeles a la que se moverá el Actor. 267 :param aceleracion: Indica lo rapido que acelera el actor hasta su velocidad máxima. 268 :param deceleracion: Indica lo rapido que decelera el actor hasta parar. 269 :param con_rotacion: Si deseas que el actor rote pulsando las teclas de izquierda y derecha. 270 :param velocidad_rotacion: Indica lo rapido que rota un actor sobre si mismo. 271 :param marcha_atras: Posibilidad de ir hacia atrás. (True o False) 272 """ 273 274 Habilidad.__init__(self, receptor) 275 pilas.escena_actual().actualizar.conectar(self.on_key_press) 276 277 if control == None: 278 self.control = self.receptor.escena.control 279 else: 280 self.control = control 281 282 self.direcciones = direcciones 283 284 self.velocidad = 0 285 self.deceleracion = deceleracion 286 self._velocidad_maxima = velocidad_maxima 287 self._aceleracion = aceleracion 288 self.con_rotacion = con_rotacion 289 self.velocidad_rotacion = velocidad_rotacion 290 self.marcha_atras = marcha_atras
291
292 - def set_velocidad_maxima(self, velocidad):
293 self._velocidad_maxima = velocidad
294
295 - def get_velocidad_maxima(self):
296 return self._velocidad_maxima
297
298 - def get_aceleracion(self):
299 return self._aceleracion
300
301 - def set_aceleracion(self, aceleracion):
302 self._aceleracion = aceleracion
303 304 velocidad_maxima = property(get_velocidad_maxima, set_velocidad_maxima, doc="Define la velocidad maxima.") 305 aceleracion = property(get_aceleracion, set_aceleracion, doc="Define la acelaracion.") 306
307 - def on_key_press(self, evento):
308 309 c = self.control 310 311 if self.con_rotacion: 312 313 if c.izquierda: 314 self.receptor.rotacion -= self.velocidad_rotacion * self.velocidad_maxima 315 elif c.derecha: 316 self.receptor.rotacion += self.velocidad_rotacion * self.velocidad_maxima 317 318 if c.arriba: 319 self.avanzar(+1) 320 elif c.abajo: 321 if self.marcha_atras: 322 self.avanzar(-1) 323 else: 324 self.decelerar() 325 else: 326 self.decelerar() 327 328 rotacion_en_radianes = math.radians(-self.receptor.rotacion + 90) 329 dx = math.cos(rotacion_en_radianes) * self.velocidad 330 dy = math.sin(rotacion_en_radianes) * self.velocidad 331 self.receptor.x += dx 332 self.receptor.y += dy 333 334 else: 335 336 if self.direcciones == MoverseConElTeclado.OCHO_DIRECCIONES: 337 if c.izquierda: 338 self.receptor.x -= self.velocidad_maxima 339 elif c.derecha: 340 self.receptor.x += self.velocidad_maxima 341 342 if c.arriba: 343 self.receptor.y += self.velocidad_maxima 344 elif c.abajo: 345 if self.marcha_atras: 346 self.receptor.y -= self.velocidad_maxima 347 else: 348 if c.izquierda: 349 self.receptor.x -= self.velocidad_maxima 350 elif c.derecha: 351 self.receptor.x += self.velocidad_maxima 352 elif c.arriba: 353 self.receptor.y += self.velocidad_maxima 354 elif c.abajo: 355 if self.marcha_atras: 356 self.receptor.y -= self.velocidad_maxima
357
358 - def decelerar(self):
359 if self.velocidad > self.deceleracion: 360 self.velocidad -= self.deceleracion 361 elif self.velocidad < -self.deceleracion: 362 self.velocidad += self.deceleracion 363 else: 364 self.velocidad = 0
365
366 - def avanzar(self, delta):
367 self.velocidad += self.aceleracion * delta 368 369 if self.velocidad > self.velocidad_maxima: 370 self.velocidad = self.velocidad_maxima 371 elif self.velocidad < - self.velocidad_maxima / 2: 372 self.velocidad = - self.velocidad_maxima / 2
373 374
375 -class MoverseComoCoche(MoverseConElTeclado):
376 "Hace que un actor se mueva como un coche." 377
378 - def __init__(self, receptor, control=None, velocidad_maxima=4, 379 aceleracion=0.06, deceleracion=0.1, rozamiento=0):
380 MoverseConElTeclado.__init__(self, receptor, 381 control=control, 382 velocidad_maxima=velocidad_maxima, 383 aceleracion=aceleracion, 384 deceleracion=deceleracion, 385 con_rotacion=True) 386 387 self._rozamiento = rozamiento 388 self._velocidad_maxima_aux = self.velocidad_maxima
389
390 - def set_rozamiento(self, nivel_rozamiento):
391 self._rozamiento = nivel_rozamiento 392 self.velocidad_maxima = self._velocidad_maxima_aux - self._rozamiento
393
394 - def get_rozamiento(self):
395 return self._rozamiento
396
397 - def set_velocidad_maxima(self, velocidad):
398 self._velocidad_maxima = velocidad 399 self._velocidad_maxima_aux = self._velocidad_maxima
400
401 - def get_velocidad_maxima(self):
402 return self.velocidad_maxima
403 404 rozamiento = property(get_rozamiento, set_rozamiento, doc="Define el rozamiento del coche con la superficie por donde circula.")
405 406
407 -class PuedeExplotar(Habilidad):
408 "Hace que un actor se pueda hacer explotar invocando al metodo eliminar." 409
410 - def __init__(self, receptor):
411 Habilidad.__init__(self, receptor) 412 receptor.eliminar = self.eliminar_y_explotar
413
414 - def eliminar_y_explotar(self):
415 explosion = pilas.actores.Explosion() 416 explosion.x = self.receptor.x 417 explosion.y = self.receptor.y 418 explosion.escala = self.receptor.escala * 2 419 pilas.actores.Actor.eliminar(self.receptor)
420
421 -class SiempreEnElCentro(Habilidad):
422 """Hace que un actor siempre esté en el centro de la camara y la desplace 423 cuando el actor se desplaza.""" 424
425 - def __init__(self, receptor):
426 Habilidad.__init__(self, receptor)
427
428 - def actualizar(self):
429 pilas.escena_actual().camara.x = self.receptor.x 430 pilas.escena_actual().camara.y = self.receptor.y
431 432
433 -class SeMantieneEnPantalla(Habilidad):
434 """Se asegura de que el actor regrese a la pantalla si sale o que no 435 salga en nigún momento de la pantalla. 436 437 Si el actor sale por la derecha de la pantalla, entonces regresa 438 por la izquiera. Si sale por arriba regresa por abajo y asi... 439 440 """
441 - def __init__(self, receptor, permitir_salida=True):
442 """Inicializa la habilidad. 443 444 :param receptor: El actor que aprenderá la habilidad. 445 :param permitir_salida: Valor booleano que establece si el actor puede salir por los lados de la ventana y regresar por el lado opuesto. Si se establece a False, el actor no puede salir de la ventana en ningún momento. 446 """ 447 Habilidad.__init__(self, receptor) 448 self.ancho, self.alto = pilas.mundo.motor.obtener_area() 449 self.permitir_salida = permitir_salida
450
451 - def actualizar(self):
452 if self.permitir_salida : 453 # Se asegura de regresar por izquierda y derecha. 454 if self.receptor.derecha < -(self.ancho/2): 455 self.receptor.izquierda = (self.ancho/2) 456 elif self.receptor.izquierda > (self.ancho/2): 457 self.receptor.derecha = -(self.ancho/2) 458 459 # Se asegura de regresar por arriba y abajo. 460 if self.receptor.abajo > (self.alto/2): 461 self.receptor.arriba = -(self.alto/2) 462 elif self.receptor.arriba < -(self.alto/2): 463 self.receptor.abajo = (self.alto/2) 464 else: 465 if self.receptor.izquierda <= -(self.ancho/2): 466 self.receptor.izquierda = -(self.ancho/2) 467 elif self.receptor.derecha >= (self.ancho/2): 468 self.receptor.derecha = self.ancho/2 469 470 if self.receptor.arriba > (self.alto/2): 471 self.receptor.arriba = (self.alto/2) 472 elif self.receptor.abajo < -(self.alto/2): 473 self.receptor.abajo = -(self.alto/2)
474 475
476 -class PisaPlataformas(Habilidad):
477 """Enseña al actor a pisar plataformas físicas.""" 478
479 - def __init__(self, receptor):
480 Habilidad.__init__(self, receptor) 481 error = random.randint(-10, 10) / 10.0 482 self.figura = pilas.fisica.fisica.crear_figura_cuadrado(receptor.x + error, 483 receptor.y + error, 484 receptor.radio_de_colision, 485 masa=10, 486 elasticidad=0, 487 friccion=0) 488 self.ultimo_x = receptor.x 489 self.ultimo_y = receptor.y
490
491 - def actualizar(self):
492 # Mueve el objeto siempre y cuando no parezca que algo 493 # no fisico (es decir de pymunk) lo ha afectado. 494 self.receptor.x = self.figura.body.position.x 495 self.receptor.y = self.figura.body.position.y
496
497 - def eliminar(self):
498 pilas.fisica.fisica.eliminar(self.figura)
499 500
501 -class Imitar(Habilidad):
502 "Logra que el actor imite las propiedades de otro." 503
504 - def __init__(self, receptor, objeto_a_imitar, con_rotacion=True):
505 """Inicializa la habilidad. 506 507 :param receptor: Referencia al actor. 508 :param objeto_a_imitar: Cualquier objeto con atributos rotacion, x e y (por ejemplo otro actor). 509 :param con_rotacion: Si debe imitar o no la rotación. 510 """ 511 Habilidad.__init__(self, receptor) 512 self.objeto_a_imitar = objeto_a_imitar 513 514 # Establecemos el mismo id para el actor y el objeto fisico 515 # al que imita. Así luego en las colisiones fisicas sabremos a que 516 # actor corresponde esa colisión. 517 receptor.id = objeto_a_imitar.id 518 519 # Y nos guardamos una referencia al objeto físico al que imita. 520 # Posterormente en las colisiones fisicas comprobaremos si el 521 # objeto tiene el atributo "figura" para saber si estamos delante 522 # de una figura fisica o no. 523 receptor.figura = objeto_a_imitar 524 525 self.con_rotacion = con_rotacion
526
527 - def actualizar(self):
528 self.receptor.x = self.objeto_a_imitar.x 529 self.receptor.y = self.objeto_a_imitar.y 530 if (self.con_rotacion): 531 self.receptor.rotacion = self.objeto_a_imitar.rotacion
532
533 - def eliminar(self):
534 if isinstance(self.objeto_a_imitar, pilas.fisica.Figura): 535 self.objeto_a_imitar.eliminar()
536 537
538 -class Disparar(Habilidad):
539 """Establece la habilidad de poder disparar un Actor o un objeto de tipo 540 pilas.municion.Municion.""" 541
542 - def __init__(self, receptor, 543 municion = pilas.actores.Bala, 544 parametros_municion = {}, 545 grupo_enemigos=[], 546 cuando_elimina_enemigo=None, 547 frecuencia_de_disparo=10, 548 angulo_salida_disparo=0, 549 offset_disparo=(0,0), 550 offset_origen_actor=(0,0), 551 cuando_dispara=None, 552 escala=1):
553 """ 554 Construye la habilidad. 555 556 :param municion: Municion o Actor que se disparará. 557 :param grupo_enemigos: Actores que son considerados enemigos y con los que colisionará la munición disparada. 558 :param cuando_elimina_enemigo: Método que será llamado cuando se produzca un impacto con un enemigo. 559 :param frecuencia_de_disparo: El número de disparos por segundo que realizará. 560 :param angulo_salida_disparo: Especifica el angulo por donde saldrá el disparo efectuado por el Actor. 561 :param offset_disparo: Separación en pixeles (x,y) del disparo con respecto al centro del Actor. 562 :param offset_origen_actor: Si el Actor no tiene su origen en el centro, con este parametro podremos colocar correctamente el disparo. 563 :param cuando_dispara: Metodo que será llamado cuando se produzca un disparo. 564 :param escala: Escala de los actores que serán disparados. 565 566 :example: 567 568 >>> mono = pilas.actores.Mono() 569 >>> mono.aprender(pilas.habilidades.Disparar, 570 >>> municion=pilas.actores.proyectil.Bala, 571 >>> grupo_enemigos=enemigos, 572 >>> cuando_elimina_enemigo=eliminar_enemigo) 573 574 .. 575 """ 576 577 Habilidad.__init__(self, receptor) 578 self.receptor = receptor 579 580 self._municion = municion 581 self.parametros_municion = parametros_municion 582 583 self.offset_disparo_x = offset_disparo[0] 584 self.offset_disparo_y = offset_disparo[1] 585 586 self.offset_origen_actor_x = offset_origen_actor[0] 587 self.offset_origen_actor_y = offset_origen_actor[1] 588 589 self.angulo_salida_disparo = angulo_salida_disparo 590 self.frecuencia_de_disparo = frecuencia_de_disparo 591 self.contador_frecuencia_disparo = 0 592 self.proyectiles = [] 593 594 self.grupo_enemigos = grupo_enemigos 595 596 self.definir_colision(self.grupo_enemigos, cuando_elimina_enemigo) 597 598 self.cuando_dispara = cuando_dispara 599 600 self.escala = escala
601
602 - def set_frecuencia_de_disparo(self, valor):
603 self._frecuencia_de_disparo = 60 / valor
604
606 return self._frecuencia_de_disparo
607
608 - def set_municion(self, valor):
609 self._municion = valor 610 self.parametros_municion = {}
611
612 - def get_municion(self):
613 return self._municion
614 615 frecuencia_de_disparo = property(get_frecuencia_de_disparo, set_frecuencia_de_disparo, doc="Número de disparos por segundo.") 616 municion = property(get_municion, set_municion, doc="Establece el tipo de municion que dispara.") 617
618 - def definir_colision(self, grupo_enemigos, cuando_elimina_enemigo):
619 self.grupo_enemigos = grupo_enemigos 620 pilas.escena_actual().colisiones.agregar(self.proyectiles, self.grupo_enemigos, 621 cuando_elimina_enemigo)
622 - def actualizar(self):
623 self.contador_frecuencia_disparo += 1 624 625 if self.pulsa_disparar(): 626 if self.contador_frecuencia_disparo > self._frecuencia_de_disparo: 627 self.contador_frecuencia_disparo = 0 628 self.disparar() 629 630 self._eliminar_disparos_innecesarios()
631
632 - def _agregar_disparo(self, proyectil):
633 proyectil.escala = self.escala 634 self._desplazar_proyectil(proyectil, self.offset_disparo_x, self.offset_disparo_y) 635 self.proyectiles.append(proyectil)
636
638 for d in list(self.proyectiles): 639 if d.esta_fuera_de_la_pantalla(): 640 d.eliminar() 641 self.proyectiles.remove(d)
642
643 - def _desplazar_proyectil(self, proyectil, offset_x, offset_y):
644 rotacion_en_radianes = math.radians(-proyectil.rotacion) 645 dx = math.cos(rotacion_en_radianes) 646 dy = math.sin(rotacion_en_radianes) 647 648 proyectil.x += dx * offset_x 649 proyectil.y += dy * offset_y
650
651 - def disparar(self):
652 if (self.receptor.espejado): 653 offset_origen_actor_x = -self.offset_origen_actor_x 654 else: 655 offset_origen_actor_x = self.offset_origen_actor_x 656 657 if issubclass(self.municion, pilas.municion.Municion): 658 659 objeto_a_disparar = self.municion(**self.parametros_municion) 660 661 objeto_a_disparar.disparar(x=self.receptor.x+offset_origen_actor_x, 662 y=self.receptor.y+self.offset_origen_actor_y, 663 angulo_de_movimiento=self.receptor.rotacion + -(self.angulo_salida_disparo), 664 rotacion=self.receptor.rotacion - 90, 665 offset_disparo_x=self.offset_disparo_x, 666 offset_disparo_y=self.offset_disparo_y) 667 668 for disparo in objeto_a_disparar.proyectiles: 669 self._agregar_disparo(disparo) 670 671 elif issubclass(self.municion, pilas.actores.Actor): 672 673 objeto_a_disparar = self.municion(x=self.receptor.x+offset_origen_actor_x, 674 y=self.receptor.y+self.offset_origen_actor_y, 675 rotacion=self.receptor.rotacion - 90, 676 angulo_de_movimiento=self.receptor.rotacion + -(self.angulo_salida_disparo)) 677 678 self._agregar_disparo(objeto_a_disparar) 679 680 else: 681 raise "No se puede disparar este objeto." 682 683 if self.cuando_dispara: 684 self.cuando_dispara()
685 686
687 - def eliminar(self):
688 pass
689
690 - def pulsa_disparar(self):
692 693
694 -class DispararConClick(Disparar):
695 """Establece la habilidad de poder disparar un Actor o un objeto de tipo 696 pilas.municion.Municion pulsando el boton izquierdo del ratón.""" 697
698 - def __init__(self, *k, **kv):
699 super(DispararConClick, self).__init__(*k, **kv) 700 self.boton_pulsado = False 701 pilas.eventos.click_de_mouse.conectar(self.cuando_hace_click) 702 pilas.eventos.termina_click.conectar(self.cuando_termina_click)
703
704 - def cuando_hace_click(self, evento):
705 if evento.boton == 1: 706 self.boton_pulsado = True
707
708 - def cuando_termina_click(self, evento):
709 if evento.boton == 1: 710 self.boton_pulsado = False
711
712 - def pulsa_disparar(self):
713 return self.boton_pulsado
714