admin管理员组文章数量:1410682
I am trying to create a Pokemon Gameboy like grid based movement in Godot, however the movement is choppy, it feels weird as when the character moves after going one tile there is a short pause after which he continues, trying to turn direction is quite the hassle as you need to stand still for a little time before you can go in a different direction, it just doesn't feel right
Here you can see my code, I am using the Dialogue Manager Add-on, which is why Input is inside the Unhandeled Input and use tweening for the actual movement as well as checking if I can actually move to the next tile
using Godot;
using Godot.Collections;
public partial class CharacterBody2d : CharacterBody2D
{
int tile_size = 16;
bool moving;
Vector2 input_dir = Vector2.Zero;
Vector2 last_dir = Vector2.Down;
AnimatedSprite2D charAnim;
Marker2D directionMarker;
Area2D actionableFinder;
public Tween tween;
public override void _Ready()
{
charAnim = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
directionMarker = FindChild("Direction") as Marker2D;
actionableFinder = GetNode<Area2D>("Direction/Area2D");
if (actionableFinder == null)
{
GD.PrintErr("Actionale Node is empty");
}
else
{
GD.Print("Found: " + actionableFinder.Name);
}
}
public override void _UnhandledInput(InputEvent @event)
{
if (Input.IsActionJustPressed("ui_accept"))
{
Array<Area2D> actionables = actionableFinder.GetOverlappingAreas();
if (actionables.Count > 0)
{
(actionables[0] as Actionable).Action();
input_dir = Vector2.Zero;
GD.Print("Hey Man!");
}
}
if (moving) return;
input_dir = Vector2.Zero;
if (Input.IsActionPressed("ui_down"))
{
input_dir = Vector2.Down;
directionMarker.Rotation = Mathf.DegToRad(0);
charAnim.Play("WalkFront");
}
else if (Input.IsActionPressed("ui_up"))
{
input_dir = Vector2.Up;
directionMarker.Rotation = Mathf.DegToRad(180);
charAnim.Play("WalkBack");
}
else if (Input.IsActionPressed("ui_right"))
{
input_dir = Vector2.Right;
directionMarker.Rotation = Mathf.DegToRad(270);
charAnim.FlipH = true;
charAnim.Play("WalkSide");
}
else if (Input.IsActionPressed("ui_left"))
{
input_dir = Vector2.Left;
directionMarker.Rotation = Mathf.DegToRad(90);
charAnim.FlipH = false;
charAnim.Play("WalkSide");
}
if (input_dir != Vector2.Zero)
{
if (!moving)
{
last_dir = input_dir;
Move();
}
}
}
public override void _PhysicsProcess(double delta)
{
if (!moving && input_dir == Vector2.Zero)
{
if (last_dir == Vector2.Down) charAnim.Play("IdleFront");
else if (last_dir == Vector2.Up) charAnim.Play("IdleBack");
else if (last_dir == Vector2.Left)
{
charAnim.FlipH = false;
charAnim.Play("IdleSide");
}
else if (last_dir == Vector2.Right)
{
charAnim.FlipH = true;
charAnim.Play("IdleSide");
}
}
}
protected void Move()
{
if (moving) return;
Vector2 motion = input_dir * tile_size;
bool canMove = !TestMove(Transform.Translated(motion), Vector2.Zero);
if (canMove)
{
moving = true;
Vector2 target_pos = Position + motion;
tween = CreateTween();
tween.TweenProperty(this, "position", target_pos, 0.35);
tween.TweenCallback(Callable.From(() => moving = false));
}
}
}
I am trying to create a Pokemon Gameboy like grid based movement in Godot, however the movement is choppy, it feels weird as when the character moves after going one tile there is a short pause after which he continues, trying to turn direction is quite the hassle as you need to stand still for a little time before you can go in a different direction, it just doesn't feel right
Here you can see my code, I am using the Dialogue Manager Add-on, which is why Input is inside the Unhandeled Input and use tweening for the actual movement as well as checking if I can actually move to the next tile
using Godot;
using Godot.Collections;
public partial class CharacterBody2d : CharacterBody2D
{
int tile_size = 16;
bool moving;
Vector2 input_dir = Vector2.Zero;
Vector2 last_dir = Vector2.Down;
AnimatedSprite2D charAnim;
Marker2D directionMarker;
Area2D actionableFinder;
public Tween tween;
public override void _Ready()
{
charAnim = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
directionMarker = FindChild("Direction") as Marker2D;
actionableFinder = GetNode<Area2D>("Direction/Area2D");
if (actionableFinder == null)
{
GD.PrintErr("Actionale Node is empty");
}
else
{
GD.Print("Found: " + actionableFinder.Name);
}
}
public override void _UnhandledInput(InputEvent @event)
{
if (Input.IsActionJustPressed("ui_accept"))
{
Array<Area2D> actionables = actionableFinder.GetOverlappingAreas();
if (actionables.Count > 0)
{
(actionables[0] as Actionable).Action();
input_dir = Vector2.Zero;
GD.Print("Hey Man!");
}
}
if (moving) return;
input_dir = Vector2.Zero;
if (Input.IsActionPressed("ui_down"))
{
input_dir = Vector2.Down;
directionMarker.Rotation = Mathf.DegToRad(0);
charAnim.Play("WalkFront");
}
else if (Input.IsActionPressed("ui_up"))
{
input_dir = Vector2.Up;
directionMarker.Rotation = Mathf.DegToRad(180);
charAnim.Play("WalkBack");
}
else if (Input.IsActionPressed("ui_right"))
{
input_dir = Vector2.Right;
directionMarker.Rotation = Mathf.DegToRad(270);
charAnim.FlipH = true;
charAnim.Play("WalkSide");
}
else if (Input.IsActionPressed("ui_left"))
{
input_dir = Vector2.Left;
directionMarker.Rotation = Mathf.DegToRad(90);
charAnim.FlipH = false;
charAnim.Play("WalkSide");
}
if (input_dir != Vector2.Zero)
{
if (!moving)
{
last_dir = input_dir;
Move();
}
}
}
public override void _PhysicsProcess(double delta)
{
if (!moving && input_dir == Vector2.Zero)
{
if (last_dir == Vector2.Down) charAnim.Play("IdleFront");
else if (last_dir == Vector2.Up) charAnim.Play("IdleBack");
else if (last_dir == Vector2.Left)
{
charAnim.FlipH = false;
charAnim.Play("IdleSide");
}
else if (last_dir == Vector2.Right)
{
charAnim.FlipH = true;
charAnim.Play("IdleSide");
}
}
}
protected void Move()
{
if (moving) return;
Vector2 motion = input_dir * tile_size;
bool canMove = !TestMove(Transform.Translated(motion), Vector2.Zero);
if (canMove)
{
moving = true;
Vector2 target_pos = Position + motion;
tween = CreateTween();
tween.TweenProperty(this, "position", target_pos, 0.35);
tween.TweenCallback(Callable.From(() => moving = false));
}
}
}
Share
Improve this question
asked Mar 7 at 20:39
GrantlbartGrantlbart
111 silver badge1 bronze badge
2
- 1 Can you add a video showing how the current movement plays out? We will better understand why it feels "choppy" and "weird" if we also see it in action – liggiio Commented Mar 8 at 10:59
- "Choppiness" is related to the frame rate and the amount of travel one does during that frame. e.g. a rate of (say) 1 pixel per 50-100 ms will look "smooth". (As would a degree of rotation). – Gerry Schmitz Commented Mar 8 at 19:13
1 Answer
Reset to default 1Your call to `Move` should be in physics process, not unhandled input. Physics process is called at a steady interval, unhandled input isn't.
本文标签: Grid based movement in Godot 43 C feeling choppy and not quite responsiveStack Overflow
版权声明:本文标题:Grid based movement in Godot 4.3 C# feeling choppy and not quite responsive - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1744910507a2631886.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论