Spawn # of objects based on another object moving

I want to have a plane move on screen and drop off “minions” as it moves. I have it working, but it never stops. I can’t delete the object when it hits the end of screen nor have it stop after dropping a certain # of minions. I have this script attached to the plane as it flys from left to right.

go.property(“acceleration”, 200)
go.property(“max_speed”, 400)
go.property(“right_left”, 1)

local spawn_timer = nil
local i = 1
local numMinions = 3

function init(self)
– movement input
self.input = vmath.vector3()

-- the current direction of movement
self.direction = vmath.vector3()

-- the current speed (pixels/second)
self.speed = 0

--spawn minions  
if i<numMinions then
	spawn_timer = timer.delay(.25, true, spawnMinion)
	i=i+1
end

end

function update(self, dt)
self.input.x = self.right_left
self.direction = self.input
– increase speed
self.speed = self.speed + self.acceleration * dt
– cap speed
self.speed = math.min(self.speed, self.max_speed)

-- move the game object
local p = go.get_position()
p = p + self.direction * self.speed * dt
go.set_position(p)

-- reset input
self.input = vmath.vector3()

end

function spawnMinion(self)
local p = go.get_position()
local pos = vmath.vector3(p.x, p.y, 0)
local minion_id = factory.create("#minionfactory", pos, nil, nil, .4)
end

function final(self)
– Cancel the timer when the script is deleted
timer.cancel(spawn_timer)
go.delete()
end

...
local function spawnMinion()
  local p = go.get_position()
  local pos = vmath.vector3(p.x, p.y, 0)
  local minion_id = factory.create("#minionfactory", pos, nil, nil, .4)
end

-- this factory now manages the spawns and the timer
local function spawnFactory()
  if i < numMinions then
    spawnMinion()
    i = i + 1
  else
    timer.cancel(spawn_timer)
  end
end

function init(self)
  self.input = vmath.vector3()
  self.direction = vmath.vector3()
  self.speed = 0
 
  -- start the spawn factory
  spawn_timer = timer.delay(0.25, true, spawnFactory)
end

function update(self, dt)
  self.input.x = self.right_left
  self.direction = self.input
  self.speed = self.speed + self.acceleration * dt
  self.speed = math.min(self.speed, self.max_speed)

  local p = go.get_position()
  p = p + self.direction * self.speed * dt
  go.set_position(p)

  -- Get the current window width as defined in your game.project
  local window_width = tonumber(sys.get_config("display.width"))
  -- Check if the objects x position is greater than the screen width
  if go.get_position().x > window_width then
    go.delete()
    timer.cancel(spawn_timer)
  end
   
  self.input = vmath.vector3()
end

code not tested, hope it works
anyway, just ask if something is not clear enough

2 Likes

Thank you. I ended up putting two trigger box colliders on the sides of the screen. I’m not sure what is better…calculating the position or using a trigger collider. Both work though.

But I did have a major issue (that I couldn’t see). I was spawning all objects at ones (like 3 minions) then the pause and it would spawn 3 more…since they were on top of each other I couldn’t tell. I’m trying your spawnfactory suggestion to see if that fixes it. Thank you.

Finally figured it out. The timer runs like a co-routine. So once you go to it…it keeps running. So you have to stop the timer to stop the spawning. Maybe the documentation said that but I must have missed it. If not the documentation should make it clear that the timer runs until it is stopped.

Seems pretty clear in the docs to me? The 2nd argument determines if it auto-repeats or is a one-time thing.

3 Likes

It was the timer issue I had that was messing up my thinking (as you replied on the other topic). Now that I have the self. variables fixed I’m good to go. Thank you.

1 Like