Tutorial de Godot – Parte 06: Física y colisiones

En el futuro de esta serie de tutoriales de Godot, a menudo necesitaremos saber cuándo dos objetos entran en contacto entre sí. En el desarrollo de juegos, esto se conoce como detección de colisiones . En este tutorial, aprenderemos cómo funcionan las colisiones en Godot.

Cuando se detecta una colisión, normalmente desea que suceda algo. Por ejemplo, cuando el sprite del jugador entra en contacto con una pared, queremos que se detenga. En cambio, si se mueve sobre un objeto, queremos que pueda recogerlo. Esto se conoce como respuesta de colisión .

Godot ofrece cuatro tipos de objetos de colisión para proporcionar detección y respuesta a la colisión. Tratemos de entender cómo funciona cada uno y cuándo usarlos con ejemplos prácticos.

CinemáticaCuerpo2D

Los nodos KinematicBody2D detectan colisiones con otros cuerpos, pero no se mueven automáticamente según propiedades físicas como la gravedad o la fricción. Deben ser movidos manualmente por el usuario a través de scripts.

Ya hemos visto un ejemplo en el tutorial de movimiento del jugador , donde usamos KinematicBody2D para mover al jugador.

Al mover un cuerpo cinemático, no debe establecer su posición directamente. En su lugar, debe utilizar los métodos move_and_collide() o move_and_slide() . Si después del movimiento el cuerpo ha chocado, como respuesta puede querer que su cuerpo rebote, que se deslice a lo largo de una pared o que altere las propiedades del otro cuerpo. La forma en que maneja la respuesta de colisión depende del método utilizado para mover KinematicBody2D:

  • Cuando se usa move_and_collide() , la función devuelve un objeto KinematicCollision2D , que contiene información sobre la colisión y el cuerpo que choca. Cualquier respuesta de colisión debe codificarse manualmente utilizando esta información (KinematicCollision2D contiene información sobre el objeto que colisiona, el movimiento restante, la posición de colisión, etc.)
  • Al usar move_and_slide() , si el cuerpo choca con otro, se deslizará a lo largo del otro cuerpo en lugar de detenerse inmediatamente. No tiene que escribir ningún código para obtener este comportamiento.

Como se mencionó anteriormente, ya tenemos un objeto KinematicBody2D en nuestro proyecto, el nodo Player . Entonces, abramos el proyecto SimpleRPG para completar su configuración.

Si recuerda, este nodo tiene una advertencia que debemos corregir.

Esta advertencia se debe a la falta de una forma de colisión. Las formas de colisión se utilizan para definir los límites de colisión del cuerpo y para detectar el contacto con otros objetos.

La forma más común de asignar una forma a un objeto de colisión es agregar un nodo CollisionShape2D o CollisionPolygon2D como su elemento secundario. Estos nodos le permiten dibujar la forma directamente en el espacio de trabajo del editor.

Agregue un nodo secundario CollisionShape2D a Player.

En el Inspector, establezca Forma en New RectangleShape2D . Ahora, el sprite del jugador se superpondrá con un rectángulo que podemos manipular para establecer el tamaño de la forma de colisión. Cambie el tamaño para que tenga el mismo tamaño que nuestro sprite.

A medida que aprendamos los otros tipos de colisionadores, veremos cómo interactúan con el KinematicBody2D de nuestro jugador .

Cuerpo estático2D

StaticBody2D son cuerpos que participan en la detección de colisiones pero, como su nombre lo indica, no se mueven en respuesta a las colisiones. Se utilizan principalmente para objetos que forman parte del entorno, como paredes, árboles, rocas, etc.

Para probar StaticBody2D , primero descarga la siguiente imagen e impórtala en Godot (recuerda desactivar Filtro en el panel Importar ).

Descargar «Teselas de mapa SimpleRPG»map_tiles.png – 5 KB

Agregue un nodo StaticBody2D como elemento secundario de Root y cámbiele el nombre Rock . Luego, agregue un nodo Sprite y un CollisionShape2D a Rock .

Selecciona Rock ‘s Sprite y arrastra el archivo map_tiles.png a la propiedad Texture en el Inspector. El sprite aparecerá en la esquina superior izquierda de la pantalla del juego.

No queremos usar toda la imagen, sino solo una pequeña región de ella. Para hacer esto, en el Inspector, busque la sección Región y habilítela.

Ahora que Region está habilitada, en la parte inferior del editor verás que hay un nuevo panel llamado Texture Region. Abrelo.

Hay varias formas de seleccionar la región que nos interesa. En nuestro caso, todos los elementos están organizados en una cuadrícula de 16 × 16 píxeles, por lo que la solución más simple es configurar el Modo de ajuste en Ajuste de cuadrícula , establecer los dos valores de Paso en 16 px y luego seleccionar el cuadrado que contiene la roca.

Ahora seleccione Rock ‘s CollisionShape2D , establezca la propiedad Shape en New CircleShape2D y, en el editor, cambie el tamaño del círculo para cubrir solo la roca.

Finalmente, seleccione el nodo Roca y establezca su Posición , en la sección Transformar , en (220, 90) .

Ahora, si inicias el juego y mueves al jugador, ¡verás que no podrá moverse a través de la roca!

Si te fijas, hay un pequeño problema: cuando el jugador está cerca de la roca, es arrastrado bajo la hierba. Puede resolver este problema configurando el índice Z del jugador en 1 (la roca tiene un índice Z 0 y, por lo tanto, se arrastrará hacia atrás). Para hacer esto, seleccione Player y en el Inspector busque la sección Z Index debajo de Node2D y establezca Z Index en 1 .

Cuerpo rígido2D

RigidBody2D es el nodo que implementa física 2D simulada. No lo controlas directamente. En su lugar, le aplicas fuerzas (gravedad, impulsos, etc.) y el motor de física de Godot calcula el movimiento resultante, incluidas las colisiones con otros cuerpos y las respuestas a las colisiones, como rebotes, rotaciones, etc. Al igual que en KinematicBody2D y StaticBody2D , debes asigne una o más formas a RigidBody2D .

Para probarlo, agregue un nodo RigidBody2D como elemento secundario de Root y cámbiele el nombre MovingRock . Luego, agregue un nodo Sprite y un CollisionShape2D a MovingRock .

Exactamente con el mismo procedimiento que vimos para StaticBody2D , configure la textura Sprite y la forma CollisionShape2D , luego mueva MovingRock a Position (210, 30) .

Si juegas ahora, verás que MovingRock comenzará a caer, golpeará a Rock y comenzará a girar mientras continúa su caída. ¡Acabas de ver el motor de física de Godot en acción por primera vez!

Puede modificar el comportamiento de RigidBody2D configurando sus propiedades en el Inspector o mediante scripts. El comportamiento del cuerpo también se ve afectado por las propiedades del mundo, como se establece en Configuración del proyecto → Física .

Nuestro juego es un juego de rol de arriba hacia abajo, por lo que no necesitamos la gravedad. Con MovingRock seleccionado, establezca el valor de Gravity Scale en 0 en el Inspector . También en el Inspector , establezca Lineal → Damp en 10 y Angular → Damp en 5 para agregar fricción.

Vuelve a ejecutar el juego. Ahora MovingRock no se cae. ¡Puedes usar tu reproductor para empujar y girar la roca!

¡Tenga en cuenta que hasta ahora no ha ingresado ninguna línea de código!

Área2D

El último tipo de objeto de colisión de Godot es Area2D . Es un área que detecta cuando otros objetos de colisión se superponen, entran o salen de ella. Un nodo Area2D también se puede usar para anular las propiedades físicas, como la gravedad o la amortiguación, en un área definida. También reciben entrada de mouse y pantalla táctil.

Agregue un nodo Area2D como elemento secundario de Root y cámbiele el nombre Flowers . Luego, agregue un nodo Sprite y un CollisionShape2D a Flowers. Configure la textura Sprite para usar la imagen de la flor de map_tiles.png y agregue a CollisionShape2D una forma de rectángulo que cubra las flores (¡ya debería haber aprendido cómo hacerlo!). Por último, mueve las Flores a la Posición (140, 100).

Adjunte un nuevo script a Flowers. Queremos conectar la señal de entrada de Area2D a este script para eliminar las flores del juego cuando el jugador se mueve sobre ellas, como si las hubiera recogido.

Seleccione Flor y vaya al panel Nodo . Aquí verá una lista de todas las señales de Area2D que puede conectar. Elija body_entered y presione Conectar…

En la ventana que se abre, elija Flowers como el nodo para conectarse.

Pulse el botón Conectar . El script Flowers.gd se abrirá y el método que manejará la señal se agregará automáticamente. Escribe este código para el método _on_Flowers_body_entered() :

func _on_Flowers_body_entered(body):
	if body.name == "Player":
		get_tree().queue_delete(self)

Este método verifica si el cuerpo ingresado en el área es Player . Si es verdadero, se eliminará del árbol de nodos actual.

Ejecuta el juego e intenta moverte sobre las flores.

Conclusiones

En este tutorial aprendimos los fundamentos del motor de física de Godot, en particular todos los tipos de objetos de colisión y sus características. En el próximo tutorial, usaremos este conocimiento para crear mapas de juego con terreno que responda a las colisiones con el jugador.