Cómo introducir delay ó retardo en un bucle?

Hola! Estoy tratando de introducir un delay al estilo time.sleep(), quiero lograr algo así:

while mono.x<200:
    mono.x += 1
    time.sleep(0.01)

Funciona sin errores, pero cuando arrastro el .py al motor solamente aparece el mono en el x=200, no se ve el “movimiento”.
No quiero usar interpolaciones ni física para esto, ya que el objetivo es mostrar el uso del bucle, es posible?
Muchas gracias!

Hola @seba, no se me ocurre un ejemplo de while dentro de un juego… es muy
poco utilizando en realidad… porque dentro del juego cada bucle while va a interrumpir
el juego…

Sí se me ocurre un ejemplo para otros bucles de repetición similares, como un for, que
se puede utilizar para darle órdenes a una colección de actores:

import pilasengine

pilas = pilasengine.iniciar()

monos = pilas.actores.Mono() * 10

for indice, mono in enumerate(monos):
    mono.x = [indice * 100], 10
    mono.y = 0

pilas.ejecutar()

Pero no sé si es algo como lo que estás buscando… ¿A otra persona se les ocurre un ejemplo de while en pilas?

Hola @Seba

Cómo ha dicho @hugoruscitti; introducir un bucle en un juego, comúnmente, se interpone con el bucle principal de dibujado. Lo cual da cómo resultado que la lógica suceda, pero no el resultado visual instantáneo; sino hasta cuando el bucle ha finalizado y entonces puede continuar el bucle principal del juego.

Ejemplo:

import pilasengine

pilas = pilasengine.iniciar()

mono = pilas.actores.Mono()


def actualizar():
    while mono.x < 100:
        mono.x += .5
        # Forzamos a pintar la ventana de pilas
        pilas.widget.repaint()

pilas.tareas.una_vez(0, actualizar)

pilas.ejecutar()

Con el ejemplo de arriba; puedes mostrar el uso del ciclo while y explicar un poco el problema que comenté mas arriba; sobre los bucles anidados. Incluso introducir las facilidades que ofrece pilas para los trozos de código que han de repetirse constantemente; tareas Manejo de tiempo con tareas — pilas

Saludos !

Gracias Hugo! Elegí Pilas como lenguaje para aplicar a la escuela y estoy introduciendo las estructuras de control básicas, por eso necesitaba un ejemplo más básico, sin entrar aún en colecciones, etc., se entiende? Gracias nuevamente!

Eso estaba buscando, un repaint! Pero en la vers. 0.83 no funciona… No tengo el pilasengine ni el widget. Gracias igualmente!

Hola @Seba, te paso el link para descargar una versión más reciente, este miércoles la vamos a estar presentando oficalmente :slight_smile:

http://hugoruscitti.github.io/pilas-website-test/#/descargas

Creo que Seba estaba expresando una duda que comparto, que es la de conseguir una ejecución secuencial de las órdenes, ya que en Pilas las órdenes parecen ejecutarse simultaneamente.

Por ejemplo, si pongo:
mono.escala=[.5], 5; mono.x=[100], 3
espero ver al mono reducir su tamaño a la mitad durante 5 sg. y luego desplazarse hasta el punto x=100 durante otros 3 sg. Pero NO es esto lo que ocurre, sino que al mismo tiempo que se reduce su tamaño, se va desplazando hasta el punto x=100. ¿Se puede conseguir que esas dos instrucciones se ejecuten secuencialmente?.

Hola @Fer, para ejecutar animaciones en forma de secuencia podrías utilizar tareas:

http://manual.pilas-engine.com.ar/tareas/

Las tareas te permiten ejecutar alguna función luego de esperar una cantidad determinada de segundos.

En tu caso, podrías reducir la escala del mono, y luego de 5 segundos (con una tarea) lanzar la animación para desplazar al actor.

Por ejemplo:

# coding: utf-8
import pilasengine

pilas = pilasengine.iniciar()

mono = pilas.actores.Mono()

def reducir_escala():
    mono.escala = [.5], 5
    
def mover_a_derecha():
    mono.x = [100], 3

pilas.tareas.una_vez(1, reducir_escala)
pilas.tareas.una_vez(6, mover_a_derecha)


pilas.ejecutar()
1 Like

OK, gracias. Acostumbrado a Python, me sorprendió esta forma de trabajar de Pilas. Pero ya veo como enfocarlo. Un saludo.

Buenas noches Hugo,

Estamos desarrollando junto a mis estudiantes el videojuego pacman. Y surge el problema del movimiento de las fantasmas. Si queremos lograr un movimiento secuencial de los fantasmas, definiendo:

# coding: utf-8
import pilasengine

pilas = pilasengine.iniciar()

mono = pilas.actores.Mono()

def mover_a_derecha(pos, seg):
    mono.x = [pos], seg

def mover_arriba(pos, seg):
    mono.y = [pos], seg

pilas.tareas.una_vez(1, mover_a_derecha(100, 3))
pilas.tareas.una_vez(4. mover_arriba(100, 3))

pilas.ejecutar()

El objeto mono no se mueve de manera “secuencial”, es decir primero hacia la posición de x = 100 en 3 segundos y luego, se mueve a la posición de y = 50 en 3 segundos. El problema es se ejecuta de manera “concurrente”, y el movimiento termina siendo en diagonal!

Desde ya muchas gracias!

Buenas, @mgomez4 !

A la espera de lo que pueda decirte Hugo, me gustaria hacerte un par de consideraciones:

La primera, podrias probar con pilas.tareas.agregar() en vez de pilas.tareas.una_vez() por que creo que eso evitaria que las dos tareas se realizaran a la vez. Desgraciadamente no puedo probar el código, pero creo que eso deberia funcionar.

La segunda, que ese tipo de movimientos hacen que los fantasmas realicen movimientos previsibles… Creo que para ese tipo de juego lo ideal seria crear una serie de “checkpoints” en los que al llegar el fantasma se llame a una función pilas.azar() y que determine si el fantasma irá a derecha, izquierda, abajo o arriba. De esta forma se crearia un movimiento totalmente aleatorio e imprevisible para el jugador :smile:

No dudeis en contarnos cualquier otra duda o idea, estaremos atentos!

Un abrazo :wink:

Muchas gracias por responder @jordinur!

Tanto con pilas.tareas.agregar() y pilas.tareas.una_vez() funcionan correctamente. Por no leer la documentación de la función una_vez() estaba utilizando mal los parámetros de la misma. En el caso de que la función que queremos ejecutar tome parámetros, no se deben pasar como:

pilas.tareas.una_vez(1, mover_a_derecha(100, 3))

sino que se debe de pasar de la siguiente manera:

pilas.tareas.una_vez(1, mover_a_derecha, 100, 3)

Como se puede observar en la documentación:
def una_vez(self, time_out, function, *args, **kwargs):
“”"Genera una tarea que se ejecutará usan sola vez.

    :param time_out: Cantidad se segundos que deben transcurrir para ejecutar la tarea.
    :param function: Función a ejecutar para lanzar la tarea.
    :param params: Parámetros que tiene que recibir la función a ejecutar.
    """
    tarea = Tarea(self, self.pilas, True, self.contador_de_tiempo + time_out, time_out,
                  function, *args, **kwargs)
    self._agregar(tarea)
    return tarea

Por otro lado, la idea es trabajar de manera progresiva con el pacman, para ir incorporando los conceptos fundamentales de programación. Inicialmente, los fantasmas se moverán de manera sencilla, repitiendo secuencias. Para, luego generar movimientos no determinísticos, como recomendas! Muchísimas gracias por la respuesta!

Te mando un fuerte abrazo!

2 Likes