14 de Septiembre, 2014

»Programando para el ZX Spectrum · Lo pasé bastante bien imitando los juegos del ZX Spectrum, y me picó el gusanillo: ¿cómo sería programar un juego para el Spectrum de verdad? Pues estoy contestando a esa pregunta con un emulador (no tengo el hardware) y Z88DK; intentando una conversión de The Legend of Traxtor. Por ahora parece vialble (y ya he publicado una herramienta: png2c), así que es posible que mi juego de Octubre sea algo especial ;).

Hay 0 comentarios, anotación clasificada en: programming, speccy.

8 de Septiembre, 2014

The Accolade

Ayer acabé y entregué The Accolade, un juego que he hecho en una semana para la SpeccyJam.

La idea era hacer un juego dentro de unas restricciones técnicas para que el resultado evocara el estilo de los juegos para ZX Spectrum, incluyendo la resolución máxima (256×192), el número de colores a usar y limitaciones más complicadas como la del attribute clash (no pueden haber más de dos colores en un celda de 8x8 pixeles). Se pueden leer las reglas en la página de la jam.

Al final he conseguido entregar un juego en isométrica, en el estilo de clásicos como Hero Quest, Alien 8, Batman and Knight Lore, con una mecánica tipo rogue (aunque los niveles no son aleatórios).

El juego no es muy largo, pero dado que es primeros de mes, aún tengo tiempo para añadir más contenido antes de considerarlo mi juego de Septiembre (la publicada es versión 0.9).

Estoy muy contento con el resultado, pese a las dificultades técnicas de la jam. El juego es bastante Spectrum, aunque funcione en una máquina de escritorio moderna. Además es oficialmente mi primer RPG, que casualmente se parece bastante a aquel juego en isométrica que hice en gwbasic cuando era un crío ;).

Hay 0 comentarios, anotación clasificada en: sfml, cpp, programming, rpg, speccy.

5 de Septiembre, 2014

»The Accolade está en camino · Aunque no correrá en un Spectrum de verdad, las reglas son bastante interesantes. Debería de estar acabado este fin de semana ;).

WIP

Es una especie de RPG (bastante sencillo), centrado en exploración y combate, con tintes de rogue-like. Veremos en qué queda ;).

Hay 0 comentarios, anotación clasificada en: 1gam, programming, sfml, rpg, speccy.

24 de Agosto, 2014

»DUAL Adventure · No he podido acabar lo que quería hacer (que la verdad era demasiado ambicioso), pero he subido DUAL Adventure como mi entrada para LD30. Lo de las 48h sigue sin encajarme, especialmente cuando se lía el fin de semana y no puedo dedicar todo el tiempo que me gustaría. Además es mi juego de Agosto para mi reto de un juego al mes, aunque no está completo (he aprendido muchas cosas sobre cómo funcionan los juegos de plataformas, con lo que lo considero un éxito pese a todo).

Hay 0 comentarios, anotación clasificada en: 1gam, javascript, programming.

20 de Agosto, 2014

»Resultados de gbjam 3 · The Legend of Traxtor, mi juego de Julio, ha quedado en puesto #21 de un total de 248 juegos. Se pueden ver los resultados de la votación en la página de la jam. Nada mal para un juego hecho en un par de días ;).

Hay 1 comentario, anotación clasificada en: 1gam, programming.

18 de Agosto, 2014

»¡Demasiadas Jams! · La verdad es que las game jams tienen mucnas cosas positivas. A mi me han ayudado a acabar juegos, que de otra forma nunca hubiera acabado. Además he aprendido muchas cosas y he mejorado mis habilidades en poco tiempo. Pero es que ahora están en todas partes, ¡hay demasiadas! Por ejemplo, las que lista CompoHub. Hoy esa web registra 6 en marcha, y eso que no están todas las que hay :o.

Hay 0 comentarios

12 de Agosto, 2014

»The matasano crypto challenges · Hice este reto vía email hace un tiempo, y es muy interesante. Me quedé atascado (perdí el interés) en el tercer bloque, pero puedo asegurar que es una de esas cosas que cuando las haces te da super-poderes ;). Yo utilicé Python y creo que fue buena idea (por el batteries included), pero en teoría cualquier lenguaje de programación puede valer.

Hay 0 comentarios, anotación clasificada en: programming.

10 de Agosto, 2014

Reproduciendo música en bucle en SFML

En SFML 2.1 tenemos una clase específica para reproducir música de fondo: sf::Music.

Su principal característica es que permite reproducir grandes ficheros haciendo streaming desde disco, con lo que no es necesario tener todo el fichero en memoria. Esto contrasta con sf::Sound, que se utiliza para sonidos en los que no puede haber latencia (se reproducen inmediatamente), y por lo tanto se almacenan en memoria.

Esta distinción está prensente en la mayoría de las librerías que he usado, aunque no siempre se utliza un interfaz diferente (por ejemplo, en pyglet es solo un parámetro en las funciones que cargan los ficheros de audio).

La clase sf::Music es bastante útil, pero le falta una funcionalidad que tampoco está disponible en muchas librerías, pero que en SFML me ha costado bastante implementar :(.

Un requerimiento frecuente cuando se reproduce música de fondo es que el fichero de audio tenga dos partes: la introducción y el cuerpo del bucle que se repite una vez la introducción ha terminado.

Hay distintas formas de implementar esto. A veces es más sencillo partir la música en dos ficheros y reproducir la segunda parte en bucle una vez la primera ha terminado, otras veces es mejor especificar el punto desde el cual el audio debe repetirse.

Para el primer caso normalmente es necesario que la librería nos permita usar un callback cuando un fichero de audio termina de reproducirse (este sistema lo uso en Javascript y Python), el segundo se puede implementar de diferentes formas, pero básicamente se trata de empezar la reproducción en un punto x en lugar de 0.

SFML utiliza un thread para reproducir el audio de forma que nuestro programa nunca se bloquee esperando operaciones con el audio. Esto en general es una buena idea, pero el sf::Music no proporciona opciones para comunicar los dos hilos de ejecución: el que corre nuestra aplicación y el que reproduce el audio. Lo mejor que tenemos en sf::Music es onGetData y onSeek; ambos ejecutados en el hilo que reproduce el audio.

La solución que he implementado en The Legend of Traxtor es la siguiente:

#include <SFML/System/Time.hpp>
#include <SFML/System/Mutex.hpp>
#include <SFML/System/Lock.hpp>
#include <SFML/Audio/Music.hpp>

class ExtMusic : public sf::Music
{
public:
    ExtMusic() : m_ext_loop(false) { }

    void setLoopOffset(float offs) {
        sf::Lock lock(m_ext_mutex);

        m_offs = sf::seconds(offs);
        m_ext_loop = true;
    }

protected:
    bool onGetData(SoundStream::Chunk &data) {
        sf::Lock lock(m_ext_mutex);

        bool result = sf::Music::onGetData(data);
        if (!result && m_ext_loop)
        {
            onSeek(m_offs);
            if (!data.sampleCount)
                sf::Music::onGetData(data);
            return true;
        }

        return result;
    }

private:
    sf::Mutex m_ext_mutex;
    sf::Time m_offs;
    bool m_ext_loop;
};

La idea de la clase ExtMusic (que extiende la clase sf::Music) es indicar desde qué segundo queremos que se repita el audio, y la reprodución saltará a ese punto en el fichero una vez nos quedemos sin datos para reproducir.

Además hay que usar un Mutex para garantizar el acceso exclusivo a los datos porque setLoopOffset se llamará desde un hilo que es distinto al que llamará a onGetData.

Se supone que SFML proporciona sf::SoudSource para que implementemos nuestras propias historias para reproducir audio, pero en mi caso era mucho más sencillo aumentar la funcionalidad de sf::Music que liarme con un interfaz de más bajo nivel como el que proporciona sf::SoundSource.

Al final el resultado es algo hacky (e incompatible con los bucles normales), pero bastante simple. La buena noticia es que alguien ha contribuido una implementación de bucles con punto de inicio, con lo que futuras versiones de SFML ya no tendrán esta limitación ;).

Hay 0 comentarios, anotación clasificada en: cpp, sfml, programming.

6 de Agosto, 2014

Sobre distribución

Ya he sobrepasado la mitad del reto de programar un juego al mes (durante el 2014), con 7 juegos. Si añadimos los que había hecho antes del empezar el reto, tengo una buena muestra para analizar.

He trabajado con diferentes lenguajes de programación y diferentes frameworks o librerías, y he probado distintos modelos de distribución, así que voy a comentar aquí algunas conclusiones.

Lenguaje Framework Linux Windows Mac Otros
C SDL 1 Fuente Binario Fuente SDL es muy portable
Python PyGame Fuente/Paquete Binario1 Fuente n/d
Python pyglet Fuente/Paquete Binario1 Fuente/Paquete2 n/d
Javascript Canvas 2D + SoundJS Navegador Navegador Navegador Necesita aceleración hardware
C++ SFML Paquete Binario3 n/d4 Soporte para Android en desarrollo

Notas:

  1. py2exe requiere una máquina con Windows para empaquetar.
  2. Empaquetado como un egg, distribución binaria de AVBin y usa la versión de python 2 instalada en el sistema.
  3. Cross-compiling en Linux, probado con Wine. No hace falta una máquina Windows.
  4. Por ahora un Mac es necesario.

Esta tabla antiende únicamente a la distribución, y en ese aspecto Javascript es la mejor opción, aunque no es cualquer navegador porque la aceleración hardware no está disponible en todas partes. No tiene en cuenta lo fácil o difícil que es el desarrollo o mis preferencias como programador (importante para mi: encuentro más satisfactorio programar en python que en javascript :P).

Además está la estabilidad de la plataforma. Por ejemplo, el resultado con Javascript es bastante variable (depende de la versión del navegador y de si tenemos aceleración en canvas), y en general es más difícil conseguir buen rendimiento. pyglet utiliza OpenGL y aceleración por hardware, y es más autocontenido que PyGame, pero este último es más estable y en general está mejor soportado (gracias a que usa SDL).

Distribuir el código puede ser la mejor opción si el juego acaba incluído en una distribución, pero entre ciclos de desarrollo y procedimientos pueden pasar muchos meses antes de que se obtengan resultados (y es posible que el juego nunca llegue a ninguna distribución).

En el caso de SDL con Dodgin Diamond 2 se puede comprobar que publicar el código fuente permite que el juego sea portado a plataformas que de otra manera sería imposible soportar. En general los ports respetan la licencia, aunque en este caso no lo considero demasiado importante.

Por ahora estoy centrándome en resultados inmediatos, sobretodo cuando se trata de una game jam, que se traduce en: el juego debe funcionar en Windows, luego Linux (porque puedo y porque me resulta fácil, no por el número de usuarios), y si es posible y con muy baja prioridad... Mac.

Hay 0 comentarios, anotación clasificada en: programming, 1gam.

4 de Agosto, 2014

The Legend of Traxtor

Ayer publiqué mi juego para Julio dentro del reto one game a month: The Legend of Traxtor.

Se trata de un juego tipo puzzle match-3 en el que controlas una nave (legendaria, claro que sí :D) que puede mover bloques buscando hacer coincidir al menos 3 iguales antes de que los bloques llegen a su linea de defensa al final del tablero.

The Legend of Traxtor (gameplay)

Aunque el planteamiento es bastante diferente, tiene muchos puntos en común con mi juego de Junio (Zooooop! es otro match-3), y creo que Traxtor es más divertido.

Además he aprovechado para participar en gbjam 3 (aquí está mi entrada), que es una game jam en la que hay que recrear (mas o menos) la apariencia de los juegos de Game Boy, esto es: resolución de 160x144 y solo 4 colores.

Sorprendentemente la limitación de los colores la he llevado más o menos bien (no es que sea un artista, así que no he echado de menos tener más colores :P), pero el tamaño de pantalla ha sido un problema a veces (¡no cabe casi nada!).

He repetido con C++ y SFML, que le voy cogiendo el tranquillo. La verdad es que no era mi intención repetir género, pero me lie un poco con otro proyecto que no pude terminar en Julio así que este juego ha sido de emergencia, desarrollado en unos 3 días durante las 96 horas de gracia permitidas para acabar el juego de cada mes (con la suerte de que me ha permitido participar en la #gbjam que empezaba en Agosto).

Por ahora hay binarios para Windows en la página del juego, en los próximos días intentaré empaquetar el juego para Ubuntu Trusty al menos.

Actualización: he publicado paquetes para Ubuntu Trusty en la página del juego.

Hay 0 comentarios, anotación clasificada en: 1gam, sfml, programming, cpp.

Entradas antiguas