pilas/habilidades.py
# -*- encoding: utf-8 -*-
# Pilas engine - A video game framework.
#
# Copyright 2010 - Hugo Ruscitti
# License: LGPLv3 (see http://www.gnu.org/licenses/lgpl.html)
#
# Website - http://www.pilas-engine.com.ar
import random
import pilas
import math
class Habilidad(object):
"""Representa una habilidad que un actor puede aprender."""
def __init__(self, receptor):
self.receptor = receptor
def actualizar(self):
pass
def eliminar(self):
pass
class RebotarComoPelota(Habilidad):
"""Le indica al actor que rebote y colisiones como una pelota.
>>> un_actor = pilas.actores.Aceituna()
>>> un_actor.aprender(pilas.habilidades.RebotarComoPelota)
"""
def __init__(self, receptor):
Habilidad.__init__(self, receptor)
error = random.randint(-10, 10) / 10.0
circulo = pilas.fisica.Circulo(receptor.x + error,
receptor.y + error,
receptor.radio_de_colision)
receptor.aprender(pilas.habilidades.Imitar, circulo)
self.circulo = circulo
receptor.impulsar = self.impulsar
receptor.empujar = self.empujar
def eliminar(self):
self.circulo.eliminar()
def impulsar(self, dx, dy):
self.circulo.impulsar(dx, dy)
def empujar(self, dx, dy):
self.circulo.empujar(dx, dy)
class RebotarComoCaja(Habilidad):
"""Le indica al actor que rebote y colisiones como una caja cuadrada.
>>> un_actor = pilas.actores.Aceituna()
>>> un_actor.aprender(pilas.habilidades.RebotarComoPelota)
"""
def __init__(self, receptor):
Habilidad.__init__(self, receptor)
error = random.randint(-10, 10) / 10.0
rectangulo = pilas.fisica.Rectangulo(receptor.x + error,
receptor.y + error,
receptor.radio_de_colision*2 - 4,
receptor.radio_de_colision*2 - 4,
)
receptor.aprender(pilas.habilidades.Imitar, rectangulo)
self.rectangulo = rectangulo
def eliminar(self):
self.rectangulo.eliminar()
class ColisionableComoPelota(RebotarComoPelota):
"""Le indica al actor que colisione como una pelota, pero que no rebote.
>>> un_actor = pilas.actores.Aceituna()
>>> un_actor.aprender(pilas.habilidades.ColisionableComoPelota)
"""
def __init__(self, receptor):
RebotarComoPelota.__init__(self, receptor)
def actualizar(self):
self.figura.body.position.x = self.receptor.x
self.figura.body.position.y = self.receptor.y
def eliminar(self):
pilas.fisica.fisica.eliminar(self.figura)
class SeguirAlMouse(Habilidad):
"Hace que un actor siga la posición del mouse en todo momento."
def __init__(self, receptor):
Habilidad.__init__(self, receptor)
pilas.escena_actual().mueve_mouse.conectar(self.mover)
def mover(self, evento):
self.receptor.x = evento.x
self.receptor.y = evento.y
class RotarConMouse(Habilidad):
""""Hace que un actor rote con respecto a la posicion del mouse.
Ejemplo:
>>> actor.aprender(pilas.habilidades.RotarConMouse,
lado_seguimiento=pilas.habilidades.RotarConMouse.ABAJO)
"""
ARRIBA = 270
ABAJO = 90
IZQUIERDA = 180
DERECHA = 0
def __init__(self, receptor, lado_seguimiento=ARRIBA):
"""Inicializa la Habilidad
:param receptor: La referencia al actor.
:param lado_seguimiento: Establece el lado del actor que rotará para estar encarado hacia el puntero del mouse.
"""
Habilidad.__init__(self, receptor)
pilas.escena_actual().mueve_mouse.conectar(self.se_movio_el_mouse)
pilas.escena_actual().actualizar.conectar(self.rotar)
self.lado_seguimiento = lado_seguimiento
self.raton_x = receptor.x
self.raton_y = receptor.y
def se_movio_el_mouse(self, evento):
self.raton_x = evento.x
self.raton_y = evento.y
def rotar(self, evento):
receptor = (self.receptor.x, self.receptor.y)
raton = (self.raton_x, self.raton_y)
angulo = pilas.utils.obtener_angulo_entre(receptor, raton)
self.receptor.rotacion = -(angulo) - self.lado_seguimiento
class MirarAlActor(Habilidad):
""""Hace que un actor rote para mirar hacia otro actor.
"""
ARRIBA = 270
ABAJO = 90
IZQUIERDA = 180
DERECHA = 0
def __init__(self, receptor, actor_a_seguir, lado_seguimiento=ARRIBA):
"""Inicializa la habilidad.
:param receptor: Actor que aprenderá la habilidad.
:param actor_a_seguir : Actor al que se desea seguir con la mirada.
:param lado_seguimiento: Establece el lado del actor que rotará para estar encarado hacia el actor que desea vigilar.
"""
Habilidad.__init__(self, receptor)
pilas.escena_actual().actualizar.conectar(self.rotar)
self.lado_seguimiento = lado_seguimiento
self.actor_a_seguir = actor_a_seguir
def rotar(self, evento):
receptor = (self.receptor.x, self.receptor.y)
actor_a_seguir = (self.actor_a_seguir.x, self.actor_a_seguir.y)
angulo = pilas.utils.obtener_angulo_entre(receptor, actor_a_seguir)
self.receptor.rotacion = -(angulo) - self.lado_seguimiento
class AumentarConRueda(Habilidad):
"Permite cambiar el tamaño de un actor usando la ruedita scroll del mouse."
def __init__(self, receptor):
Habilidad.__init__(self, receptor)
pilas.escena_actual().mueve_rueda.conectar(self.cambiar_de_escala)
def cambiar_de_escala(self, evento):
self.receptor.escala += (evento.delta / 4.0)
class SeguirClicks(Habilidad):
"Hace que el actor se coloque la posición del cursor cuando se hace click."
def __init__(self, receptor):
Habilidad.__init__(self, receptor)
pilas.escena_actual().click_de_mouse.conectar(self.moverse_a_este_punto)
def moverse_a_este_punto(self, evento):
if (evento.boton == 1):
self.receptor.x = [evento.x], 0.5
self.receptor.y = [evento.y], 0.5
class Arrastrable(Habilidad):
"""Hace que un objeto se pueda arrastrar con el puntero del mouse.
Cuando comienza a mover al actor se llama al metodo ''comienza_a_arrastrar''
y cuando termina llama a ''termina_de_arrastrar''. Estos nombres
de metodos se llaman para que puedas personalizar estos eventos, dado
que puedes usar polimorfismo para redefinir el comportamiento
de estos dos metodos. Observa un ejemplo de esto en
el ejemplo ``pilas.ejemplos.Piezas``.
"""
def __init__(self, receptor):
Habilidad.__init__(self, receptor)
pilas.escena_actual().click_de_mouse.conectar(self.cuando_intenta_arrastrar)
def cuando_intenta_arrastrar(self, evento):
"Intenta mover el objeto con el mouse cuando se pulsa sobre el."
if (evento.boton == 1):
if self.receptor.colisiona_con_un_punto(evento.x, evento.y):
pilas.escena_actual().termina_click.conectar(self.cuando_termina_de_arrastrar, id='cuando_termina_de_arrastrar')
pilas.escena_actual().mueve_mouse.conectar(self.cuando_arrastra, id='cuando_arrastra')
self.comienza_a_arrastrar()
def cuando_arrastra(self, evento):
"Arrastra el actor a la posicion indicada por el puntero del mouse."
if self._el_receptor_tiene_fisica():
pilas.escena_actual().fisica.cuando_mueve_el_mouse(evento.x, evento.y)
else:
self.receptor.x += evento.dx
self.receptor.y += evento.dy
def cuando_termina_de_arrastrar(self, evento):
"Suelta al actor porque se ha soltado el botón del mouse."
pilas.escena_actual().mueve_mouse.desconectar_por_id(id='cuando_arrastra')
self.termina_de_arrastrar()
pilas.escena_actual().termina_click.desconectar_por_id(id='cuando_termina_de_arrastrar')
def comienza_a_arrastrar(self):
if self._el_receptor_tiene_fisica():
pilas.escena_actual().fisica.capturar_figura_con_el_mouse(self.receptor.figura)
def termina_de_arrastrar(self):
if self._el_receptor_tiene_fisica():
pilas.escena_actual().fisica.cuando_suelta_el_mouse()
def _el_receptor_tiene_fisica(self):
return hasattr(self.receptor, 'figura')
class MoverseConElTeclado(Habilidad):
"""Hace que un actor cambie de posición con pulsar el teclado."""
CUATRO_DIRECCIONES = 4
OCHO_DIRECCIONES = 8
def __init__(self, receptor, control=None, direcciones=OCHO_DIRECCIONES, velocidad_maxima=4,
aceleracion=1, deceleracion=0.1, con_rotacion=False, velocidad_rotacion=1, marcha_atras=True):
"""Inicializa la habilidad.
:param receptor: Referencia al actor que aprenderá la habilidad.
:param control: Control al que va a responder para mover el Actor.
: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.
:param velocidad_maxima: Velocidad maxima en pixeles a la que se moverá el Actor.
:param aceleracion: Indica lo rapido que acelera el actor hasta su velocidad máxima.
:param deceleracion: Indica lo rapido que decelera el actor hasta parar.
:param con_rotacion: Si deseas que el actor rote pulsando las teclas de izquierda y derecha.
:param velocidad_rotacion: Indica lo rapido que rota un actor sobre si mismo.
:param marcha_atras: Posibilidad de ir hacia atrás. (True o False)
"""
Habilidad.__init__(self, receptor)
pilas.escena_actual().actualizar.conectar(self.on_key_press)
if control == None:
self.control = self.receptor.escena.control
else:
self.control = control
self.direcciones = direcciones
self.velocidad = 0
self.deceleracion = deceleracion
self._velocidad_maxima = velocidad_maxima
self._aceleracion = aceleracion
self.con_rotacion = con_rotacion
self.velocidad_rotacion = velocidad_rotacion
self.marcha_atras = marcha_atras
def set_velocidad_maxima(self, velocidad):
self._velocidad_maxima = velocidad
def get_velocidad_maxima(self):
return self._velocidad_maxima
def get_aceleracion(self):
return self._aceleracion
def set_aceleracion(self, aceleracion):
self._aceleracion = aceleracion
velocidad_maxima = property(get_velocidad_maxima, set_velocidad_maxima, doc="Define la velocidad maxima.")
aceleracion = property(get_aceleracion, set_aceleracion, doc="Define la acelaracion.")
def on_key_press(self, evento):
c = self.control
if self.con_rotacion:
if c.izquierda:
self.receptor.rotacion -= self.velocidad_rotacion * self.velocidad_maxima
elif c.derecha:
self.receptor.rotacion += self.velocidad_rotacion * self.velocidad_maxima
if c.arriba:
self.avanzar(+1)
elif c.abajo:
if self.marcha_atras:
self.avanzar(-1)
else:
self.decelerar()
else:
self.decelerar()
rotacion_en_radianes = math.radians(-self.receptor.rotacion + 90)
dx = math.cos(rotacion_en_radianes) * self.velocidad
dy = math.sin(rotacion_en_radianes) * self.velocidad
self.receptor.x += dx
self.receptor.y += dy
else:
if self.direcciones == MoverseConElTeclado.OCHO_DIRECCIONES:
if c.izquierda:
self.receptor.x -= self.velocidad_maxima
elif c.derecha:
self.receptor.x += self.velocidad_maxima
if c.arriba:
self.receptor.y += self.velocidad_maxima
elif c.abajo:
if self.marcha_atras:
self.receptor.y -= self.velocidad_maxima
else:
if c.izquierda:
self.receptor.x -= self.velocidad_maxima
elif c.derecha:
self.receptor.x += self.velocidad_maxima
elif c.arriba:
self.receptor.y += self.velocidad_maxima
elif c.abajo:
if self.marcha_atras:
self.receptor.y -= self.velocidad_maxima
def decelerar(self):
if self.velocidad > self.deceleracion:
self.velocidad -= self.deceleracion
elif self.velocidad < -self.deceleracion:
self.velocidad += self.deceleracion
else:
self.velocidad = 0
def avanzar(self, delta):
self.velocidad += self.aceleracion * delta
if self.velocidad > self.velocidad_maxima:
self.velocidad = self.velocidad_maxima
elif self.velocidad < - self.velocidad_maxima / 2:
self.velocidad = - self.velocidad_maxima / 2
class MoverseComoCoche(MoverseConElTeclado):
"Hace que un actor se mueva como un coche."
def __init__(self, receptor, control=None, velocidad_maxima=4,
aceleracion=0.06, deceleracion=0.1, rozamiento=0, velocidad_rotacion=1):
MoverseConElTeclado.__init__(self, receptor,
control=control,
velocidad_maxima=velocidad_maxima,
aceleracion=aceleracion,
deceleracion=deceleracion,
velocidad_rotacion=velocidad_rotacion,
con_rotacion=True)
self._rozamiento = rozamiento
self._velocidad_maxima_aux = self.velocidad_maxima
def set_rozamiento(self, nivel_rozamiento):
self._rozamiento = nivel_rozamiento
self.velocidad_maxima = self._velocidad_maxima_aux - self._rozamiento
def get_rozamiento(self):
return self._rozamiento
def set_velocidad_maxima(self, velocidad):
self._velocidad_maxima = velocidad
self._velocidad_maxima_aux = self._velocidad_maxima
def get_velocidad_maxima(self):
return self.velocidad_maxima
rozamiento = property(get_rozamiento, set_rozamiento, doc="Define el rozamiento del coche con la superficie por donde circula.")
class PuedeExplotar(Habilidad):
"Hace que un actor se pueda hacer explotar invocando al metodo eliminar."
def __init__(self, receptor):
Habilidad.__init__(self, receptor)
receptor.eliminar = self.eliminar_y_explotar
def eliminar_y_explotar(self):
explosion = pilas.actores.Explosion()
explosion.x = self.receptor.x
explosion.y = self.receptor.y
explosion.escala = self.receptor.escala * 2
pilas.actores.Actor.eliminar(self.receptor)
class SiempreEnElCentro(Habilidad):
"""Hace que un actor siempre esté en el centro de la camara y la desplace
cuando el actor se desplaza."""
def __init__(self, receptor):
Habilidad.__init__(self, receptor)
def actualizar(self):
pilas.escena_actual().camara.x = self.receptor.x
pilas.escena_actual().camara.y = self.receptor.y
class SeMantieneEnPantalla(Habilidad):
"""Se asegura de que el actor regrese a la pantalla si sale o que no
salga en nigún momento de la pantalla.
Si el actor sale por la derecha de la pantalla, entonces regresa
por la izquiera. Si sale por arriba regresa por abajo y asi...
"""
def __init__(self, receptor, permitir_salida=True):
"""Inicializa la habilidad.
:param receptor: El actor que aprenderá la habilidad.
: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.
"""
Habilidad.__init__(self, receptor)
self.ancho, self.alto = pilas.mundo.obtener_area()
self.permitir_salida = permitir_salida
def actualizar(self):
if self.permitir_salida :
# Se asegura de regresar por izquierda y derecha.
if self.receptor.derecha < -(self.ancho/2):
self.receptor.izquierda = (self.ancho/2)
elif self.receptor.izquierda > (self.ancho/2):
self.receptor.derecha = -(self.ancho/2)
# Se asegura de regresar por arriba y abajo.
if self.receptor.abajo > (self.alto/2):
self.receptor.arriba = -(self.alto/2)
elif self.receptor.arriba < -(self.alto/2):
self.receptor.abajo = (self.alto/2)
else:
if self.receptor.izquierda <= -(self.ancho/2):
self.receptor.izquierda = -(self.ancho/2)
elif self.receptor.derecha >= (self.ancho/2):
self.receptor.derecha = self.ancho/2
if self.receptor.arriba > (self.alto/2):
self.receptor.arriba = (self.alto/2)
elif self.receptor.abajo < -(self.alto/2):
self.receptor.abajo = -(self.alto/2)
class PisaPlataformas(Habilidad):
"""Enseña al actor a pisar plataformas físicas."""
def __init__(self, receptor):
Habilidad.__init__(self, receptor)
error = random.randint(-10, 10) / 10.0
self.figura = pilas.fisica.fisica.crear_figura_cuadrado(receptor.x + error,
receptor.y + error,
receptor.radio_de_colision,
masa=10,
elasticidad=0,
friccion=0)
self.ultimo_x = receptor.x
self.ultimo_y = receptor.y
def actualizar(self):
# Mueve el objeto siempre y cuando no parezca que algo
# no fisico (es decir de pymunk) lo ha afectado.
self.receptor.x = self.figura.body.position.x
self.receptor.y = self.figura.body.position.y
def eliminar(self):
pilas.fisica.fisica.eliminar(self.figura)
class Imitar(Habilidad):
"Logra que el actor imite las propiedades de otro."
def __init__(self, receptor, objeto_a_imitar, con_escala=True, con_rotacion=True):
"""Inicializa la habilidad.
:param receptor: Referencia al actor.
:param objeto_a_imitar: Cualquier objeto con atributos rotacion, x e y (por ejemplo otro actor).
:param con_rotacion: Si debe imitar o no la rotación.
"""
Habilidad.__init__(self, receptor)
self.objeto_a_imitar = objeto_a_imitar
# Establecemos el mismo id para el actor y el objeto fisico
# al que imita. Así luego en las colisiones fisicas sabremos a que
# actor corresponde esa colisión.
receptor.id = objeto_a_imitar.id
# Y nos guardamos una referencia al objeto físico al que imita.
# Posterormente en las colisiones fisicas comprobaremos si el
# objeto tiene el atributo "figura" para saber si estamos delante
# de una figura fisica o no.
if hasattr(objeto_a_imitar, '_cuerpo'):
receptor.figura = objeto_a_imitar
self.con_escala = con_escala
self.con_rotacion = con_rotacion
def actualizar(self):
self.receptor.x = self.objeto_a_imitar.x
self.receptor.y = self.objeto_a_imitar.y
if self.con_escala:
self.objeto_a_imitar.escala = self.receptor.escala
if self.con_rotacion:
self.receptor.rotacion = self.objeto_a_imitar.rotacion
def eliminar(self):
if isinstance(self.objeto_a_imitar, pilas.fisica.Figura):
self.objeto_a_imitar.eliminar()
class Disparar(Habilidad):
"""Establece la habilidad de poder disparar un Actor o un objeto de tipo
pilas.municion.Municion."""
def __init__(self, receptor,
municion = pilas.actores.Bala,
parametros_municion = {},
grupo_enemigos=[],
cuando_elimina_enemigo=None,
frecuencia_de_disparo=10,
angulo_salida_disparo=0,
offset_disparo=(0,0),
offset_origen_actor=(0,0),
cuando_dispara=None,
escala=1,
control=None):
"""
Construye la habilidad.
:param municion: Municion o Actor que se disparará.
:param grupo_enemigos: Actores que son considerados enemigos y con los que colisionará la munición disparada.
:param cuando_elimina_enemigo: Método que será llamado cuando se produzca un impacto con un enemigo.
:param frecuencia_de_disparo: El número de disparos por segundo que realizará.
:param angulo_salida_disparo: Especifica el angulo por donde saldrá el disparo efectuado por el Actor.
:param offset_disparo: Separación en pixeles (x,y) del disparo con respecto al centro del Actor.
:param offset_origen_actor: Si el Actor no tiene su origen en el centro, con este parametro podremos colocar correctamente el disparo.
:param cuando_dispara: Metodo que será llamado cuando se produzca un disparo.
:param escala: Escala de los actores que serán disparados.
:param control: Indica los controles que utiliza el actor para saber cuando pulsa el botón de disparar.
:example:
>>> mono = pilas.actores.Mono()
>>> mono.aprender(pilas.habilidades.Disparar,
>>> municion=pilas.actores.proyectil.Bala,
>>> grupo_enemigos=enemigos,
>>> cuando_elimina_enemigo=eliminar_enemigo)
..
"""
Habilidad.__init__(self, receptor)
self.receptor = receptor
self._municion = municion
self.parametros_municion = parametros_municion
self.offset_disparo_x = offset_disparo[0]
self.offset_disparo_y = offset_disparo[1]
self.offset_origen_actor_x = offset_origen_actor[0]
self.offset_origen_actor_y = offset_origen_actor[1]
self.angulo_salida_disparo = angulo_salida_disparo
self.frecuencia_de_disparo = frecuencia_de_disparo
self.contador_frecuencia_disparo = 0
self.proyectiles = []
self.grupo_enemigos = grupo_enemigos
self.definir_colision(self.grupo_enemigos, cuando_elimina_enemigo)
self.cuando_dispara = cuando_dispara
self.escala = escala
self.control = control
def set_frecuencia_de_disparo(self, valor):
self._frecuencia_de_disparo = 60 / valor
def get_frecuencia_de_disparo(self):
return self._frecuencia_de_disparo
def set_municion(self, valor):
self._municion = valor
self.parametros_municion = {}
def get_municion(self):
return self._municion
frecuencia_de_disparo = property(get_frecuencia_de_disparo, set_frecuencia_de_disparo, doc="Número de disparos por segundo.")
municion = property(get_municion, set_municion, doc="Establece el tipo de municion que dispara.")
def definir_colision(self, grupo_enemigos, cuando_elimina_enemigo):
self.grupo_enemigos = grupo_enemigos
pilas.escena_actual().colisiones.agregar(self.proyectiles, self.grupo_enemigos,
cuando_elimina_enemigo)
def actualizar(self):
self.contador_frecuencia_disparo += 1
if self.pulsa_disparar():
if self.contador_frecuencia_disparo > self._frecuencia_de_disparo:
self.contador_frecuencia_disparo = 0
self.disparar()
self._eliminar_disparos_innecesarios()
def _agregar_disparo(self, proyectil):
proyectil.escala = self.escala
self._desplazar_proyectil(proyectil, self.offset_disparo_x, self.offset_disparo_y)
self.proyectiles.append(proyectil)
def _eliminar_disparos_innecesarios(self):
for d in list(self.proyectiles):
if d.esta_fuera_de_la_pantalla():
d.eliminar()
self.proyectiles.remove(d)
def _desplazar_proyectil(self, proyectil, offset_x, offset_y):
rotacion_en_radianes = math.radians(-proyectil.rotacion)
dx = math.cos(rotacion_en_radianes)
dy = math.sin(rotacion_en_radianes)
proyectil.x += dx * offset_x
proyectil.y += dy * offset_y
def disparar(self):
if (self.receptor.espejado):
offset_origen_actor_x = -self.offset_origen_actor_x
else:
offset_origen_actor_x = self.offset_origen_actor_x
if issubclass(self.municion, pilas.municion.Municion):
objeto_a_disparar = self.municion(**self.parametros_municion)
objeto_a_disparar.disparar(x=self.receptor.x+offset_origen_actor_x,
y=self.receptor.y+self.offset_origen_actor_y,
angulo_de_movimiento=self.receptor.rotacion + -(self.angulo_salida_disparo),
rotacion=self.receptor.rotacion - 90,
offset_disparo_x=self.offset_disparo_x,
offset_disparo_y=self.offset_disparo_y)
for disparo in objeto_a_disparar.proyectiles:
self._agregar_disparo(disparo)
disparo.fijo = self.receptor.fijo
elif issubclass(self.municion, pilas.actores.Actor):
objeto_a_disparar = self.municion(x=self.receptor.x+offset_origen_actor_x,
y=self.receptor.y+self.offset_origen_actor_y,
rotacion=self.receptor.rotacion - 90,
angulo_de_movimiento=self.receptor.rotacion + -(self.angulo_salida_disparo))
self._agregar_disparo(objeto_a_disparar)
objeto_a_disparar.fijo = self.receptor.fijo
else:
raise Exception("No se puede disparar este objeto.")
if self.cuando_dispara:
self.cuando_dispara()
def eliminar(self):
pass
def pulsa_disparar(self):
return self.control.boton if self.control else pilas.escena_actual().control.boton
class DispararConClick(Disparar):
"""Establece la habilidad de poder disparar un Actor o un objeto de tipo
pilas.municion.Municion pulsando el boton izquierdo del ratón."""
def __init__(self, *k, **kv):
super(DispararConClick, self).__init__(*k, **kv)
self.boton_pulsado = False
pilas.eventos.click_de_mouse.conectar(self.cuando_hace_click)
pilas.eventos.termina_click.conectar(self.cuando_termina_click)
def cuando_hace_click(self, evento):
if evento.boton == 1:
self.boton_pulsado = True
def cuando_termina_click(self, evento):
if evento.boton == 1:
self.boton_pulsado = False
def pulsa_disparar(self):
return self.boton_pulsado
class PerseguirAOtroActor(Habilidad):
"""Hace que un actor persiga a otro actor.
No navega alrededor de obstaculos.
"""
def __init__(self, receptor, objetivo, velocidad=5, inteligencia=1):
Habilidad.__init__(self, receptor)
self.objetivo = objetivo
self.velocidad = velocidad
self.perdido = None
def actualizar(self):
def limitar(valor):
return min(max(valor, -self.velocidad), self.velocidad)
objectivo_x = self.objetivo.x
objectivo_y = self.objetivo.y
if inteligencia == 0:
if random.randint(0, 10) > 7:
# se pierde
self.perdido = ( self.objetivo.x, self.objetivo.y )
else:
self.perdido = None
if self.perdido:
( objectivo_x, objetivo_y ) = perdido
self.receptor.x += limitar(objetivo_x - self.receptor.x)
self.receptor.y += limitar(objetivo_y - self.receptor.y)