2 preguntas en un hilo

Buenas, lo siento por esto, pero es que tengo 2 cosas que preguntar completamente diferentes, bueno, voy a decirlos:

  1. ¿En qué está programado Pilas Engine 2? Es que me da curiosidad

  2. Me ha llamado la atención la función que tiene Pilas Engine sobre la posibilidad de hacer una función update, lo que me llama la atención es que se llama como si estuviera programando una función nueva, pero no, no se si me explico, voy a colocar una imagen sobre lo que digo:
    image
    , o sea, ¿cómo funciona eso? si alguien me lo podría explicar, por favor, que sea en Python.

Aca esta la página de la API documentada pero aun no funciona
https://app.pilas-engine.com.ar/#/api

Aca tendrías que poder ver la API de Pilas Engine.y verificar como esta construido cada cosa, pero es un quilombo verlo directamente en el código fuente de motor.

Por lo que veo el método updatet forma parte de la clase escena.
Screenshot_4

Pilas Engine se maneja con Escenas y el método Update pertenece a esa clase.

El update es un “bucle” que se ejecuta 60 veces por segundo.
se usa para mover personajes o cosas por el estilo

Por lo visto hugo ya esta prepando el editor para poder ir a la clase directamente, pero aun no funciona…
Tendrias que comprender Typescript y javascript para poder programar con Pilas Engine, aunque sea de manera Básica.
Los conceptos de programación entre python y Typescript son muy parecidos, solo cambia el lenguaje, osea la forma de escribir el código…

2 Likes

Sí, eso ya lo sé, lo que pasa es como Hugo Ruscitti y demás programadores hayan hecho cosas así, por ejemplo, como ha creado el programador de Love2D que con crear una función llamada update se actualice 60 fps por segundo, si alguien sabe, por favor, que me lo explique por Python.

¡Hola!, ¿Cómo están?!!!

Como menciona @kone9, pilas está programado en TypeScript (que es muy parecido a JavaScript) y también usa un par de bibliotecas extra, por ejemplo, para crear componentes y la interfaz del editor estoy usando emberjs y para dibujar en pantalla, colisiones, audios y todo lo demás dentro del juego uso phaserjs.

La versión anterior de pilas sí estaba realizada en python, y usaba algunas bibliotecas externas también como qt (para dibujar y hacer la interfaz visual).

De hecho, hubo una versión aún más vieja de pilas que usaba pygame y python. Esa versión fue la primera de todas, y si bien no tenía un editor se podía programar con un editor de textos externo.

En su momento escribí algo sobre la historia de pilas y varias cosas que aprendí en el trayecto en mi blog: ¡Comenzamos Pilas Engine 2! :: Examplelab — Mi blog igual no te quiero aburrir jejeje, por ahí tu pregunta iba por otro lado, ya nos dirás!

Con respecto a tu otra pregunta, sobre la función “actualizar”, me imagino que lo que estás buscando es lo que se llama “mainloop”. Esta es una idea que está presente en cada uno de los motores de juegos: para que un juego pueda mostrar que los “objetos se mueven”, se necesita estar dibujando una y otra vez la pantalla. Así que se suele crear un bucle que espere una fracción de segundo (1/60 segundos o algo así), luego se recalculan posiciones de personajes, se lee un instante el estado del teclado y por último se vuelve a dibujar.

Aquí hay un artículo (bastante viejo) en donde se muestra la idea del “main loop” y como usarlo dentro de un juego: http://losersjuegos.com.ar/referencia/articulos/bucle los ejemplos están en el lenguaje C, pero igualmente creo que vas a poder tomar algunas ideas.

Creo que si buscas mainloop en youtube u otros sitios de desarrollo de juegos seguramente vas a llegar a ejemplos puntales en python.

Igualmente, se me ocurrió mostrarte cómo se podría crear un mainloop muy simple (aunque algo feo) usando python y un bonito auto en ascii art:

(usé algunos tildes, así que vas a tener que ejecutarlo con python 3 en adelante)

import time

contador = 0

auto = """"
     .--------.
____/_____|___ \___
O    _   - |   _   ,*
'--(_)-------(_)--'
"""

# Dibuja un auto pero poniendo espacios a la izquierda.
def dibujar_auto(posicion_x):
    # Toma el auto y lo separa en lineas, luego imprime
    # cada linea con un margen para que parezca que el
    # auto está moviéndose a la derecha.
    for x in auto.split("\n"):
        print(" " * posicion_x + x)

# Dibuja una auto moviendose a la derecha.
while True:
    time.sleep(0.016) # 1/60 segundos aprox

    # antes de esta linea sería ideal poder limpiar
    # la pantalla, sino van a aparecer muchos autos.

    # dibuja el autor en la posición que diga el contador.
    dibujar_auto(contador)
    contador += 1

    # cuando llega a la derecha de la pantalla vuelve
    # a empezar.
    if contador > 50:
        contador = 0

y cuando lo ejecutes te va a quedar algo así:

2021-08-18 7xdmr

Claro, no es lo más lindo del mundo… pero dibujar en una consola con ascii art es más difícil de lo que parece. Es más, te diría que si estás usando python te conviene mirar pygame o alguna herramienta que te permita abrir una ventana y dibujar usando píxeles. La idea es la misma, vas a tener que crear un bucle tipo while True y dentro de ese bucle procesar, dibujar y esperar.

Ah, por cierto, no se si te sirva para seguir investigando (o no), pero hace algunos años había hecho este video mostrando detalles internos de pilas: cómo hacerle cambios y esas cosas.

¡Si te sirve avisanos!, al final escribí mucho pero en este punto estoy en duda si entendí tu pregunta o agarré para otro lado.

Sí sí, muchas gracias por vuestras respuestas pero no es lo que necesito, lo que me interesaría ver es cómo funciona el mainloop de las librerías para videojuegos, por ejemplo, pilas.ejecutar(), o en Pilas Engine 2, o Love2D, me refiero a que el programador que use la librería para hacer el mainloop solo tiene que crear una función, como si fuera nueva, pero con el nombre update o el programado, lo que quiero saber es cómo funciona la librería para que si detecta una nueva función llamada update la librería haga un mainloop, perdón por las molestias

Me refiero a algo así:

Ahhh, creo que ahora te entiendo…

Yo me imagino que el mainloop recibe un objeto, y trata de ver si ese objeto tiene un método update y lo invoca. Por ejemplo, un motor de juegos podría tener un código como este (en python):

juego = Juego()

# mainloop del motor de juego
while True:
   juego.update()
   juego.draw()
   time.sleep(0.016)

Entonces, como programador, uno no tiene que tocar el mainloop del motor del juego, sino crear una clase Juego e implementar los métodos “draw” y “update”.

class Juego:
 
    def update(self):
        print("mi metodo update")

    def draw(self):
        print("Dibujar en pantalla")

Otra variante, podría ser que el main loop llame a métodos teniendo cuidado de que el método realmente existe con la función getattr. Por ejemplo si se produce una colisión:

juego = Juego()

# mainloop del motor de juego
while True:

   if se_produce_una_colision():
      # consulta si existe un método llamado "cuando_se_produce_una_colisión"
      # y si existe lo llama.
      if getattr(juego, "cuando_se_produce_una_colision", None):
         juego.cuando_se_produce_una_colision()

   juego.update()
   juego.draw()
   time.sleep(0.016)

Es decir, si el mainloop tiene una referencia al juego, puede llamar métodos dentro del juego (métodos que escribe quien usa el motor) y a su vez detectar si hay métodos nuevos o no.

En el caso de las funciones que pusiste en love (que está hecho en el lenguaje Lua por lo que veo) el concepto es parecido. Cuando se define una función como “love.draw”, es como si se estuviera creando una función e insertándola dentro del objeto “love”. Es decir, es como si en python hicieramos algo como esto:

def mi_funcion_dibujar():
    print("dibujar")

juego.dibujar = mi_funcion_dibujar

pero en lua se ve mucho más lindo.

Muchas gracias de verdad Hugo, llevaba buscando algo así, muchas gracias, Pilas Engine me ha inspirado en continuar una librería que intenté hacer hace unos meses, casualmente también escrito en Pygame :eyes:

1 Like

Perdón por hacer tantas preguntas, pero me he quedado con la duda, la versión anterior a 1 de Pilas, me dijiste que usaba Pygame, pero lo que me llama la atención es que para el mainloop alguien solo tenga que usar pilas.ejecutar() y los demás cosas vayan antes que eso, sin tener que estar dentro de ningún if for o cualquier función, ya que en Pygame las cosas como añadir imágenes y demás van dentro del mainloop, ¿cómo funciona para que añadir imágentes no tenga que estar dentro del mainloop? no se si me explico, en Pygame es hacer un mainloop y el teclado, imágenes y demás dentro de ahí, pero, en tu librería, las imagenes y teclado no va dentro de nada y el mainloop es solo pilas.ejecutar(), o sea, como hacer para que el programador que use la librería solo tenga que hacer eso y no lo demás

Hola @Rintri !!!, no se si entendí muy bien tu consulta, pero de todas formas trataré de comentar algunas cosas que te podrían orientar.

El main loop, en el caso de pilas, en realidad está invocando a tú código. Así que vas a poder intervenir y hacer cosas como cargar imágenes o cambiar objetos porque el main loop no hace otra cosa más que ejecutar funciones por su nombre, es decir, lo que haga la función dentro ya es algo que vos podrías cambiar.

Formalmente, eso se llama inversión de control, no se si el link que pongo está bueno o no, pero si buscas ese término (inversion of control) seguramente te va a orientar. La idea detrás de la inversión de control es que el “motor del juego” llame a tu código en lugar de que vos lo llames a el.

Otro recurso que te puede servir es un artículo que escribí cuando estaba empezando a hacer que pilas funcione en modo interactivo, es un artículo difícil de leer pero igual te lo paso por si te sirve para el proyecto que estás haciendo.

Y por cierto, ¡no te disculpes por las preguntas!, ¡está buenísimo que preguntes!, estoy aquí para ayudar en lo que pueda.

¡Abrazo!

Busca el libro en pdf “desarrollo-de-videojuegos-enfoque-practico-vol-1” ahi te explican los conceptos de un motor de videojuegos, pero es en C++… Busco conceptos sin importar el motor ni el lenguaje

1 Like