War battles tutorial Tank movement bonus (SOLVED)

Hi. I want to add a patrol movement to tanks (they are created by a factory).
However, i stumbled across a little paradox : the random point in which every tank should follow is the same for every tank : they patrol in the same way; they use the same movement vector.

How is that possible ?
Is there a solution ?

Thanks for helping me.

Are you storing the movement vector as a local variable, or in self? It must be in self to be different for each tank.

It will be a lot easier to help if you share your code where you think the problem is.

3 Likes

Hi ross,

thanks to your advice this code below works a little better ( I changed random x and y global variables into a self.* vector randomized ).
However the tanks always go to the right top of the screen.
Here it is.
Any remarks are welcomed

function init(self)
	math.randomseed(os.time())
	self.speed = 50
	self.dir = vmath.vector3()
	self.count = 2
end

function updateanimation(self)
	if self.dir ~= self.dir_bkp then
		if self.dir.y > 0 then
			msg.post("#sprite", "play_animation", { id = hash("tank-up") })
		elseif self.dir.y <= 0 then
			msg.post("#sprite", "play_animation", { id = hash("tank-down") })
		end
		if self.dir.x > 0 then
			msg.post("#sprite", "play_animation", { id = hash("tank-right") })
		elseif self.dir.x <= 0 then
			msg.post("#sprite", "play_animation", { id = hash("tank-left") })
		end
	end
end
function update(self, dt)
	local position = go.get_position()
	self.count = self.count - dt
	if self.count < 0 then
		self.dir = vmath.normalize(vmath.vector3(math.random(),math.random(),0))
		self.count = 2
	end
	local movement = position + self.dir * self.speed * dt
	go.set_position(movement)
	updateanimation(self)
	self.dir_bkp = self.dir
end
1 Like

Okay, my last code works as expected :

function init(self)
	math.randomseed(os.time())
	self.speed = 50
	self.dir = vmath.vector3()
	self.dir_bkp = vmath.vector3()
	self.count = 2
end

function final(self)
	-- Add finalization code here
	-- Remove this function if not needed
end
function updateanimation(self)
	if self.dir ~= self.dir_bkp then
		if self.dir.y > 0 then
			msg.post("#sprite", "play_animation", { id = hash("tank-up") })
		elseif self.dir.y <= 0 then
			msg.post("#sprite", "play_animation", { id = hash("tank-down") })
		end
		if self.dir.x > 0 then
			msg.post("#sprite", "play_animation", { id = hash("tank-right") })
		elseif self.dir.x <= 0 then
			msg.post("#sprite", "play_animation", { id = hash("tank-left") })
		end
	end
end
function update(self, dt)
	local position = go.get_position()
	self.count = self.count - dt
	if self.count < 0 then
		self.dir = vmath.normalize(vmath.vector3(math.random(-50,50),math.random(-50,50),0))
		self.count = 2
	end
	if position.x > 720 or position.x < 0 then
		self.dir.x = self.dir.x * -1
	elseif position.y > 720 or position.y < 0 then
		self.dir.y = self.dir.y * -1
	end
	local movement = position + self.dir * self.speed * dt
	go.set_position(movement)
	updateanimation(self)
	self.dir_bkp = self.dir
end

function on_message(self, message_id, message, sender)
	-- Add message-handling code here
	-- Remove this function if not needed
end

function on_input(self, action_id, action)
	-- Add input-handling code here
	-- Remove this function if not needed
end

function on_reload(self)
	-- Add reload-handling code here
	-- Remove this function if not needed
end
1 Like

Sidenote: math.randomseed initializes the randomizer with a specified starting point so if you feed it a number N you will get a sequence of random numbers, feeding it N again at a later point will restart the random sequence so you get the same sequence again.

The takeaway: do not call math.randomseedmore than once. In your code you call it at init for each tank, so the random sequence will reset with every tank spawn.

3 Likes

Thanks for your precision, it’s good to know that.

More info :
In the Tower Ball example, a math.randomseed(os.time()) is called in the init function of the handler script.