Search code examples
godotgdscript

Movement State Implementation


I'm making an RPG where the player can freely move around the over world with the WASD keys; but when in combat the player switches to a tactical grid-based movement controlled by the mouse. I thought to use states to accomplish this; but I don't know how to properly do this.

Here is my code for my movement mechanics:

extends KinematicBody2D

export (int) var speed = 250
var velocity

var states = {movement:[Over_Mov, Tile_Mov]}
var current_state = null

func _ready():
    current_state = Over_Mov

func get_input():
    velocity = Vector2()

    if Input.is_action_pressed("ui_up"):
        velocity.y -= 1
    elif Input.is_action_pressed("ui_down"):
        velocity.y += 1
    elif Input.is_action_pressed("ui_right"):
        velocity.x += 1
    elif Input.is_action_pressed("ui_left"):
        velocity.x -= 1
    velocity = velocity.normalized() * speed

func _physics_process(delta):
    get_input()
    move_and_collide(velocity*delta)

I am using Godot's sample for movement mechanics.


Solution

  • One simple way to handle state is to use an enum with match.

    enum State { OVER_MOV, TILE_MOV }
    
    export(int) var speed = 250
    var velocity
    var current_state = OVER_MOV
    
    func handle_over_mov_input():
        velocity = Vector2()
        if Input.is_action_pressed("ui_up"):
            velocity.y -= 1
        elif Input.is_action_pressed("ui_down"):
            velocity.y += 1
        elif Input.is_action_pressed("ui_right"):
            velocity.x += 1
        elif Input.is_action_pressed("ui_left"):
            velocity.x -= 1
        velocity = velocity.normalized() * speed
    
    func handle_tile_mov_input():
        # .. handle tile mov input here
        pass
    
    func _physics_process(delta):
        match current_state:
            OVER_MOV: handle_over_mov_input()
            TILE_MOV: handle_tile_mov_input()
        move_and_collide(velocity*delta)
        if some_state_changing_condition:
            current_state = other_state
    

    If you would like to get more involved with the state pattern take a look at the State chapter from the GameProgrammingPatterns book.