Haciendo CuteGodChigüire: Implementado el selector del terreno

Este artículo es la parte 3 de 4 de la serie Haciendo CuteGodChiguire: desarrollando un prototipo

CuteGodChigüire: Revision 2

La revisión 2 de CuteGodChigüire ya toma la forma de un programa interactivo. Posee un selector que sigue al mouse. Con dicho selector, puedo levantar bloques de terreno haciendo click sobre uno y depositándolos haciendo click sobre otro lugar. Esto es, básicamente, el mecanismo principal del juego. Quedaría comenzar a implementar las cosas que lo hacen un juego, como la detección de patrones, las personas que pasean, el movimiento de scroll para tener un mundo más grande.


Implementación del cursor

El trabajo principal en esta revisión fue implementar el selector que sigue al mouse. Para esto se implementaron 3 métodos en la clase World: setSelector, getMouseIntersect, y getIntersectRectangle. El primer método no hace más que establecer la posición del selector en las coordenadas del arreglo del terreno. El segundo método es el más poderoso: dada la posición del mouse con respecto al mapa retorna las coordenadas de arreglo del terreno correspondiente. Recordemos que la ventana principal tiene una superficie (representada por la clase WorldScrollView) y es en esta superficie donde se dibuja el mapa con un desplazamiento dado para hacer el scroll. Esto nos obliga a hacer dos cambios de sistemas de coordenadas para poder llegar al sistema que utiliza getMouseIntersect.

La detección del espacio bajo el cursor se realiza detectando la columna sobre la que está parado el selector (con una simple división). Luego se toma esa misma columna y para cada espacio en esa columna se toma el rectángulo que abarca todos los bloques de terreno de ese espacio con la función getIntersectRectangle. Finalmente se establece cual rectángulo está más cerca del cursor y se retornan las coordenadas de su espacio correspondiente. Se establecieron también los casos para cuando el mouse está fuera de la zona del mapa.

Acción de la mano

Luego de hacer esa parte, que dió bastante trabajo para lo poco escrito, procedí a aprender cómo funciona el modelo de eventos de Pygame, y es realmente sencillo. Una cola recoge los eventos que van lanzando los dispositivos como el mouse, el teclado o el joystick (si lo activas), y uno debe escribir un código que pase por esa cola para ir procesando cada evento. Sólo quedaba hacer una función en World que quite el bloque de terreno que esté bajo el selector y guardarlo en éste, y que deposite el bloque si el selector ya tiene uno tomado.

Conclusión

A partir de ahora queda hacer la detección de patrones para tener el mecanismo básico de juego. Sin embargo, quisiera apartar un tiempo para investigar dos cosas. La primera de ellas es trabajar con Surfarray, una clase de Pygame. Esta clase me permite acceder a los pixeles de una imagen, con lo que puedo hacer cosas muy poderosas, como modificar colores, niveles, saturación, brillo, contraste a través de técnicas totalmente conocidas. Específicamente, Surfarray devuelve los pixeles como matrices, el tipo de datos perfecto para hacer multiplicaciones de matrices, que es el fundamento de todos los cambios que les mencioné anteriormente. Escribiré más sobre eso en la próxima revisión.

La segunda de las cosas que quiero investigar es sobre las interpolaciones. En Actionscript existe una clase muy útil llamada Tween. Esta clase me permite modificar propiedades de un objeto en el tiempo con transiciones de todo tipo (suaves, lineales, fuertes, etc.). Esto permite hacer movimientos suaves de un objeto, o hacer fades con muy poco código. Creo que esto es algo que se puede implementar en Python muy fácilmente, y estoy trabajando en ello.

Mientras tanto, los dejo con el código fuente descargable en Python de esta revisión. Prometo buscar para próximas revisiones la manera de lanzar también un ejecutable para Windows.

Archivos

This website uses IntenseDebate comments, but they are not currently loaded because either your browser doesn't support JavaScript, or they didn't load fast enough.

5 Responses to “Haciendo CuteGodChigüire: Implementado el selector del terreno”

  1. Joaquin Windmüller  on Junio 16th, 2007

    Hola Chigüire,

    Te recomiendo revisar mootools (librería js) que tiene implementadas muchas funciones de interpolación basadas en esto: http://www.robertpenner.com/easing/

    Mucho éxito con el CuteGodChigüire

    Saludos

    Reply

  2. Ciro  on Junio 16th, 2007

    Epa Joaquín,

    Precisamente en Flash 8 incorporaron ese código. Supongo que en JavaScript no se iba a dar el lujo de esperar.

    No he actualizado el post, pero ya tengo listo la clase para hacer interpolaciones a cualquier objeto, tan solo me falta acomodar unos detalles para llevarlos a módulos de Python que pueda importar en cualquier lado. Vivan los generadores, es lo que puedo decir :-) .

    ¡Gracias por estar pendiente, saludos!

    Reply

  3. Joaquin Windmüller  on Junio 17th, 2007

    Ah genial, tanto leer tu blog me ha provocado escribir un juego a mi también. No es mi área pero con desarrollando un juego me inicié en la programación (aquellos tiempos de algoritmos 1 y “El Wumpus”). Capaz algún día lo porte a javascript.

    No he tenido tiempo de revisar el código que has completado hasta ahora, uno de estos días capaz lo haga. Mucho éxito.

    Saludos

    Reply

  4. Albestio  on Junio 19th, 2007

    Hola wenas,
    quiero hacer un juego en python usando pygame. Tus posts son una gran ayuda, aun que el código me tira error:

    File “CuteGod.py”, line 360, in ?
    main()
    File “CuteGod.py”, line 352, in main
    worldScrollView.setSelectorPosition(event.pos)
    File “CuteGod.py”, line 280, in setSelectorPosition
    selectorPos = self.world.getMouseIntersect(mapMouse)
    File “CuteGod.py”, line 134, in getMouseIntersect
    if any(rowIntersectsMouse):
    NameError: global name ‘any’ is not defined

    Defino any?

    ya dirás algo :wink:

    Reply

  5. Ciro  on Junio 19th, 2007

    Hola Albestio,

    Chequea que la versión de Python que estés utilizando sea 2.5 como mínimo, ya que any es una función local incluída allí.

    Reply


Leave a Reply