En este tutorial paso a paso, crearemos las bases de un plataformero básico usando Godot engine. Al finalizar, tendremos un prototipo con las siguientes características:
Para empezar, necesitamos crear nuestro proyecto en Godot. Los proyectos en Godot se representan mediante carpetas, estas carpetas deben de tener el mismo nombre de nuestro proyecto, y todo asset de nuestro juego ira dentro de esta carpeta. Ponle un nombre a tu proyecto y presiona crear para empezar a editarlo.
¡Sin embargo! Antes de empezar con la creación de nuestro juego, necesitaremos definir dos cosas muy importantes: la resolución y los controles.
Todo videojuego funciona con una resolución "fija", esta resolución es determinada según el tipo de contenido del videojuego, si es un videojuego que usa elementos 3D con texturas de alta calidad, muy probablemente su resolución sera HD (1280x720) o 4K (3840x2160). Sin embargo, en nuestro juego usaremos recursos en pixel art, es decir en un estilo pixeleado, y por ende necesitaremos usar una resolución ¡Mucho mas baja! Mas específicamente, trabajaremos con una resolución de 320x180, la cual es una resolución popular entre videojuegos independientes en pixel-art, como Celeste, Shovel Knight, Nuclear throne, etc.
Si te preguntas el porque de esta resolución en especifico, si multiplicamos 320x180 por 4, tendremos una resolución HD de 1280x720, ideal para escalar pixeles en pantallas modernas
Para definir esta resolución en nuestro proyecto, buscaremos en la barra superior del editor la sección de Project, desplegamos el menu, y dentro de este presionaremos el primer botón Project settings.
Al presionar este botón, se abrirá la configuración del proyecto en una nueva ventana. Aquí buscaremos la opción de Window/Ventana dentro de la categoría Display, donde podremos modificar todo lo relacionado con la ventana de nuestro juego. Aquí podremos especificar el ancho y largo de nuestra ventana, que por defecto sera el tamaño de nuestra pantalla, aquí especificaremos la resolución de 320 de ancho/width por 180 de alto/height.
Ademas, buscaremos en la sección de Stretch/Estirar la propiedad de Mode/Modo, y escogeremos la opción Viewport, esto escalara nuestro juego para que se pueda ver en pantallas modernas.
¡No cierres el menu todavía!
En las configuraciones de proyecto, buscaremos la categoría de Input map/Mapa de entrada
Aquí en este menu vamos a definir todas las acciones que pueda realizar nuestro personaje, en nuestro caso solo queremos movimiento básico (caminar hacia la derecha e izquierda) y un salto, al estilo clásico de Super Mario.
Para crear una acción, tendremos que introducir el nombre de esta en la caja de texto Add New Action/Añadir una nueva acción, y presionar la tecla Enter en tu teclado, o el botón de Añadir/Add localizado en el extremo derecho.
Crearemos tres acciones
Por cada acción, asignaremos una tecla, para asignarla presionaremos el botón de +, y pulsaremos una tecla de nuestro teclado, escoge la que tu prefieras para dicha acción.
Tu mapa de entradas se debería de ver similar a este:
Ya podremos cerrar el menu de configuración y empezar a crear nuestro juego.
Godot funciona a partir de un árbol de escenas y nodos. Una escena esta constituida por multiples nodos, y un nodo individual puede ser muchas cosas, como un bloque de texto, una textura, una pista de audio, etc. Podemos ver las escenas como una construcción, y los nodos como los ladrillos de esta. Para añadir nodos a nuestra escena, tendremos que buscar en el apartado superior izquierdo del editor.
Nuestro personaje sera un nodo de tipo CharacterBody2D, para añadirlo a la escena, tendremos que seleccionar cualquiera de los dos botones subrayados (+, Other Node/Otro nodo), y luego buscaremos CharacterBody2D
Asegurate de crear un nodo de CharacterBody2D! no un CharacterBody3D
Una vez creado el nodo CharacterBody2D, podemos empezar a añadir nodos hijo a la escena. Para empezar, necesitamos ver a nuestro personaje usando una textura, esta textura puede ser una imagen plana o una animación. Si deseamos añadir animaciones a nuestro personaje, la mejor practica es utilizar un Spritesheet
A continuación, tienes dos opciones a seguir: A. Una textura estática si no queremos animación o B: Una textura animada si queremos animar nuestro personaje
Para mostrar a nuestro personaje con una imagen estática, crearemos un Sprite2D como hijo del CharacterBody2D. Para que podamos ver nuestro Sprite, tendremos que asignar una textura a la propiedad de Texture/Textura, localizada en el apartado de propiedades de nodo en la parte derecha del editor.
Siéntete libre de usar cualquier imagen que desees, para propósitos de este tutorial, puedes usar el icono de Godot incluido por defecto en el proyecto, o también puedes descargar uno de estos aliens:
Dale click al personaje que mas te guste para descargarlo!
Asegurate de guardar cualquier imagen que descargues dentro de la carpeta de tu juego!
Si en cambio, queremos animar a nuestro personaje, debemos de usar un Spritesheet. Un Spritesheet es una sola imagen que contiene multiples cuadros de animación separados vertical y/o horizontalmente. Puedes buscar un Spritesheet, realizar el tuyo, o descargar cualquiera de estos Spritesheet básicos:
Una vez tengamos nuestra textura, crearemos un nodo AnimatedSprite2D como hijo de nuestro CharacterBody2D. Notaremos que este nuevo nodo no tiene una propiedad de textura como Sprite2D, en cambio, tiene una propiedad llamada Sprite Frames, que se encuentra en la categoría de Animation, daremos click y crearemos un nuevo recurso de SpriteFrames
Al crear el recurso de SpriteFrames, podemos darle click para acceder a el.
Y aqui podremos ver una nueva ventana, localizada en la parte inferior del editor, este es el editor de animaciones, a continuación podrás ver los elementos mas importantes de este editor:
Puede suceder que la parte inferior del editor no se despliegue correctamente, para que aparezca, arrastra el borde superior de esta sección hacia arriba.
Por el momento, crearemos dos animaciones (con el botón #1), y las nombraremos: Idle y Correr. Al abrir nuestro Spritesheet (con el botón #7), veremos una nueva ventana:
Esta es la ventana de Selección de frames de Spritesheet, y es aquí donde seleccionaremos los frames que usaremos de nuestro Spritesheet. En el apartado derecho de esta ventana podremos ajustar la cantidad de cortes que se le harán a nuestra imagen. En nuestro caso, nuestro Spritesheet solo se compone de 2 cuadros horizontales, entonces ajustaremos la propiedad de Horizontal a 2 recortes, y Vertical a 1.
En caso de usar un Spritesheet online o propio, debes de ajustar la cantidad de recortes al numero de frames que tenga tu imagen, algunos Spritesheets también contienen separación entre los frames, ajustable por la propiedad Separation
Una vez este recortada correctamente nuestra imagen, seleccionaremos los frames en el orden que queremos que se reproduzca nuestra animación
¡Tip! En caso de usar un Spritesheet de 2 frames como el que usamos en este tutorial, es recomendado seleccionar el 2do frame de animación primero, de esta manera el personaje empezara la animación en movimiento, y no parecerá arrastrándose al mover
Para nuestra "animación" de Idle, crearemos otra animación (Botón #1), la llamaremos "Idle" y repetiremos el proceso de abrir nuestro Spritesheet (Botón #7), sin embargo esta vez solo seleccionaremos un cuadro. La "animación" de Idle se reproducirá cuando nuestro personaje no este realizando ninguna acción.
¡Y listo! Asi se vera la interfaz del editor cuando tengamos nuestras animaciones preparadas para usar después.
Ahora que podemos ver a nuestro personaje en el editor, tenemos que darle una forma, con la que podrá interactuar y colisionar con el mundo y sus elementos. Para añadir esta forma, crearemos un nodo CollisionShape2D como hijo de nuestro CharacterBody2D.
Podrás notar que nuestro nuevo nodo tiene una advertencia! No te preocupes, esto es debido a que nuestro nodo todavía no tiene una forma definida.
Advertencia! verifica que añadas tu nodo CollisionShape2D como hijo de tu nodo CharacterBody2D, pues un nodo de colisión NO funcionara si no es hijo de un cuerpo de físicas como CharacterBody2D.
Verifica que la jerarquía de tu árbol sea similar a la presentada arriba.
Para crear una forma, buscaremos la propiedad Shape en el apartado de propiedades de nodo, localizada en la parte derecha del editor.
Al intentar crear un recurso de forma, veremos un listado con multiples opciones, quizá demasiadas, pero ¡No te abrumes! Pues en la mayoría de casos solo necesitaremos de tres opciones:
CircleShape2D: Un circuloRectangleShape2D: Un rectánguloCapsuleShape2D: Una capsula
Siéntete libre de probar y experimentar con cualquiera de estas opciones.
Una vez tengamos esta forma, nuestro personaje estará listo para interactuar con el nivel que diseñemos
Para finalizar con la preparación de nuestro personaje, necesitaremos una cámara que siga al jugador mientras se mueve por el nivel. Creemos un nodo Camera2D como hijo de nuestro CharacterBody2D. Para nuestra suerte, la cámara de Godot funcionara automáticamente, sin necesidad de código u otro ajuste.
Sin embargo, podemos activar el suavizado de posición encontrado en el panel de propiedades de nodo localizado en la parte derecha del editor, esto hará que nuestra cámara se vea mucha mas fluida al moverse
Ya tenemos la base de nuestro personaje construida, ahora, solo necesitamos aplicarle lógica a nuestro personaje para que lo podamos controlar. Por el momento, solo realizaremos la lógica de movimiento y de salto básico.
Para crear un nuevo archivo de código y asignarlo a nuestro personaje, presionaremos el botón de añadir Script localizado en la barra superior de nuestro editor de escena, donde se abrirá una nueva ventana de creación de Script, nosotros no necesitaremos un template u otra opción, asi que podemos presionar Create para crear y abrir nuestro código:
Una vez creado nuestro archivo de Script, se nos redireccionará automáticamente al editor de código de Godot, donde veremos esta unica linea de código:
extends CharacterBody2D
Esta unica linea de código nos dice algo ¡muy importante! al extender el nodo de CharacterBody2D , estamos construyendo nuestro propio nodo a partir del nodo ya creado, siguiendo esta lógica, todos los elementos que creemos en Godot para nuestro juego, serán pequeñas construcciones creadas a partir de los bloques que nos de el programa, y asi mismo, estas pequeñas construcciones serán los bloques de lo que sera nuestra construcción, es decir, nuestro juego.
A continuación, empezaremos nuestro código estableciendo todas las variables que usaremos en el jugador.
#Bloque de variables
var gravedad = -9.8
var rapidez = 150
var salto = 250
Luego, usaremos una función nativa de Godot, _physics_process(delta), la cual se ejecuta cada frame, para nosotros, cada 0.0617 segundos, para aplicar la fuerza de gravedad sobre el personaje
#La función de physics_process() se ejecuta cada frame
func _physics_process(delta: float) -> void:
#Esta función hará que nuestro personaje tenga físicas
move_and_slide()
#Aplicaremos constantemente la fuerza de gravedad sobre el personaje
velocity.y += gravedad
Ahora, crearemos un salto básico añadiendo este bloque de código dentro de la función de physics_process
#Si el jugador unde la tecla de salto y el personaje esta en el suelo, añadiremos la fuerza de salto
if Input.is_action_just_pressed("salto") and is_on_floor():
velocity.y = -poder_salto
Muy seguramente creaste tus mapas de entradas (controles) con un nombre distinto a "salto", "derecha" o "izquierda", Asegurate de cambiar esto en las funciones de Input según corresponda.
Y luego, añadiremos una lógica de movimiento hacia la derecha e izquierda dentro de physics_process.
#Bloque de código para movimiento horizontal
#Normalizaremos la velocidad horizontal a 0 si no hay ninguna tecla presionada
velocity.x = 0
#Cuando presionemos a la izquierda, sumaremos
if Input.is_action_pressed("izquierda"):
velocity.x += rapidez
if Input.is_action_pressed("derecha"):
velocity.x -= rapidez
Hemos terminado con el funcionamiento básico de nuestro personaje! Si has usado el nodo AnimatedSprite2D para crear las animaciones, este es el momento de usarlas! Añade este código a physics_process
#Si el personaje esta quieto, entonces reproducirá la animacion de caminar
if velocity.x != 0:
$AnimatedSprite2D.play("caminar")
#De lo contrario, cuando el personaje este quieto, reproducira la "animación" de idle
else:
$AnimatedSprite2D.play("idle")
Adicionalmente a esto, podemos modificar el bloque de movimiento horizontal del personaje para que gire hacia la derecha e izquierda.
#Bloque de código para movimiento horizontal
#Normalizaremos la velocidad horizontal a 0 si no hay ninguna tecla presionada
velocity.x = 0
#Cuando presionemos a la izquierda, sumaremos
if Input.is_action_pressed("izquierda"):
velocity.x += rapidez
$AnimatedSprite2D.flip_h = true
if Input.is_action_pressed("derecha"):
velocity.x -= rapidez
$AnimatedSprite2D.flip_h = true
Y con esto, todo el codigo del personaje se vera asi:
extends CharacterBody2D
#Bloque de variables
var rapidez = 100;
var poder_salto = 250
var gravedad = -9.8
#La función de physics_process() se ejecuta cada frame
func _physics_process(delta: float) -> void:
#Esta función hará que nuestro personaje tenga físicas
move_and_slide()
#Aplicaremos constantemente la fuerza de gravedad sobre el personaje
velocity.y += gravedad
#Si el jugador unde la tecla de salto y el personaje esta en el suelo, añadiremos la fuerza de salto
if Input.is_action_just_pressed("salto") and is_on_floor():
velocity.y = -poder_salto
#Bloque de código para movimiento horizontal
#Normalizaremos la velocidad horizontal a 0 si no hay ninguna tecla presionada
velocity.x = 0
#Cuando presionemos a la izquierda, sumaremos
if Input.is_action_pressed("izquierda"):
velocity.x += rapidez
$AnimatedSprite2D.flip_h = true
if Input.is_action_pressed("derecha"):
velocity.x -= rapidez
$AnimatedSprite2D.flip_h = false
#Bloque de animación
#Si el personaje esta quieto, entonces reproducirá la animacion de caminar
if velocity.x != 0:
$AnimatedSprite2D.play("caminar")
#De lo contrario, cuando el personaje este quieto, reproducira la "animación" de idle
else:
$AnimatedSprite2D.play("idle")
Para empezar a crear nuestro nivel, debemos de crear otra escena. Hay varias maneras de realizar esto, por ejemplo, podemos usar el atajo de teclado Ctrl+n, o bien podemos crearla desde la interfaz del editor con el botón + al lado de nuestra pestaña de personaje (esta interfaz es similar a la de un navegador Web!) o desde el menu de Scene localizado en la parte superior izquierda del editor
Al crear nuestra nueva escena, veremos que esta vacía, necesitaremos añadir un nodo de tipo Node2D. Es aquí donde añadiremos todo el contenido de nuestro nivel, y eventualmente, a nuestro personaje.
Un tilemap, en español "Mapa de mosaicos", es un conjunto de cuadros que usaremos para representar nuestro nivel, bien sea con cuadros de suelo u otros cuadros de elementos como arboles, cajas, decoraciones, etc. Con este nodo, podremos "pintar" estos elementos sobre una cuadricula para construir nuestro nivel. Podrás reconocer el concepto de Tilemap o Tileset a traves de editores de nivel en videojuegos como Super Mario maker o Geometry Dash
Al final de ajustar nuestro Tilemap, tendremos un sistema muy similar al de estos ejemplos
Empezaremos creando un nodo de tipo TileMapLayer como hijo de nuestro nodo Node2D.
Advertencia! Es importante que crees un nodo TileMapLayer y no un nodo , pues este ultimo esta deprecado y no es recomendable usarlo en nuevas versiones.
TileMap
Una vez creado nuestro nodo TileMapLayer, buscaremos por la propiedad Tileset en la sección de propiedades del nodo (recuerda, se encuentra en la parte derecha del editor) y crearemos un nuevo recurso de Tileset.
Al crear un nuevo Tileset, se creara una nueva pestaña en la parte inferior del editor donde podremos empezar a editar nuestros tiles.
Si no encuentras la pestaña de Tileset, asegúrate que tengas seleccionado el nodo de TileMapLayer y que hayas creado correctamente el recurso de Tileset en la sección de propiedades.
Para empezar a definir los tiles de nuestro nivel, necesitamos por supuesto una textura de Tileset, el cual se ve como una imagen bastante grande que contiene en forma de mosaico todos los cuadros de nuestro nivel.
Para propósitos de este tutorial, he simplificado el asset tileSet de Kenney para que sea mas compacto y fácil de usar, sin embargo también puedes descargar el Tileset completo si deseas usarlo
Antes de cargar nuestra textura en el Tileset, primero le especificaremos a nuestro nodo TileMapLayer el tamaño exacto en pixeles de cada elemento de nuestra textura. En nuestro caso, el tamaño de cada elemento es de 18x18, el cual se lo especificaremos en la propiedad Tile Size dentro de las propiedades del Tileset en nuestro nodo TileMapLayer
Ya especificado el tamaño de nuestros tiles, podemos añadir nuestra textura en la sección de Tileset añadiendo un nuevo Atlas. Al cargarla, nos aparecerá un aviso donde nos preguntara si queremos crear automáticamente los tiles a partir de la textura, y responderemos Yes.
Si hemos especificado correctamente el tamaño de nuestros tiles, el editor ha recortado automáticamente cada uno de los tiles en nuestra imagen, lo que significa que ya tenemos nuestro Tilemap! Sin embargo, antes de empezar a construir nuestro nivel, tendremos que definir una forma para estos tiles, y asi nuestro personaje podrá interactuar con ellos.
Si al hacer este proceso automático, el tilemap aparece roto, (similar a la imagen inferior) la solución mas simple es eliminar la textura (con el icono de bote de basura)
Iremos nuevamente a la sección de propiedades del Tileset de nuestro nodo TileMapLayer y buscaremos por la propiedad Physics Layer, y crearemos una capa de físicas para nuestros tiles.
Una vez creada nuestra capa de físicas, tendremos que aplicarla a nuestros tiles. Para hacer esto, iremos al apartado de Tileset en la parte inferior del editor, y seleccionaremos el modo de Paint para "pintar" atributos sobre nuestros tiles.
El atributo que debemos de pintar sera nuestra capa de físicas, indicada en el editor como Physics Layer 0, cuando tengamos esta propiedad seleccionada, podremos darle click a cualquier tile en la parte derecha para pintar una colisión sobre este. Para generar una colisión vacía (es decir, borrar la forma) podemos presionar la tecla C para eliminar la forma, y si queremos colocar una colisión normal nuevamente, presionaremos la tecla F. Estos controles son atajos, para ver estas opciones podremos abrir el menu de propiedades indicado por los tres puntos blancos.
Procura no asignar una colisión a los tiles inferiores del tilemap! Estos tiles son decorativos (como pasto, hojas, hongos, etc) y necesitaremos que el personaje NO colisione con estos.
Si hemos pintado las colisiones sobre nuestros tiles correctamente, nuestro nivel esta listo para construir! cualquier ajuste adicional que queramos añadir a nuestro tilemap, como un nuevo tile o ajustar la colisión o animación de un tile, lo haremos modificando este Tileset.