As the title says, trying to make my first game on here and have the enemy pick a random coordinate to patrol to when the player is outside its detection radius. It seems to be picking a coordinate and then not refreshing because it just floats to the bottom left corner whenever the player is too far away. Any help appreciated!
go.property("dir", vmath.vector3())
local reg_speed = 30
local radius = 100
function init(self)
self.dir = vmath.vector3()
self.speed = reg_speed
end
function update(self, dt)
local p = go.get_position()
local player_pos = go.get_position("Player")
local direction = player_pos - p
if vmath.length(player_pos - p) <= radius then
if vmath.length_sqr(direction) > 0 then
direction = vmath.normalize(direction)
end
go.set_position(p + direction * self.speed * dt)
else
local x = math.random(0,15)
local y = math.random(0,15)
local target = vmath.vector3(x,y,1)
local distance = target - p
if vmath.length_sqr(distance) > 0 then
distance = vmath.normalize(distance)
end
go.set_position(p + distance * self.speed * dt)
end
end
local x = math.random(0,15) – The values are pretty small.
You are basiclly randomly pick new coordinate to go in each frame. Instead you should pick new coordinate and go to it until you reach the point (or certain proximity). Also I would expect that reaching the target point takes some time instead of instatly getting there, but maybe you had different idea?
Yea its just cause the map is 15 x 15 at the moment, i figured anything higher would cause it to go out of bounds. The aim is for it to gradually get there instead of teleport. Is it worth using some kind of true/false variable to keep track of whether its reached the target or not?
Is it worth using some kind of true/false variable to keep track of whether its reached the target or not?
Yes, exactly!
Typically should logic is like
function init(self)
self.dir = vmath.vector3()
self.speed = reg_speed
-- Lets store the flag for target following:
self.is_executing_route = false
end
--First let's make some additional functions for more clarity:
local function move_closer_to_player(self, dt)
-- Implement logic for moving closer to the player. Remember to move enemy just a little bit closer to player, not to player position! Also route execution flag should be set to false.
end
local function continue_route(self, dt)
-- Implement logic for continuing the current route. Remember to move enemy just a little bit closer to target position, not immediately to the target pos! Also check if you have reached the target point here (or you are close enough).
end
local function get_new_target(self, dt)
-- Implement logic for getting a new target. Just getting new target, you can also call continue_route() to move a little bit in the same frame. Dont forget to set the is_executing_route flag to true.
end
function update(self, dt)
local player_pos = go.get_position("Player")
local enemy_pos = go.get_position()
local distance = vmath.length(player_pos - enemy_pos)
local is_player_close = distance < 100
if is_player_close then
move_closer_to_player(dt)
else
if self.is_executing_route then
continue_route(dt)
else
get_new_target(dt)
end
end
end
I have not tested the code above, I just writen it directly here, so there may be some mistakes, but I hope it gives you an idea what can be done.
Also as @Alex_8BitSkull mentioned, try using higher values for target coordinates. Maybe start with printing player coordinates when traversing map to get a grasp of range that interests you?
That was definitely part of the issue, i changed from 15x15 to 500x500 which seems to be the actual map size, just need to fix the thing where it overwrites every frame
Thanks for the help! I have something that works well enough, figured i might as well post here:
go.property("dir", vmath.vector3())
local reg_speed = 50
local radius = 100
local health = 50
function init(self)
self.dir = vmath.vector3()
self.speed = reg_speed
self.health = health
self.arrived = true
self.target = vmath.vector3()
end
function update(self, dt)
local p = go.get_position()
local player_pos = go.get_position("Player")
local direction = player_pos - p
if vmath.length(player_pos - p) <= radius then
if vmath.length_sqr(direction) > 0 then
direction = vmath.normalize(direction)
end
go.set_position(p + direction * self.speed * dt)
else
if self.arrived == true then
local x = math.random(50,450)
local y = math.random(50,450)
self.target = vmath.vector3(x,y,1)
self.arrived = false
end
local distance = self.target - p
if vmath.length_sqr(distance) > 0 then
distance = vmath.normalize(distance)
end
if self.arrived == false then
go.set_position(p + distance * self.speed * dt)
if vmath.length_sqr(self.target - p) < 1 then
self.arrived = true
end
end
end
end