Creando un Sistema de Combate Hack and Slash en Godot 4: Combos y Golpes
En este tutorial completo aprenderás paso a paso cómo programar un sistema de combate tipo Hack and Slash en Godot 4. Implementaremos combos de ataques, detección de golpes por áreas, gestión de estados de animación y retroalimentación visual para tus enemigos.
Introducción al Sistema de Combate Hack and Slash
El género Hack and Slash se define por su acción vertiginosa, fluidez de movimientos y sistemas de combate cuerpo a cuerpo basados en cadenas de golpes (combos). En Godot 4, estructurar un sistema de combate robusto requiere una combinación limpia de máquinas de estados, áreas de colisión dinámicas (Area2D o Area3D) y una gestión precisa de las animaciones mediante AnimationPlayer.
A lo largo de este tutorial, construiremos desde cero la lógica necesaria para que tu personaje pueda realizar un combo de tres golpes, detectar impactos en enemigos cercanos, aplicar daño en tiempo real y mostrar efectos visuales impactantes.
🛠️ Requisitos Previos y Configuración del Proyecto
Antes de escribir código, asegúrate de tener instalado Godot 4.x (se recomienda la versión 4.2 o superior). Necesitaremos la siguiente estructura básica en tu escena de personaje:
- Un nodo raíz
CharacterBody2Dpara el jugador. - Un nodo
Sprite2DoAnimatedSprite2Dpara los gráficos. - Un nodo
AnimationPlayerpara gestionar las animaciones de movimiento y ataque. - Un nodo
Area2Dhijo del jugador llamadoHitboxque contendrá unCollisionShape2D.
⚔️ Paso 1: Configurando las Áreas de Daño (Hitboxes y Hurtboxes)
El pilar fundamental de cualquier juego de acción es la separación entre el área que inflige daño (Hitbox) y el área que lo recibe (Hurtbox).
- Selecciona tu nodo
Hitbox(Area2D) y asegúrate de configurar sus capas de colisión (Collision Layers y Collision Masks) para que solo detecte a los enemigos. - Posiciona el
CollisionShape2DdelHitboxde manera que coincida con el arma o los puños del personaje durante los fotogramas clave de ataque. - Desactiva la propiedad
monitoringymonitorablepor defecto en el inspector, o mantén el área desactivada mediante código hasta que el frame de ataque lo requiera.
📜 Paso 2: Programando la Cadena de Combos
Para lograr un sistema de combos responsivo, debemos rastrear el índice del ataque actual (combo_step) y verificar si el jugador presiona el botón de ataque antes de que termine la animación actual.
Crea un script llamado PlayerCombat.gd y añade el siguiente código:
extends CharacterBody2D
@export var speed: float = 300.0
@onready var animation_player: AnimationPlayer = $AnimationPlayer
@onready var hitbox_shape: CollisionShape2D = $Hitbox/CollisionShape2D
var is_attacking: bool = false
var combo_step: int = 1
var can_combo: bool = false
func _ready() -> void:
hitbox_shape.disabled = true
func _physics_process(delta: float) -> void:
read_input(delta)
func read_input(_delta: float) -> void:
if Input.is_action_just_pressed("attack"):
if not is_attacking:
start_attack()
鈁elive_combo()
func start_attack() -> void:
is_attacking = true
combo_step = 1
play_current_combo_animation()
func try_buffered_combo() -> void:
if can_combo:
combo_step += 1
if combo_step > 3:
combo_step = 1
play_current_combo_animation()
can_combo = false
func play_current_combo_animation() -> void:
match combo_step:
1:
animation_player.play("attack_1")
2:
animation_player.play("attack_2")
3:
animation_player.play("attack_3")
func _on_animation_finished(anim_name: String) -> void:
if anim_name.begins_with("attack"):
is_attacking = false
combo_step = 1
can_combo = false
hitbox_shape.disabled = true
🛡️ Paso 3: Sincronizando los Frames de Impacto
Para que el combate se sienta preciso, el hitbox del jugador debe activarse únicamente durante los frames activos de la animación de ataque. Podemos lograr esto añadiendo llamadas a métodos en el AnimationPlayer.
Crea dos funciones auxiliares en tu script para ser llamadas desde la animación:
func enable_hitbox() -> void:
hitbox_shape.disabled = false
func disable_hitbox() -> void:
hitbox_shape.disabled = true
func allow_combo_window() -> void:
can_combo = true
🎯 Paso 4: Implementando la Hurtbox en los Enemigos
Los enemigos deben contar con una zona receptora de daño conectada a una barra de vida o script de estadísticas. Veamos cómo procesar la señal cuando el Hitbox del jugador colisiona con el Hurtbox del enemigo.
Crea un script para el enemigo Enemy.gd:
extends CharacterBody2D
@export var max_health: int = 100
@onready var current_health: int = max_health
func take_damage(amount: int) -> void:
current_health -= amount
print("Enemigo recibió daño. Vida restante: ", current_health)
# Efecto visual de retroceso o destello
modulate = Color.RED
await get_tree().create_timer(0.1).timeout
modulate = Color.WHITE
if current_health <= 0:
die()
func die() -> void:
queue_free()
Y conecta la señal area_entered de tu Hitbox:
# Dentro de PlayerCombat.gd
func _on_hitbox_area_entered(area: Area2D) -> void:
if area.has_method("take_damage"):
var damage_to_deal = 15 * combo_step
area.take_damage(damage_to_deal)
📊 Comparativa de Tipos de Ataques en Combates 2D
| Tipo de Ataque | Velocidad | Daño Base | Ventana de Combo | Alcance |
|---|---|---|---|---|
| --- | --- | --- | --- | --- |
| Golpe Ligero 1 | Rápido (0.3s) | Bajo (15) | Amplia | Corto |
| Golpe Ligero 2 | Medio (0.4s) | Medio (25) | Media | Corto-Medio |
| --- | --- | --- | --- | --- |
| Golpe Finalizador | Lento (0.7s) | Alto (50) | Nula | Amplio |
✨ Paso 5: Añadiendo Feedback Visual y Sonoro
Un sistema de combate excelente depende en gran medida del gamefeel. Para mejorar la experiencia del usuario, implementaremos pequeños efectos de sacudida de cámara (CameraShake) y partículas de impacto.
func trigger_hit_effects() -> void:
# Sacudida de cámara simple
var camera = get_viewport().get_camera_2d()
if camera:
camera.offset = Vector2(randf_range(-5, 5), randf_range(-5, 5))
await get_tree().create_timer(0.05).timeout
camera.offset = Vector2.ZERO
🔍 Preguntas Frecuentes (FAQ)
¿Cómo evito que el jugador se mueva mientras ataca?
Puedes bloquear la velocidad horizontal multiplicando la velocidad por cero o desactivando el procesamiento de movimiento dentro de la funciónstart_attack() hasta que la animación finalice.
¿Cómo añado efectos de partículas al golpear?
Instancia una escena precargada de partículas de tipoGPUParticles2D en la posición exacta donde ocurre la intersección entre el Hitbox y la Hurtbox, y libérala automáticamente al terminar su emisión.
🚀 Conclusión
¡Felicidades! Has implementado con éxito la base de un sistema de combate Hack and Slash en Godot 4. Ahora cuentas con una estructura modular que incluye gestión de estados de combo, áreas de impacto sincronizadas y retroalimentación visual para enemigos. A partir de aquí, puedes expandir este sistema añadiendo habilidades especiales, parry (contraataques) o esquivas con marcos de invulnerabilidad (i-frames).
Tutoriales relacionados
- Creando Efectos de Partículas Espectaculares en Godot 4: Explosiones, Magia y Másintermediate20 min
- Creando un Sistema de Crafteo y Recetas en Godot 4: Fabricando el Mundo de tu Juegointermediate15 min
- Navegación entre Escenas y Gestión de Estado en Godot 4: Creando un Flujo de Juego Dinámicointermediate15 min
- Creando un Sistema de Habilidades (Skills) y Árbol de Talentos en Godot 4intermediate15 min
- Creando un Sistema de Detección de Colisiones Avanzado en Godot 4: Precisión y Respuestaintermediate18 min
Comentarios (0)
Aún no hay comentarios. ¡Sé el primero!