Home »

Tutorial de Patapang (IV): empezamos a jugar

Hasta ahora hemos aprendido un montón de conceptos de Godot haciendo nuestra escena de menú. Pero seguro que estás deseando empezar a jugar. Así que ¡manos a la obra!

Para esta parte del tutorial necesitaremos algunos recursos gráficos adicionales, bien ordenados en sus directorios de recursos:

resources/images/bg/0.png
resources/images/gui/fx.png

Puedes poner directamente el proyecto en este punto desde esta rama de git: https://gitlab.com/pablo_alba/patapangtutorial/-/tree/step12

Escena de juego

Lo primero que vamos a hacer es crear una escena nueva. Para ello usa el menú Scene / New Scene. Elige 2DScene, y renombra el nodo raíz de esta escena como “Play”.

A continuación, añádele un nodo “TextureRect”, renombralo como “Background”, y ponle como textura el fichero “resources/images/bg/0.png”. Guarda con Ctrl + S, y graba la escena con el nombre que te propone: “Play.tscn”.

Como ya sabes, puedes ejecutar el juego con F5. Eso lanza la escena principal. Pero también puedes lanzar la escena actual con F6. Si lo pruebas ahora, verás que se te abre una pantalla que solamente tiene la imagen de fondo que hemos definido.

El suelo

Ahora vamos a añadir una pieza básica de este juego: el suelo. En Patapang el suelo tiene un papel fundamental. Por ejemplo, es necesario detectar la colisión de las burbujas con el suelo para rebotar, o cuando caigan “powerups” deben quedar apoyados en el suelo.

Una de las ventajas de utilizar Godot es que resuelve por ti un montón de problemas complejos (y muy comunes) en los juegos. Y uno de los principales es la detección y gestión de colisiones. ¿Cómo sé que un elemento ha tocado a otro? ¿Cómo evito que los objetos se atraviesen entre sí al moverse? Todo esto se puede programar desde cero, o podemos ahorrarnos mucho trabajo tedioso y dejar que Godot lo haga por nosotros.

En este caso vamos a utilizar un nuevo tipo de nodo de Godot llamado “KinematicBody2D”. Que no te asuste el nombre, no es nada muy complejo. Se trata de un elemento estático (no le afectan cosas como la gravedad), que puede interactuar (colisionar) con otros elementos.

Así que el primer paso es añadir a Play un nodo hijo de tipo “KinematicBody2D”, y renombrarlo a “Floor”.

Vamos a querer que el suelo esté cerca de la parte inferior de la pantalla, aunque dejando espacio para los controles. Así que en el Inspector pon la propiedad “Transform / Position” a 840.

Pero claro, no basta con que el suelo sea capaz de detectar colisiones. También necesitamos que el jugador vea el suelo, y “KinematicBody2D” no tiene ninguna propiedad de imagen. La solución es muy sencilla, aunque requiere hacer algo que aún no hemos hecho: empezar a poner unos nodos hijos de otros. En el árbol de nodos pincha en el nodo “Floor”, y añádele un nodo hijo de tipo “TextureRect”. A este último arrástrale la imagen “floor.png” a su propiedad “texture” del Inspector. Para hacerlo tan grande como la pantalla, en el mismo inspector pon la propiedad de “Rect / Size / x” a 1920.

Aunque como puedes ver el cuadrado de la imagen ahora es grande, la imagen en sí misma no ha crecido. Esto podemos resolverlo con la propiedad “Stretch Mode”. Por ejemplo, si ponemos el valor “Scale” forzará el tamaño de la imagen al tamaño del rectángulo. En este caso no es buena solución, porque queda bastante deformado. Lo ideal aquí es elegir “Tile”, que repetirá la imagen una y otra vez hasta rellenar el espacio. Como la imagen que tenemos para el suelo está justamente diseñada para esto, el resultado es perfecto.

Ya casi tenemos nuestro suelo, pero todavía no. Como puedes ver, aparece un icono de aviso al lado del nodo “Floor”. Esto es porque ahora mismo el nodo no tiene forma. Aunque le hayamos añadido un hijo de tipo “TextureRect”, ese nodo es solamente visual, no hace nada internamente para el tema de colisiones. Tenemos que definirle una forma para las colisiones: Un nuevo nodo de tipo “CollisionShape2D”. Añádelo como hijo de “Floor”, y verás… otro icono de aviso. Esta vez, porque aunque hayamos añadido el nodo, nos falta definir la forma concreta que queremos. ¿Será un círculo? ¿Un rectángulo? ¿Una elipse? Godot nos da esas opciones y muchas más.

Con el nodo “CollisionShape2D” seleccionado, en el Inspector despliega los valores posibles para la propiedad “Shape” y elige “New RectangleShape2D”.

Luego, para centrarlo, y darle tamaño, pon estos valores:

TIP: Si no ves los "extents" pincha sobre el valor "RectangleShape2D" para que se desplieguen sus propiedades
  • “Extents / x”: 960
  • “Extents / y”: 128
  • “Transform / Position / x”: 960
  • “Transform / Position / y”: 128
TIP: La colocación y el tamaño de elementos también se puede hacer de forma visual, arrastrando y ampliando. Pero es mucho más propensa a errores y menos exacta. En nuestra opinión, siempre que puedas colocar algo con valores exactos, mucho mejor.
Puedes poner directamente el proyecto en este punto desde esta rama de git: https://gitlab.com/pablo_alba/patapangtutorial/-/tree/step13

El personaje principal (I)

Vamos por fin a manejar a nuestro protagonista. También se va a basar en un “KinematicBody2D”. Como ya te adelanto que va a ir ganando complejidad, en lugar de ser un simple nodo de la escena de juego, el personaje principal va a ser una escena en sí mismo. Así que una vez más usa el menú Scene / New Scene. Elige “Other node”, y “KinematicBody2D”. Cambia el nombre del nodo raíz a “Player”.

Vamos a hacer algo muy parecido a lo que hemos hecho para el suelo. Añadiremos a este nodo Player dos hijos, uno capaz de visualizar una imagen, y otro que defina la forma que queremos para las colisiones. En este caso vamos a elegir una forma de “cápsula”, que encaja muy bien con el cuerpo de un personaje.

En el árbol de nodos pincha en el nodo “Player”, y añádele un nodo hijo de tipo “TextureRect”. A este último arrástrale la imagen “adventure_guy.png” a su propiedad “texture” del Inspector.

En el árbol de nodos vuelve a pinchar en el nodo “Player”, y añádele un nodo hijo de tipo “CollisionShape2D”. Con este nodo seleccionado, despliega los valores posibles para la propiedad “Shape” y elige “New CapsuleShape2D”.

Para ajustarlo a la figura pon estos valores:

  • “Radius”: 80
  • “Height”: 300
  • “Transform / Position / x”: 160
  • “Transform / Position / y”: 243

Por último, guarda todo como “Player.tscn”.

Puedes poner directamente el proyecto en este punto desde esta rama de git: https://gitlab.com/pablo_alba/patapangtutorial/-/tree/step14

Escenas hijas

Pues el siguiente paso es añadir la escena que acabamos de crear como una escena hija de la escena “Play”. Para eso vamos a volver a la escena “Play”. Si aún la tienes abierta, basta con que cambies a su pestaña. Si no, ábrela con el menú “Scene / Open scene””.

Ahora selecciona el nodo raíz “Play”, y pulsa en el botón (o pulsa con el botón derecho sobre el nodo y selecciona “Instance Child Scene”). En la ventana que sale elige la escena “Player.tscn”.

Si todo ha ido bien, verás que se ha añadido la escena completa como si fuera un simple nodo. Para ajustarlo a esta escena, pon estas propiedades:

  • “Transform / Position / x”: 845
  • “Transform / Position / y”: 605
  • “Transform / Scale / x”: 0.5
  • “Transform / Scale / y”: 0.5

Si ejecutas la escena con F6, verás efectivamente el personaje en el suelo.

El personaje principal (II)

Para acabar esta parte del tutorial, vamos a darle un mínimo de interactividad al personaje principal. Vuelve a abrir la escena Player, y con el nodo raíz seleccionado pulsa el botón para asociarle un script de GDScript. Llámalo “Play.gd”.

Vamos a crear una función especial, llamada “_physics_process”. Esta función va a ser llamada automáticamente por Godot cada vez que procese la física del juego. Es decir, que va a ser llamada un montón de veces por segundo. De hecho, recibe un parámetro, “delta”, que indica el número de milisegundos desde que fue llamada por última vez. Esto lo usaremos más adelante.

Lo que vamos a hacer ahora es comprobar si el jugador ha pulsado el cursor “derecha” o “izquierda”, y decidir con eso si queremos voltear horizontalmente la imagen o no. Más adelante tendremos controles en pantalla, pero por ahora para poder probar mientras desarrollamos esta opción es muy cómoda.

TIP: Godot nos permite acceder fácilmente a las interacciones con el usuario mediante la clase "Input". Hay un montón de constantes predefinidas que puedes ver (y cambiar) en el menú "Project / Project Settings / Input map"
1
2
3
4
5
func _physics_process(delta):
if Input.is_action_pressed("ui_right"):
$TextureRect.flip_h = false
elif Input.is_action_pressed("ui_left"):
$TextureRect.flip_h = true
Puedes poner directamente el proyecto en este punto desde esta rama de git: https://gitlab.com/pablo_alba/patapangtutorial/-/tree/step15

¡Continuará! Cada semana, un nuevo post tutorial.


Tutorial: