[pyar] ¡Invasores del espacio!(era: juegos, IOC, blah)

Top Page
Attachments:
+ (text/plain)

Reply to this message
Author: Daniel F Moisset
Date:  
To: pyar
New-Topics: Re: [pyar] ¡Invasores del espacio! (era: juegos, IOC, blah)
Subject: [pyar] ¡Invasores del espacio!(era: juegos, IOC, blah)
OK, después de una semana movidita junte los ratos suficientes para hacer
mi versión de space invaders con el framework que proponía; el framework y
el juego están en
https://beetroot.except.com.ar/publicsvn/python-cooperative-multitasking/trunk/

Algunas aclaraciones primero:
* La solución que puse no tiene que ver nada con mónadas; lo que estoy
haciendo es concurrencia cooperativa. Es decir, como tener un thread por
cada elemento del juego (jugador, cada disparo, enemigo). Lo de las
mónadas se fue porque implicaba armar un sublenguaje, y a Lucio no le
gustaba (a mi en realidad no me molesta).
* la parte de cooperativa hace que no haya que calentarse por locks, y
race conditions y esas cosas.
* Algunas cosas del framework son sucias (más en el sentido de
implementación que de API) porque lo hice de la forma rápida. En
particular la emision de señales es poco eficiente. Para el ejemplo que
hice, no se nota ni un poquito
* Algunas partes del framework son sucias a nivel API por falta de cosas
en Python2.4; usar Python2.5 me hubiera salvado de un par, pero no tengo
un 2.5 tan a mano.
* Algunas partes del framework son sucias a nivel API por un par de
problemas de diseño de python (como son los generadores) sobre lo cual
voy a rantear más tarde.
* Algunas partes del jueguito se pueden simplificar o refactorear;
quedaron algunas partes desacomodadas y repetidas porque lo hice apurado,
y porque estaba jugando un poco con la metodología de hacer juegos así...
con lo cual cuando había cosas parecidas para hacer, probaba todas en
distintos lugares del juego :) Eso hace que se aprenda más, pero que
quede menos consistente/legible.

El juego en si esta bastante completo; le falta scoring, y pantallas de
principio, fin(ganaste), fin(perdiste), tabla de scores, menu,
transiciones de nivel, que quedan como ejercicio para el lector. Los
gráficos son horribles, ya los voy a cambiar robando de por ahí.

Mis conclusiones de laburar con el bicho este son:

1) La lógica en general me pareció más simple/limpia (que era la meta
original), así que el experimento me pareció bastante exitoso. Se eliminan
los pedacos donde uno tiene que fragmentar la logica y traducirla a flags
en un manejador de eventos (diseñe varias cosas del juego para necesitar
esas cosas explicitamente, por ejemplo el secuenciado de escenas, o el
ratito que el jugador esta "stunned" después que le pegan).

2) Para algunos elementos del juego, la lógica realmente tiene la forma de:

while 1:
e = evento()
if e.tipo == "A": manejar_evento_tipo_A()
elif e.tipo == "B": manejar_evento_tipo_B()
else e.tipo == "C": manejar_evento_tipo_C()

Esa es la lógica que te fuerza la forma usual de IOC; para bichos de esta
forma, usar un framework como el mío o no al final da lo mismo. En el caso
del space invaders, el jugador es bastante así.

3) Incluso cuando pasa lo anterior una ventaja de escribirlo (lo=algo como
el jugador con la lógica clásica de manejo de eventos) en la forma en que
estoy proponiendo, es que se modifica de forma bastante natural cuando uno
tiene que hacer cambios de lógica que rompan el esquema.

Por ejemplo, al principio mi jugador resucitaba instantaneamente (con una
vida menos) cuando lo mataban. Tenía todo el esquema de un event loop
clásico. En un momento decidí que cuando le peguen, desaparezca y no sea
controlable por un instante, antes de reaparecer al medio de la pantalla.
en el manejador de ticks, agregue:

if self.stunned:
# sleep for some ticks
c.connect(tick)
for t in range (25): yield c # Esperar un tick
self.stunned = False

Sin el framework, tendría que tener t como una variable de estado del
objeto jugador, no podría hacer el for de forma tan directa (sino que
tendría que manejar el contador a mano), y tendría un if grandote
alrededor de mi manejador de tick.

4) En un principio tuve miedo de tener que pelearme con el orden en que se
schedulean los hilos de ejecución, y el orden en que se reciben las
señales. Sorprendentemente programe todo sin calentarme (a ver con que me
encontraba), y en ningun caso me trajo problemas.

Por otro lado, sé que si quisiera controlar algunas cosas (por ej. el
layering de gráficos) tendría que manejar un poquito de eso (o
alternativamente, para el ejemplo anterior, hacer un hilo aparte de
dibujado, en vez de controlar los dibujos en cada objeto, cosa que resulta
muy simple y piola).

5) No se ve en el código, pero el proceso de armar el juego fue bastante
natural, agregando cosas por cada feature en vez de tener que irlas
intercalando en los manejadores de eventos. Eso suma.

6) Lo que menos me gusta es no poder construir abstracciones alrededor de
un yield

7) No tengo idea como andará en eficiencia lo que hice para cosas más grosas

8) La forma en que hago señales es un poco rara (más parecida a condition
variables que a colas de mensajes). Hacer algo más del estilo de colas, y
un manejo un poco más limpio creo que ayudaría; tambén hacer matching de
eventos. Igual para el caso de estudio mío, lo que hay alcanzaba más que
bien

OK, los dejo jugar y me cuentan que piensan

Saludos,
D.


---------------------------------------------------------------------
Para dar de baja la suscripción, mande un mensaje a:
   pyar-unsubscribe@???


Para obtener el resto de direcciones-comando, mande un mensaje a:
pyar-help@???

PyAr - Python Argentina - Sitio web: http://www.python.com.ar/