reckfellENGINE

Player movement and hits

Complete DodgePlayer.cs: bounded movement without faster diagonals and a single hit event.

On this page

Attach Scripts/DodgePlayer.cs to the CharacterBody2D root from the player prefab. File and class names must match. Use the complete class:

C#
using Reckfell;

public partial class DodgePlayer : CharacterBody2D
{
    [Signal] public delegate void HitEventHandler();
    [Export] public float Speed { get; set; } = 220.0f;
    public bool Active { get; set; } = true;

    public override void _Draw()
    {
        DrawRect(new Rect2(-14, -14, 28, 28), new Color(0.2f, 0.4f, 1.0f));
    }

    public override void _PhysicsProcess(double delta)
    {
        if (!Active)
        {
            Velocity = Vector2.Zero;
            return;
        }

        Velocity = Input.GetVector("move_left", "move_right", "move_up", "move_down") * Speed;
        MoveAndSlide();
        Position = new Vector2(
            Mathf.Clamp(Position.X, 14, 626),
            Mathf.Clamp(Position.Y, 14, 346));
    }

    public void StartAt(Vector2 position)
    {
        Position = position;
        Velocity = Vector2.Zero;
        ResetPhysicsInterpolation();
        Active = true;
    }

    public void TakeHit()
    {
        if (!Active)
            return;
        Active = false;
        Velocity = Vector2.Zero;
        EmitSignal(SignalName.Hit);
    }
}

How movement works

Input.GetVector() reads the four configured actions and limits vector length to one. Speed uses pixels per second. MoveAndSlide() applies the physics step itself; do not multiply Velocity by delta again.

After movement, position is clamped to X = 14–626 and Y = 14–346. The 14-pixel margin is half the player's side. These values are specific to the 640 × 360 arena, an explicit prototype limit rather than automatic adaptation to any world size.

There are no solid walls here. CharacterBody2D supplies the movement API; Clamp sets the screen boundary, while the hazard's separate Area2D detects a hit.

Starting and ending a round

StartAt() sets position, clears velocity and interpolation, then enables controls. Call it after adding the player to the tree. TakeHit() disables Active before emitting Hit, preventing several overlaps from producing repeated defeats. The level controller subscribes to that signal.

At Active = false, the script skips movement polling and clears velocity. UI does not automatically block Input; gameplay control is explicitly disabled here.

Expected result

After the full build, F6 on Player.rprefab shows a square moving with WASD / arrows and staying entirely inside the window. Releasing controls stops it. If it does not move, check game-window focus, Input Map bindings and the attached class. In the complete level, controls start only after pressing the start button.

Reckfell Engine documentationBack to top ↑
QUICK LINKSGetting startedEntity hierarchyC# & .NET 10Scenes and prefabs
Reckfell guides and full API K
reckfellENGINE
RECKFELL ACCOUNT

Sign in

Sign in to your Reckfell account.

One account for the entire Reckfell platform.