Godot Version
4.3
Question
I am trying to do tile based movement, but by mouseclick in a 2d world. So you click a tile, on release, the character moves one tile per tick till we get to the clicked tile.
All good.
I have a giant map. and a player.
To not have to load in the entire map, I figured I would use AStarGrid2D and just add it to my player script.
I would then simply only load the current VisibleRect() into the A* to limit the amount of computation needed.
However, I’m getting lost in trying to figure out which coordinates go where.
Here is my code.
public override void _Ready()
{
_sprite = GetNode<AnimatedSprite2D>("AnimatedSprite2D");
_map = GetParent().GetNode<TileMapLayer>("Map");
_tileSize = _map.TileSet.TileSize;
_aStar = new AStarGrid2D();
_sprite.Play("Idle Down");
_aStar.DiagonalMode = AStarGrid2D.DiagonalModeEnum.OnlyIfNoObstacles;
_aStar.DefaultComputeHeuristic = AStarGrid2D.Heuristic.Manhattan;
_aStar.CellSize = _tileSize;
}
private void initializeAStar()
{
_aStar.Clear();
var visibleRect = (Rect2I)GetViewport().GetVisibleRect();
_aStar.Region = visibleRect;
if (_aStar.IsDirty())
{
_aStar.Update();
}
}
public override void _Input(InputEvent @event)
{
if (@event is InputEventMouseButton mouseEvent && @event.IsActionReleased("click"))
{
var clickedTile = mouseEvent.Position;
CalculatePath(clickedTile);
}
}
public override void _PhysicsProcess(double delta)
{
if (_path != null && _currentPathIndex < _path.Count())
{
GlobalPosition = _path[_currentPathIndex] * _tileSize;
_currentPathIndex++;
}
}
private void CalculatePath(Vector2 targetTile)
{
var playerPosition = _map.LocalToMap(Position);
var targetPosition = _map.LocalToMap(targetTile);
initializeAStar();
_path = _aStar.GetIdPath(playerPosition, targetPosition, true);
_currentPathIndex = 0;
}
I reckon it goes wrong in converting between viewport coordinates, and local coordinates. - can someone make it make sense please? .
ViewPort.GetVisibleRect()
gives me global coordinates.
MousePosition gives me local.
Position gives me local.
Also I really want the player to snap to the tiles why i figured I have to get the tilemap coordinates in there somewhere.
My scene layout looks like this
|- World (tilemap)
|- Player (astargrid2d here)
|- Camera
Would it make my life ALOT easier to simply have the a* in a world script and reference it from the player to move?
Thanks in advance.