pixelboyz logo
Desarrollo de Videojuegos

Tutorial de Godot Engine Parte 7–Física y Detección de Colisiones

image

Índice de contenido


En este tutorial vamos a echar un vistazo a dos temas clave en el desarrollo de juegos de Godot, detección de colisiones y simulaciones físicas. La detección de colisiones simplemente detecta si dos objetos se superponen. La física, por otro lado, simula el movimiento y la interacción de los objetos del juego en función de las propiedades físicas. Esto, por supuesto, también incluye el manejo de colisiones. También hay un video de este tutorial y esta podría ser una de esas ocasiones, debido a todo el movimiento en los resultados, en las que quizás desee consultar el video incluso si prefiere los tutoriales basados ​​en texto. Entonces, si tiene dificultades para entender de qué estoy hablando aquí, asegúrese de revisar rápidamente el video, puede tener la respuesta.

Puede mira el video aquío incrustado debajo.

Comprobación de colisiones

Comencemos comprobando las colisiones entre dos objetos, en este caso, dos objetos Sprite diferentes. He creado la siguiente escena:

Son simplemente dos objetos sprite uno al lado del otro. Luego adjunté un script al de la izquierda. Esta secuencia de comandos actualiza la posición del sprite izquierdo hasta que se produce una colisión, momento en el que se restablece al principio y lo hace todo de nuevo. Al igual que:

animado

Echemos un vistazo al script ahora:

extends Sprite

var start_pos = Vector2()
var box1 = null
var box2 = null

func _ready():
   set_process(true)
   start_pos = get_pos()
   box1 = RectangleShape2D.new()
   box2 = RectangleShape2D.new()

func _process(delta):
   # Get a reference to the other sprite
   var sprite2 = get_node("/root/SceneRoot/Sprite 2")
   
   # Update our location
   self.move_local_x(0.1)
   
   # set the boundaries of each RectangleShape2D to those of the texture making up our sprite
   # values are relative to center, thus half width and height
   box1.set_extents(Vector2(self.get_texture().get_size().width/2,self.get_texture().get_size().height/2))
   box2.set_extents(Vector2(
sprite2.get_texture().get_size().width/2,sprite2.get_texture().get_size().height/2))
   
   #Now check to see if box1 at sprite1's pos collided with box2 and sprite2's position
   if(box1.collide(get_transform(),box2,sprite2.get_transform())):
      set_pos(start_pos) # it did, so reset position to beginning, what's old is new again!

Esencialmente, lo que está haciendo aquí es crear un RectangleShape2D usando los límites de la imagen de textura de cada Sprite. AKA, creando un rectángulo del tamaño de la textura. Luego verifica si box1 en la posición transformada de Sprite1 choca con box2 en la posición transformada de Sprite2. Por supuesto, dado que ambos usan el mismo mapa de textura, ¡no es necesario que crees dos objetos RectangleShape2D diferentes! Además, dado que el tamaño nunca cambia, en realidad no necesita set_extents() en process(). Hay una serie de clases de formas simples que se pueden usar para verificar colisiones, como polígonos cóncavos y convexos, círculos e incluso rayos (para seleccionar con el mouse).

Esta es una forma de verificar colisiones simples. Sin embargo, encontrará rápidamente que se vuelve difícil de manejar a medida que agrega más y más objetos y tiene que compararlos entre sí. Afortunadamente, el motor de física hace que este proceso sea mucho más fácil.

Simulaciones de física

Ahora que vimos una forma de probar las colisiones, avancemos y discutamos el sistema de física. Básicamente, un motor de física simula el movimiento utilizando matemáticas complejas, calculando cómo interactúan los elementos entre sí y las fuerzas externas como la gravedad. Luego, la simulación física actualiza, ya sea de forma fija o por cuadro, un conjunto de objetos con las nuevas ubicaciones calculadas por la simulación. Luego, actualiza las posiciones de los objetos de juego visibles en consecuencia. Sin embargo, en Godot, generalmente no es necesario realizar ese último paso, se realiza automáticamente.

Comencemos con un ejemplo extremadamente simple, la gravedad.

Primero comenzamos creando un nodo RigidBody2D:

imagen

A continuación, relacionado con el nodo RigidBody2D, cree un nodo sprite. Estoy usando el icon.png predeterminado que viene con Godot. Su jerarquía debería verse así:

imagen

… y eso es. Ahora ha creado un objeto físico al que se le aplicará la gravedad. Ejecuta tu juego y deberías ver:

anima2

Ahora detengámonos un segundo para ver exactamente lo que está sucediendo aquí.

Primero, comencemos con la parte RigidBody2D… Hay tres tipos de objetos físicos que puedes usar en tu mundo de juego 2D:

imagen

La mayor diferencia es cómo son tratados por la simulación.

Se puede pensar en un RigidBody como un objeto físico típico. Es el más intensivo en procesamiento, pero también tiene la mayor funcionalidad. A menos que tenga una razón diferente, si algo necesita física, probablemente sea un cuerpo rígido. Este es un objeto físico que puede moverse, puede chocar con otros objetos y chocar contra sí mismo.

El siguiente es el StaticBody2D. Este es un objeto inmóvil en su mundo. Básicamente, las cosas pueden golpearlo, puede ser golpeado, pero no se mueve. También requiere mucho menos poder de procesamiento para manejar. En general, cosas como el mundo, o disparadores invisibles pero inmóviles, serán cuerpos estáticos.

Finalmente está KinematicBody2D. Este es un objeto físico que no tiene el rango de funcionalidad de un cuerpo rígido (por ejemplo, no puede aplicarle fuerza), pero puede moverse y puede chocar con otros objetos físicos. Lo más importante de un cuerpo cinemático es que su movimiento generalmente lo controla directamente usted, sin la simulación física. Generalmente este es el sprite del personaje. Desea que la simulación física reaccione a sus acciones, pero generalmente controla esos movimientos directamente en el código.

Entonces, esos son los tres tipos principales de objetos físicos, ahora veamos la configuración global. ¿Observas cómo la gravedad se aplica automáticamente a nuestra simulación? ¿De dónde viene esto?

La respuesta es confiar en la configuración del proyecto ole:

imagen

Entonces… ¿qué significan esos valores? Bueno, esta es una de las cosas buenas de trabajar completamente en Godot. En muchos motores de física como Box2D, trabajas en metros, luego tienes que traducir de metros a píxeles cuando transformas tus sprites. En Godot, estos valores están en píxeles. Entonces, un valor de gravedad de 98 significa que la gravedad se mueve a 98 píxeles por segundo.

Ahora, ¿qué pasa con la configuración de Rigid Body? Bueno, echemos un vistazo:

imagen

Mass Friction y Bounce son los valores más utilizados. Oye, ¿masa y peso no son lo mismo? No, no exactamente. La masa es la cantidad de «cosas» que componen un objeto, mientras que el peso es la cantidad que pesan las cosas.

Considere la pregunta clásica «¿Qué pesa más, una tonelada de ladrillos o una tonelada de plumas?» Ambos objetos tendrían pesos idénticos (una tonelada), pero masas muy diferentes. De alguna manera, puede ser más fácil pensar en la masa que en la densidad.

La fricción, por otro lado, es cómo se desliza en contacto con otra superficie. Imagínese deslizando un ratón por una superficie en un ángulo de 45 grados. Si una superficie fuera de goma y la otra de vidrio, el mouse se moverá a velocidades muy diferentes. La fricción controla esto. El rebote a menudo se denomina restitución. Esta es la cantidad de, bueno, rebote en un objeto. O cuánto reacciona a una colisión. Una pelota de goma tiene un valor de «rebote» más alto, mientras que un ladrillo es casi 0. Otro concepto clave es el sueño, esta es la capacidad de apagar el cuerpo rígido durante los cálculos, determina si se usa o no como parte del sobre toda la simulación. La velocidad lineal y angular finalmente son los valores de movimiento predeterminados del objeto.

Estilo de física de colisiones

Ahora echemos un vistazo a cómo se manejan las colisiones usando un motor de Física. Cambiemos la escena anterior para agregar otro elemento de física, esta vez un cuerpo estático, así:

imagen

El sprite superior tiene un RigidBody2D como padre. La parte inferior tiene un StaticBody2D como padre. Ahora necesitamos definir un volumen de colisión para cada uno, tal como lo hicimos al principio. Simplemente agregue un nuevo nodo a cada cuerpo (¡no el sprite, es el padre!) de tipo CollisionShape2D, para que su jerarquía se vea así:

imagen

Luego, para cada CollisionShape2D, debe elegir una forma delimitadora. Con CollisionShape2D seleccionado en Inspector, simplemente seleccione el menú desplegable Forma y elija el que mejor se adapte:

imagen

Finalmente, ajústalo para que cubra las partes colisionables de tu sprite:

imagen

Ahora cuando ejecutas el juego:

anima3

¡Tada! Colisiones calculadas por el motor de física. Ahora puedes jugar un poco con las propiedades físicas de tu cuerpo rígido y ver cómo reacciona de manera diferente.

En este caso, usamos una caja simple para nuestra detección de colisión, y eso funciona bien para objetos con forma de caja. Pero si tu objeto no tiene forma de caja o círculo, ¿qué haces? Introduzca CollisionPolygon2D:

imagen

Funciona exactamente igual que CollisionShape2D, pero puedes definir la forma tú mismo. Quite uno de los nodos CollisionShape2D y reemplácelo con un nodo CollisionPolygon2D. Con el nodo Colisión seleccionado, notará una nueva opción en la ventana 2D:

imagen

Haga clic en el lápiz y ahora puede dibujar un polígono alrededor de su objeto:

imagen

Y una vez cerrado:

imagen

¡Una representación MUCHO más precisa de su objeto para colisiones!

Nodos cinemáticos

Finalmente, veamos los objetos KinematicBody2D. Estos son especiales porque el motor de física no controla su movimiento, tú lo haces. Sin embargo, pueden chocar con entidades en el mundo de la física. En términos generales, así es como crearías tu personaje. A diferencia de RigidBodies, no puede aplicar fuerzas o impulsos. En su lugar, los mueve directamente. Vamos a crear un ejemplo simple:

Primero agregue un KinimaticBody2D a su escena, agregue un sprite y una forma de colisión para él, así:

imagen

Ahora aplique un script a KinematicBody2D con el siguiente código:

extends KinematicBody2D

func _ready():
   set_process(true)   
func _process(delta):
   move(Vector2(0.04,0))

Simplemente movemos el cuerpo 0,4 píxeles por actualización. Sin embargo, como puede ver en los resultados, se producirán colisiones entre el objeto controlado por el código del juego y la simulación física:

anim4

Obviamente, hay mucho más en la simulación física. Puede crear uniones y resortes y definir qué objetos colisionan con otros objetos, pero eso cubre la mayoría de los conceptos básicos. Asegúrate de ver el vídeo si te cuesta, ¡ya que cubre las cosas con un poco más de detalle!

El video




Source link

Tags :
7Física,Colisiones,Detección,Engine,Godot,parte,Tutorial

Comparte :

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *