Animating random movement for ai

Currently I’m trying to make a simple ai that moves to random locations. I’m confused as to why my self.ai_target_position variable is nil even though I don’t have typos and I made sure to place the functions in the correct order? (Also I just realised I did the math wrong for the ai movement I’m pretty sure (position + direction * speed * dt) but I got the direction wrong.)

local function random_position()
	return vmath.vector3(math.random(1, sys.get_config("display.width")),  math.random(1, sys.get_config("display.height")), 0)
end

function init(self)
	-- should return a vector
	self.ai_target_position = random_position()
end

function fixed_update(self, dt)
	ai_pos = go.get_position("/kid")
	go.set_position(ai_pos + vmath.vector3(self.ai_target_position.x - ai_pos.x, self.ai_target_position.y - ai_pos.y, 0) * 150 * dt, "/kid")
end

Thanks to anyone who answers.

Looks like it doesn’t. Did you print its value on init?

This becomes a infinite number quickly. So your math here is very dangerous and not very useful:

https://defold.com/codepad/#?c=#cp_sprite&s1=DYewxghsAEBmCuA7MAXAliR0BOFEBMQBbAfQAcQBnNdTACgEoAoASGwFMV5ssA3IiCgAWAOl7tUIbAGY6A4SNwFidAIwAaaJQCelEQHNOJMJlhp9dAET40lMsAjaRAdzT5hlhg03R5opYREapo6eoYoxqbmVjZ2Dk5C7OZCKJ7e0AAMzOwETEwIyLRYaIg0dJTswLDM0LValbAiEGgkKBDY4eRUNBhY0AC8OHiBXdRFjEx10GTYJSjlDU0tbR1GFGO9IgAeIYvNre2d6z2YItq7VUsHqxHHRSIAXtm5TKCQMPvreQWovdDwZHwgnYCyqmncNTqnyoA2g+hABjW3XGlhEnlY8JEFVuyN6dGhlGgAGpoPxBKJxJIZKDGvsVkdcacttAALTQAnbC605aHJEbU7aVnslrrM6aLLQABU0FUAFYMlLoO5NKj0Tl8N8kL9MNBMCQiOxKJQIIYaZoDUaTewSG5zYbjYZdgR2NhmEx1ZrCn89SUyPB5hUweztYgbfhNBAQ26PfktUVdaGOKAIPgadHckA

Ah no I didn’t, that was my bad, I got this error so I thought it wasn’t necessary

Where the actual error is located at.

go.set_position(ai_pos + vmath.vector3(self.ai_target_position.x - ai_pos.x, self.ai_target_position.y - ai_pos.y, 0) * 150 * dt, "/kid")

With setting the position, all I want is that the game object to move to the target location and then get a new target location and move there once it reaches that location, I also realised that I probably could just animate this but I don’t know if it’s a good either to check every tick whether the game object’s current location is equal to target location and instead be event based?

local function ai_reached_target(self)
	if go.get_position("/kid") == self.ai_target_position then
		self.ai_target_position = random_position()
		go.animate("/kid", "position", go.PLAYBACK_ONCE_FORWARD, self.ai_target_position, go.EASING_INQUAD, 1)
	end
end

Thanks for replying by the way.

Something like this(check source code)?

1 Like

Ah yes, thank you so much. I wonder if it would be possible to do it based on a timer? As long as the timer’s still running, the random movement continues and cycles through random positions. I see why you made a table though, and that makes complete sense. Ah wait, you can pass a function into a timer. Just tried that and got an error.

Why not! Just add a timer and when its complete cancel go.animate or toggle a boolean.

1 Like

Yea, that makes sense, I’m just confused on how to write it.

local function ai_move_to_pos()
	ai_target_position = random_position()
	if go.get_position("/kid") ~= ai_target_position then
		go.animate("/kid", "position", go.PLAYBACK_ONCE_FORWARD, ai_target_position, go.EASING_INQUAD, 1)
	end
end

function init(self)
	timer.delay(0, false, ai_move_to_pos)
end

So I understand what this means is that the timer would activate instantly, it wouldn’t loop, and calls the function above (which works), where would the boolean come in, if you can explain that, and while I understand your code, with timers I don’t know how functions with parameters would be handled, and I don’t think Lua has delegates although you can kinda work that in.

Did you read this:

And this:

What is your point of using 0 on timer.delay? And why did you set its repeat to false? Instead of 0,false why don’t you just call the function itself? Is this what you want?

You should spend more time to figure this out, I bet you will :slight_smile:

4 Likes

Sorry for the late response, I think I almost figured it out like you said and I did read the links beforehand, I reset the timer to true, ultimately the goal is that I’m trying to do a minigame similar to the Warioware games (the reaction ones), have the ai move to a place, then do something, pause, then gives the player time to react. Because it’s just a prototype I’m not actually going to do animations, I think this might be a wonky way to do it but it does seem to be working, you have the timer, which delays longer than the time that the animation takes.

  1. Timer delays, then passes a message to the script of the go that’s supposed to move.
  2. Message occurs, which then calls the method that handles the animation, once animation ends it’ll set the behavior (just by using math.random).

I think I overcomplicated it originally because I thought I would have to somehow pause the timer that controls when movement occurs, then set the behavior.

Glad you solve it.

Just I don’t understand this part(why you need it):

If it is just for a prototype and this quick solution saves the day then ok… but trusting timer against animation is not a very solid solution.

1 Like

Thanks for the heads up. Yea once I either get flipbook animations (or model animations, I wanna play around with both, it’s fun to learn), maybe there only needs to be a bit of chaining animations stated in Completion callbacks.

Idle animation → ai moves to position and plays movement animation → plays randomised animation (which is dependent on the ai’s behavior and has a set amount of frames) then chains to movement animation? I’m just getting my thoughts down on paper but I think that would make sense, hahahahahah.