Parametros a MiActor.decir() [SOLUCIONADO]

Buenas!

Agradecerioa mucho si alguien me indicara como podria cambiar la ubicación x,y del método .decir(), o hacerlo “espejado”. El problema está en que si el actor “dice” algo estando a la izquierda de la pantalla, el actor “globo” queda la mitad fuera de la pantalla y no se lee.

He mirado el codigo de pilasengine.actores.actor,py donde se define “decir”:

def decir(self, mensaje, autoeliminar=True):
        """Emite un mensaje usando un globo similar al de los comics.

        :param mensaje: Texto a mostrar en el mensaje.
        :type mensaje: string
        :param autoeliminar: Establece si se eliminará el globo al cabo de
                             unos segundos.
        :type autoeliminar: boolean
        """
        nuevo_actor = self.pilas.actores.Globo(mensaje, self.x, self.y,
                                               autoeliminar=autoeliminar,
                                               objetivo=self)
        nuevo_actor.z = self.z - 1

Como se puede ver, solo admite los parametros “texto” y True o False para que el mensaje quede fijo o desaparezca a los 3 segundos, y no sé como acceder a los parametros de “nuevo_actor”, donde intuyo que si se podria modificar.
No se podria implementar un método “espejado=True” para el método “decir”??? Eso solucionaria el problema (creo…), ya que el globo se dibujaria a “espejo” y quedaria a la derecha del actor (aunque no sé si el texto tambien se veria al reves :joy: )

Quizás parezca un tema tonto, pero estoy haciendo un juego con muchos dialogos, y me presenta un gran problema no poder poner actores a la izquierda de la pantalla…

Muchas gracias.

Hola @jordinur, el método decir es solo una especie de atajo para incluir dialogos. Tal vez lo mejor en tu caso es que construyas un atajo diferente. Por ejemplo:

def decir_desplazado_a_derecha(que_actor, texto):
    nuevo_actor = self.pilas.actores.Globo(texto, que_actor.x + 50, que_actor.y,
                                               autoeliminar=True,
                                               objetivo=que_actor)
    nuevo_actor.z = que_actor.z - 1

y para usarlo:

mi_actor = pilas.actores.Mono()
decir_desplazado_a_derecha(mi_actor, "hola !!!")

PD: no pude probar el código, puede que tenga algún error…

Hola, Hugo, ante todo muchas gracias por responder, y por hacerlo tan rápido.
Estoy en el trabajo, y he probado el codigo en la Pc con Windows, que no tiene Python instalado (aunque si Pilas jejeje…). Con un par de modificaciones menores el código ha funcionado, aunque como yo me temia, no acaba de ser lo que necesito. El tema es que el bocadillo sigue saliendo con la puntita de abajo a la derecha, aunque el actor esté a la izquierda. Si haces un espejado del actor Globo, el texto tambien sale espejado (como yo me temia).
Pero no te preocupes, esto para mí ya es un reto, y lo que voy a hacer es tratar de crear una nueva class Globo modificada y personalizada (tranquilo, que no toco la original…haré la Globo2) que se espeje segun donde esté el actor, sin espejar el texto (o quizás espejandolo 2 veces para que vuelva a estar del derecho, :smile: ). Si lo consigo ya os lo hago saber.

Muchas gracias de nuevo y hasta pronto…!

Bueno, esto es lo que he conseguido…
La verdad es que estoy bastante satisfecho, aunque a decir verdad el 99,9999 % del código es copiado.
Pero funciona bien, y eso es lo que cuenta para poder seguir con mi nuevo juego :smile:

Basicamente he creado una variable booleana para saber cuando debe ir de un lado y cuando del otro, y he redibujado el pico de abajo del bocadillo para que quede del lado correcto. Tambien he quitado todas las referencias a “objetivo”, ya que no dejaba cambiar las x y del bocadillo, y me tapaba una parte del actor.

# -*- encoding: utf-8 -*-
# Creado por Jordi Mestres (Alfons del Pou), Agosto de 2016, con PilasEngine ver. 1.4.1
#
#class Globo2 copiada y adaptada desde pilasengine.actores.Globo()
#
# pilas engine: un motor para hacer videojuegos
#
# Copyright 2010-2014 - Hugo Ruscitti
# License: LGPLv3 (see http://www.gnu.org/licenses/lgpl.html)
#
# Website - http://www.pilas-engine.com.ar


import pilasengine
pilas = pilasengine.iniciar(titulo="Adaptando la class Globo()")

from pilasengine.actores.actor import Actor

class Globo2(pilasengine.actores.Actor):
    """Representa un cuadro de dialogo estilo historietas.

    El actor se tiene que inicializar con una cadena de texto:

        >>> globo = pilas.actores.Globo("Hola mundo")

    .. image:: ../../pilas/data/manual/imagenes/actores/globo.png
    """

    def __init__(self, pilas, texto="", x=0, y=0, dialogo=None,
                 avance_con_clicks=True, autoeliminar=False, ancho_globo=0,
                 alto_globo=0, a_derecha=True):
        """ Constructor del Globo

        :param texto: Texto a mostrar en el globo.
        :type texto: boolean
        :param x: posicion horizontal del globo.
        :type x: int
        :param y: posicion vertical del globo.
        :type y: int
        :param dialogo: Dialogo que contiene las frases a mostrar en el globo.
        :type dialogo: Dialogo
        :param avance_con_clicks: Permite avanzar el dialogo pulsando el ratón.
        :type avance_con_clicks: boolean
        :param autoeliminar: Indica si se desea eliminar el globo cuando
                             pasen 3 segundos.
        :type autoeliminar: boolean
        :param ancho_globo: Estabece el ancho del globo en pixeles.
        :type ancho_globo: int
        :param alto_globo: Estabece el alto del globo en pixeles.
        :type alto_globo: int
        
        :param a_derecha: establece si el bocadillo va a derecha o a izquierda
        :type a_derecha: boolean
        """

        self.dialogo = dialogo
        Actor.__init__(self, pilas, x=x, y=y)
        self.imagen = 'invisible.png'
        self.a_derecha = a_derecha #este valor me da el texto a derecha o a izquierda
        ancho, alto = pilas.utils.obtener_area_de_texto(texto)

        # Podemos pasar el ancho del globo ya que si contiene opciones
        # cuyo texto es más largo que la cabecera del globo, no queda bien.
        if ancho_globo == 0:
            ancho = int((ancho + 12) - (ancho % 12))
        else:
            if ancho_globo > ancho:
                ancho = ancho_globo
            else:
                ancho = int((ancho + 12) - (ancho % 12))

        # Lo mismo para el alto
        if alto_globo == 0:
            alto = int((alto + 12) - alto % 12)
        else:
            alto = alto + alto_globo

        self.imagen = pilas.imagenes.cargar_superficie(ancho + 36,
                                                       alto + 24 + 35)

        self._pintar_globo(ancho, alto)
        self.imagen.texto(texto, 17, 20)
        if a_derecha: #si True texto a la derecha
			self.centro = ("izquierda", "abajo")
        else: #si False texto a la izquierda
			self.centro = ("derecha", "abajo")
        self.escala = 0.1
        self.escala = [1], 0.2
        self.ancho_globo = ancho
        self.alto_globo = alto

        if avance_con_clicks:
            self.pilas.escena_actual().click_de_mouse.conectar(self.cuando_quieren_avanzar)

        if autoeliminar:
            pilas.escena_actual().tareas.una_vez(3, self.eliminar)

        self.x = x
        self.y = y


    def cuando_quieren_avanzar(self, *k):
        """Función que se ejecuta al hacer click para avanzar o
        eliminar el globo.
        """
        if self.dialogo:
            self.dialogo.avanzar_al_siguiente_dialogo()
        else:
            self.eliminar()

    def _pintar_globo(self, ancho, alto):
        imagen = self.pilas.imagenes.cargar("globo.png")
        #self.espejado=True
        # esquina sup-izq
        self.imagen.pintar_parte_de_imagen(imagen, 0, 0, 12, 12, 0, 0)

        # borde superior
        for x in range(0, int(ancho) + 12, 12):
            self.imagen.pintar_parte_de_imagen(imagen, 12, 0, 12, 12, 12 + x, 0)

         # esquina sup-der
        self.imagen.pintar_parte_de_imagen(imagen, 100, 0, 12, 12,
                                           12 + int(ancho) + 12, 0)

        # centro del dialogo
        for y in range(0, int(alto) + 12, 12):
            # borde izquierdo
            self.imagen.pintar_parte_de_imagen(imagen, 0, 12, 12, 12, 0, 12 + y)
            # linea horizontal blanca, para el centro del dialogo.
            for x in range(0, int(ancho) + 12, 12):
                self.imagen.pintar_parte_de_imagen(imagen, 12, 12, 12, 12,
                                                   12 + x, 12 + y)

            # borde derecho
            self.imagen.pintar_parte_de_imagen(imagen, 100, 12, 12, 12,
                                               12 + int(ancho) + 12, 12 + y)

        # parte inferior
        self.imagen.pintar_parte_de_imagen(imagen, 0, 35, 12, 12, 0,
                                           0 + int(alto) + 12 + 12)

        # linea horizontal de la parte inferior
        for x in range(0, int(ancho) + 12, 12):
            self.imagen.pintar_parte_de_imagen(imagen, 12, 35, 12, 12, 12 + x,
                                               0 + int(alto) + 12 + 12)

        self.imagen.pintar_parte_de_imagen(imagen, 100, 35, 12, 12,
                                           12 + int(ancho) + 12,
                                           0 + int(alto) + 12 + 12)
        # Pico de la parte de abajo
        if self.a_derecha:
			self.imagen.pintar_parte_de_imagen(imagen, 67, 35, 33, 25,
                                           +12,#pico a la izquierda!!!!!
                                           
                                           0 + int(alto) + 12 + 12)
        else:
			self.imagen.pintar_parte_de_imagen(imagen, 67, 35, 33, 25,
                                           
                                           int(ancho) - 12,#pico a la derecha!!!
                                           0 + int(alto) + 12 + 12)


pilas.actores.vincular(Globo2)



def midecir(que_actor, texto, desplazado): #funcion decir adaptada
    if desplazado:
		nuevo_actor = pilas.actores.Globo2(texto, que_actor.x -20, que_actor.y+35,autoeliminar=False, a_derecha=True)
    else:
		nuevo_actor = pilas.actores.Globo2(texto, que_actor.x +20, que_actor.y+35,autoeliminar=False, a_derecha=False)
    nuevo_actor.z = que_actor.z - 1


mi_actor1 = pilas.actores.Mono()
mi_actor2 = pilas.actores.Mono()
mi_actor3 = pilas.actores.Mono()

mi_actor1.x = -220
mi_actor1.y = 50
mi_actor2.x = 220
mi_actor2.y = 50
mi_actor3.y = -100

def hablarmono():
    mi_actor3.decir('Texto decir normal') #funcion decir normal

midecir(mi_actor1,"Texto a la derecha", True) #(actor que habla, texto a mostrar, bocadillo a la derecha)
midecir(mi_actor2,"Texto a la izquierda", False)

pilas.tareas.siempre(3, hablarmono) #para que me de tiempo a agrandar la ventana y hacer la foto :)

pilas.ejecutar()

PD: Aunque pongo las tres tildes al principio y al final del codigo no queda bien escrito… agradeceria me explicaran como hacerlo correctamente.

Excelente @jordinur !!!, muchas gracias por compartirlo!!!

Las comillas tienen que ser invertidas, que en realidad son un tipo de comilla muy raro, en algunos teclados está arriba a la izquierda:

ah, y tienen que ser tres al principio y tres al final del código.

Creo que esas comillas son en realidad el acento “abierto” (“accent obert” que decimos los catalanes) y que se usa en muchas lenguas romance europeas. En mi caso está a la derecha de la letra P (keyb español/catalán/francés con Ñ y Ç)
Lo que pasa es que al ser un “acento” o “tilde” para que se imprima hay que pulsarlo más de una vez, así que para imprimirlo 3 veces habria que pulsarlo como 4 ó 5 veces… :cold_sweat: