Creating a 2D Player Combat System in Godot

Welcome back to our game development blog! Today, we’re diving into an essential aspect of many 2D games: the combat system. Whether you’re building a platformer, a beat ‘em up, or an RPG, having a solid combat system is crucial for engaging gameplay. In this tutorial, we’ll walk you through creating a basic 2D player combat system in Godot. We’ll cover setting up the player, handling attacks, and detecting hits.


Setting Up the Project


Before we start coding, let’s set up our Godot project:


1. Create a New Project

Open Godot and create a new project. Name it something like “CombatSystemTutorial”.

2. Set Up the Scene

Create a new 2D scene and add a KinematicBody2D node. This will be our player node.

Add a Sprite and CollisionShape2D as children of the KinematicBody2D node to represent the player visually and physically.

Add an Area2D node and a CollisionShape2D as children of the KinematicBody2D node. This will be used to detect hits.


Step 1: Creating the Player Script


We’ll start by writing a script to handle the player’s movement and attack logic:


1. Attach a Script to the Player

Select the KinematicBody2D node and attach a new script named Player.gd.

2. Define Player Variables

In the script, define variables for movement, attack, and animation:


extends KinematicBody2D


# Player Variables

var speed = 200

var is_attacking = false


# Animation and Attack Timing

onready var animation_player = $AnimationPlayer

var attack_duration = 0.5

var attack_timer = 0.0


func _ready():

    pass


func _process(delta):

    if !is_attacking:

        move()

    else:

        attack_timer -= delta

        if attack_timer <= 0:

            is_attacking = false

            animation_player.play("Idle")


func move():

    var velocity = Vector2()

    if Input.is_action_pressed("ui_right"):

        velocity.x += 1

    if Input.is_action_pressed("ui_left"):

        velocity.x -= 1

    if Input.is_action_pressed("ui_up"):

        velocity.y -= 1

    if Input.is_action_pressed("ui_down"):

        velocity.y += 1


    velocity = velocity.normalized() * speed

    move_and_slide(velocity)


Step 2: Implementing the Attack Logic


Next, we’ll add the attack logic and handle hit detection:


1. Add Input for Attacking

Go to Project > Project Settings > Input Map and add a new action named attack. Assign a key to this action (e.g., Space).

2. Handle Attack Input

Update the _process function to handle the attack input:


func _process(delta):

    if !is_attacking:

        move()

        if Input.is_action_just_pressed("attack"):

            attack()

    else:

        attack_timer -= delta

        if attack_timer <= 0:

            is_attacking = false

            animation_player.play("Idle")


func attack():

    is_attacking = true

    attack_timer = attack_duration

    animation_player.play("Attack")

    $Area2D.set_monitoring(true)


3. Detect Hits

Connect the Area2D’s body_entered signal to the player script to detect hits:


func _on_Area2D_body_entered(body):

    if is_attacking and body.has_method("take_damage"):

        body.take_damage(10)


Step 3: Setting Up Enemy and Damage Handling


To complete the combat system, we need an enemy that can take damage:


1. Create an Enemy Scene

Create a new 2D scene and add a KinematicBody2D node. This will be our enemy node.

Add a Sprite and CollisionShape2D as children of the KinematicBody2D node to represent the enemy visually and physically.

Save the scene as Enemy.tscn.

2. Attach a Script to the Enemy

Select the KinematicBody2D node and attach a new script named Enemy.gd.

3. Define Damage Handling in the Enemy Script

In the script, define variables and a function to handle taking damage:


extends KinematicBody2D


# Enemy Variables

var health = 50


func _ready():

    pass


func take_damage(amount):

    health -= amount

    if health <= 0:

        die()


func die():

    queue_free()


Step 4: Putting It All Together


Place the enemy in the main scene and test the combat system:


1. Instance the Enemy Scene

Instance the Enemy.tscn scene in the main scene.

2. Test the Combat System

Run the game and test the player movement and attacking. Ensure the player can attack the enemy, and the enemy takes damage and eventually dies.


Conclusion


You’ve successfully implemented a basic 2D player combat system in Godot! This system includes player movement, attacking, and enemy damage detection. From here, you can expand the system by adding features like different attack types, enemy AI, and player health management.


Stay Connected


Follow our blog for more tutorials, tips, and insights into game development with Godot and other engines. Share your experiences and any challenges you encounter in the comments below. Let’s continue to learn and create amazing games together!


Summary of Steps


1. Set Up the Project: Create a new project and set up the player and enemy scenes.

2. Create the Player Script: Define movement, attack, and animation variables.

3. Implement Attack Logic: Handle attack input and detect hits.

4. Set Up Enemy and Damage Handling: Create an enemy that can take damage and die.

5. Test the Combat System: Instance the enemy in the main scene and test the combat interactions.


Happy developing!

Comments

Popular posts from this blog

Creating 2D Character Movement in Godot: A Step-by-Step Tutorial

Exploring “Papers, Please”: A Tale of Morality and Bureaucracy