Programando Tetris con DragonRuby
Publicado el 11 de marzo de 2024En octubre de 2016 me dispuse a aprender a programar videojuegos con Ruby usando la biblioteca Gosu. Siempre me gustó el juego Tetris y me pareció un buen ejemplo como primer proyecto. Es relativamente simple como para llegar al punto de declararlo "terminado" sin sentirme abrumado. En el proceso, podía aprender lo suficiente de las herramientas como para tener una idea mínima para arrancar algo nuevo.
Todavía tengo el código que escribí en ese momento. No es buen código, pero dado que lo escribí para experimentar y aprender, no lo juzgo tanto. Conseguí recursos gráficos libres de internet, y en menos de 200 líneas de código logré esto:
No es gran cosa, pero en su momento me voló un poco la cabeza poder mover piezas con un gamepad y ver que el código que había escrito se traducía en cosas tan gráficas. Acostumbrado a tanta programación backend y web, esto era novedoso. Si bien había experimentado con PyGame y otras cosas antes de esto, me animaba la idea de programar con un lenguaje que me gusta y conozco tanto como Ruby. De todas formas, el experimento no pasó mas de eso.
Mi historia con el desarrollo de videojuegos siguió de forma bastante infrecuente. Recientemente hice un par de cursos con Godot, que me parece una herramienta genial para desarrollar videojuegos, y poca cosa más. Pero siempre mantuve el tema en la cabeza y hasta empecé un cuaderno donde voy anotando ideas de cosas que se me ocurren para desarrollar en juegos.
En algún momento de mi carrera me enteré de la existencia de DragonRuby, otra biblioteca para desarrollar videojuegos con Ruby. Amir Rajan, el fundador y uno de los desarrolladores de DragonRuby, publicó un juego hecho con DR en Nintendo Switch. El hecho de que pudiera usar Ruby y éste último dato me motivaron para conseguir una licencia. Teniendo las herramientas, era cuestión de tiempo que me pusiera a aprender a usarlo y empezara a desarrollar mis juegos, ¿no? Bueno, sí, pero demoré un rato.
DragonRuby no es gratuito, pero tiene un precio bastante accesible y se vende a precio de descuento muy frecuentemente (algunas veces se consigue gratis por alguna promoción o game jam). Encima de eso, hay muchos factores que permiten obtener una licencia gratuita: ser menor de 18 años, estudiante de cualquier tipo, quieres enseñar a alguien a programar, y más. O simplemente se puede escribir un correo electrónico a Amir explicando por qué quieres una licencia gratis y te la va a otorgar.
Amir tiene la costumbre de usar una frase "now build a game dammit" (algo así como "ahora crea un juego maldición"). Cada vez que leía esta frase, ya fuera en el Discord del proyecto o en Mastodon, me sentía un poco mal... Un día que tuve libre en el trabajo recientemente decidí poner en uso esa licencia de DragonRuby que había obtenido hace tiempo, y hacer un juego. Había visto que Ryan C. Gordon (@icculus) - desarrollador de SDL, portador de muchos juegos a Linux, entre otras cosas- tenía un tutorial para desarrollar Tetris con DragonRuby. Así que ese dichoso día me fijé el objetivo de seguir el tutorial, y lo conseguí. Ya tenía los recursos gráficos de mi primer intento con Gosu, era hora de darle vida a una versión más de Tetris.
Programar con DragonRuby fue sumamente divertido. Me hizo acordar por qué me resultaba tan divertida la programación, algo que no me pasaba desde hace bastante tiempo. Por primera vez en muchos años, volví a quedarme despierto hasta tarde programando. No tengo la más mínima idea de programación de videojuegos. No conozco los patrones, o las buenas prácticas y tenía básicamente cero experiencia. Se me ocurre algo que quiero que pase en el juego, y tengo que pensar de cero cómo se podría implementar en el contexto del framework. Esto me forzó a pensar en soluciones totalmente nuevas para mí, expandir mi creatividad y salir de mi zona de confort. Esa sensación de descubrimiento y resolución de problemas me resultó casi como una droga!
DragonRuby tiene unos principios fundamentales atados a GTK:
- El juego corre en una función principal
- que se ejecuta 60 veces por segundo
- y tiene que decirle a la computadora qué dibujar cada vez
El "Hola Mundo" de DragonRuby se ve así:
def tick args args.outputs.labels << [580, 400, '¡Hola mundo!'] end |
Esa función se va a ejecutar 60 veces por segundo (¡60fps!), así que hay que programar todo en relación a eso y ese paradigma es totalmente distinto a lo que acostumbro a programar. La lógica del juego, los menúes, interacciones y demás, van todo por esos 60 ticks por segundo. Una vez que esto hace clic en la cabeza, se empieza a pensar en relación a eso y ya las ideas van mutando a formas de implementarlas en base al tick.
Empecé a usar mi cuaderno donde anotaba ideas (y apuntes de cosas que aprendía) para desarrollo de videojuegos como agenda. Inicialmente le agregué algunas cosas simples al juego base del tutorial:
- Niveles - Cada 10 líneas se sube de nivel, lo que acelera un poco la caída de las piezas.
- Apariencia - El tutorial nos enseña cómo dibujar sólidos en la pantalla, que los cambié por sprites que conseguí en OpenGameArt, así como el fondo y otros detalles más. La animación inicial de los bloques del título en base a funciones matemáticas me divirtió mucho!
Prácticamente todos los días desde que empecé el proyecto dediqué aunque sea unos minutos después del trabajo o antes de acostarme para agregarle al código. Fui agregando varias cosas más: Pantalla de inicio con menú de opciones, efectos al hacer dobles, triples o tetris, pausar el juego, créditos, ayuda, pantalla completa opcional, y más ajustes. Corregí unos errores de colisión, aunque hay un bug todavía al momento de rotar piezas que necesito arreglar.
Para la música, usé el editor de música de GB Studio, un entorno de desarrollo de videojuegos para Game Boy. La breve melodía que se escucha al iniciar el juego es el resultado de aprender a usar la herramienta con ensayo y error en unos minutos, metiendo las notas a mano de oído hasta tener algo relativamente aceptable. La canción deja que desear, pero probablemente en algún momento le dedique algo más de tiempo como para tener una versión más decente de Korobeiniki, la canción folclórica rusa en la que está basada el tema de Tetris.
DragonRuby hace súper fácil la publicación en itch.io, así que agregué a mi cuenta el perfil de "desarrollador" y subí mi versión de Tetris en este enlace. Empecé con el nombre "Picando Tetris", pero no tengo idea si eso podría traerme problemas por usar un nombre registrado. Otras versiones tuvieron el nombre código "Picandotris", hasta que un amigo me sugirió "Fertris" (Fernando's Tetris!) y ahí quedó porque nombras cosas es difícil. Se puede descargar gratis para Linux, RaspberryPi, Mac OS y Windows. Si la llegan a probar, cuenten qué tal anduvo.
El resultado final se ve algo así:
No creo que comparta el código porque si lo ve un desarrollador de videojuegos profesional me va a mandar preso. Hablando en serio, es un código para experimentar y aprender y no creo que nadie más que yo pueda beneficiarse mucho de él.
La experiencia de agregarle cosas al Tetris de icculus queda, y además de haberme divertido, es una de las tantas cosas que aportan a mi experiencia como programador. Pero por sobre todo, ¡me divertí! Si ya sabes Ruby y te interesa, te recomiendo leer más sobre DragonRuby y empezar a hacer juegos. Y si bien ya no me voy a sentir mal cada vez que lea a Amir pidiendo que haga juegos, todavía tengo que arrancar uno propio de cero. La parte más difícil de Tetris es la lógica del juego, y eso lo hizo todo icculus en este ejemplo. Además Amir ya me dijo "seguí haciendo juegos maldición", ¡ya vendrán otros proyectos!
Siempre me ha interesado la idea de desarrollar mi propio videojuego, pero no sé si cambiaría mi carrera como para dedicarme a eso a tiempo completo. Es un tema que me interesa mucho, y me fascinan los distintos procesos creativos que se involucran: programación, diseño, arte, sonido. Pero sí me encantaría poder publicar varias de las ideas que tengo como videojuegos en algún momento. El tiempo que pasé programando y experimentando con DragonRuby se me pasó volando. Así que por lo menos para mantener esa sensación de programar cosas divertidas, espero seguir desarrollando juegos como pasatiempo.
3 comentarios en este post
Feed de comentarios-
Family 76 en 1 | Picando Código |
28 marzo. 2024 - 09:42
[…] pieza con el ritmo de la canción. En esta versión de Tetris basé los colores de las piezas en mi Tetris. Más adelante me familiaricé con la canción más popular de Tetris, Korobeiniki, en el Game Boy, […]
grilix 12 marzo. 2024 - 11:03
Fa, cómo estoy para hacer un servidor para algún juego!
En lo poco que he visto, una vez que entendés más o menos cómo hacer un juego (principalmente lo que decís de pensar en ticks), lo podés trasladar a otros lados y es parecido. Hay que explorar ideas y hacer muchas pruebas chiquitas para ir practicando!
Esperemos ver nuevas aventuras y que nos lleguen más aprendizajes.
Fernando 21 marzo. 2024 - 07:56
Sí, creo que una vez que te acostumbrás a pensar en ese paradigma, se puede trasladar a otros lados. Estoy en eso ahora, haciendo un montón de pruebas y experimentos para ir aprendiendo y agarrándole la mano. ¡En algún momento seguro lo publique!