Hi Godot Experts, I am relatively new to Godot and I am having an issue with random character movement on an isometric plane.

I am attempting to recreate an old game I used to play called Ninja Farm that was unfortunately deleted by the developers.

Image Reference

I would like for the ninjas (AI) to randomly move around the scene while staying within the borders of the isometric view. They will then stay in that position for a few seconds, then move in another random direction to create the effect of wandering. Any idea on how to approach this?, I have looked up previous forums and videos but none seem to be relevant to the random movement within borders.

The tilemap I am using for the ground is in isometric view and each tile is 32x16. The area of which I would like the AI to be able to move is 15 tiles by 15 tiles - a square.

Godot version 3.2.3.stable
in Engine

+1 vote

AStar path finding is going to be your best most performant option here, a video about it can be found here : https://www.youtube.com/watch?v=Ad6Us73smNs

Here is some code that does generally what you want. Note that it does not account for two characters attempting to move to the same grid position at the same time.

``````extends KinematicBody2D

var move_timer : Timer
var can_move = true
var world_destination = null
var speed = 25
var velocity_vector = Vector2.ZERO

move_timer = Timer.new()
move_timer.one_shot = true
move_timer.wait_time = 3
move_timer.connect("timeout", self, "_on_move_timer_timeout")

func _physics_process(delta: float) -> void:
if world_destination:
move_towards_world_destination(delta)
elif can_move:
set_world_destination()

func move_towards_world_destination(delta):
# move towards world_destination in sync with physics step
var direction_vector = self.position.direction_to(world_destination).normalized()
velocity_vector = move_and_slide(velocity_vector + (direction_vector * speed * delta))

# arrived at world_destination
if abs(self.position.distance_to(world_destination)) < 0.05:
# snap our position to world_destination to avoid any funny business
self.position = world_destination
world_destination = null
velocity_vector = Vector2.ZERO
can_move = false
move_timer.start()

func set_world_destination():
var move_directions = [Vector2.UP, Vector2.DOWN, Vector2.LEFT, Vector2.RIGHT]
var current_grid_position = get_current_grid_position()
randomize()
# set a random adjacent tile to our potential_grid_position
var potential_grid_position = current_grid_position + move_directions[randi() % move_directions.size()]

# make sure we select a tile within our wonder zone
while not is_inside_wander_zone(potential_grid_position):
randomize()
potential_grid_position = current_grid_position + move_directions[randi() % move_directions.size()]

# set our world_destination
world_destination = get_world_position_from_grid_position(potential_grid_position)

func is_inside_wander_zone(grid_position):
# here is where you can define the grid coordinates of your wander zone
var wander_zone_start = Vector2(0,0)
var wander_zone_end = Vector2(15,15)
var inside_wander_zone = false
if wander_zone_start.x <= grid_position.x and grid_position.x <= wander_zone_end.x:
if wander_zone_start.y <= grid_position.y and grid_position.y <= wander_zone_end.y:
inside_wander_zone = true
return inside_wander_zone

# here is where you would need to translate self.position to a grid position
func get_current_grid_position():
var some_translation
var current_grid_position = self.position * some_translation
return current_grid_position

# here is here you would need to translate a grid position to a world position
func get_world_position_from_grid_position(grid_position):
var some_translation
var current_world_position = grid_position * some_translation
return current_world_position

# when our timer times out we can move again
func _on_move_timer_timeout():
can_move = true
``````
by (3,898 points)
selected by
Making a sprite randomly move within borders