In this lesson, we'll use a factory to spawn some asteroids around our ship. These will appear off-screen and then move toward the center.
Open the asteroid.script file and delete the random_direction function we’re going to rewrite it to match the new behavior we want.
Instead of picking a completely random direction, we’ll make the asteroids move toward the center of the screen.
So start by removing all the code inside the random_direction function. We’ll now write a new version from scratch.
[69-85] - Delete the function
In this new function, we want our asteroid to move toward the center of the screen. To do that, we need to calculate the direction from the asteroid’s current position to the center.
The formula to get a direction between two points is:
direction = target_position - start_position
Below is our new function, called move_to_center. Take your time to read through it and try to understand how it works on your ow
[70–72] - First, we calculate the center position — this is the target our asteroid will move toward.
[75] - Then, we get the current position of the asteroid.
[78–79] - Here we apply the formula to get the direction vector toward the center. We subtract each axis (x and y) to get a proper direction.
[82] - Finally, we normalize the direction vector so that it only gives the direction, not the magnitude.
When you calculate a direction between two points (like moving from A to B), the result is a vector that points the right way but its length (also called magnitude) depends on how far apart the points are.
If you use this raw vector for movement, your object will move faster when it's far away and slower when it's close, which is usually not what you want.
By normalizing the vector, you make its length exactly 1, keeping only the direction and removing the distance.
This way, you can multiply it by a constant speed to make your object move at a consistent rate, no matter how far it is.
Now let’s go back to the init function and call our freshly written move_to_center function to give the asteroid its direction
[99] - Let's remove the old call to random_direction.
[101] - And now, use our brand-new move_to_center function instead!
Launch the game to see the result. The asteroid should now move toward the center of the game.
Before setting up our spawning factory, we need to create a collection that contains the different types of asteroids. This collection will serve as a reference to dynamically spawn our game objects.
Why?
Because you can’t dynamically spawn any game object directly. You can only spawn game objects that have been compiled ahead of time, these are called Game Object Compiled (GOC) files. But a game object is only compiled when it’s part of the build.
That’s why we’ll place our asteroid game objects inside a collection and include this collection in the game build. This way, the asteroids will be compiled (even if they’re not loaded at the start of the game), and we’ll be able to spawn them dynamically using their respective .goc names.
So let’s create a new collection:
Open the asteroid folder, create a new collection file, and name it “asteroids”.
Add each asteroid game object to our new collection.
Drag and drop asteroid_l.go and asteroid_s.go into the "asteroids" collection.
You don’t need to move the game object, just add them inside the collection.
Next, open asteroid_factory.go.
Attach the asteroid_factory.script we created earlier, and also add a Factory component.
At the end, your game object should look like this:
Then, click on the Factory component and set the Prototype to asteroid_l.go.
Also, make sure to check the Dynamic Prototype box.
Now our spawner is almost ready! Before writing our script, there’s one last thing to do: add a Collection Proxy component.
But what is a Collection Proxy component?
According to the Defold documentation:
The Collection Proxy component is used to load and unload new game “worlds” dynamically based on the content of a collection file. It can be used to implement switching between game levels, GUI screens, narrative scenes throughout a level, loading/unloading mini-games, and more.
You might be thinking: “Okay, but we’re not loading new levels or scenes here.” That’s true, we won’t do that in this module.
But in future modules, it will be useful.
For now, the Collection Proxy will simply reference our asteroid collection, which contains the asteroid game objects. This setup will generate a compiled game object (.goc) file for each asteroid.
So, add a Collection Proxy component, and in the Collection input field, select our asteroids.collection.
Our spawner is ready, the final major step is to code the behavior we want.
Open asteroid_factory.script and delete all the existing code.
Here’s the start of our new function:
[1] — An exported property to set the number of asteroids we want to spawn.
[4–5] — We store the screen size in constant variables again.
[6] — The size of our sprite.
Next, add an init function and write the following code:
[9–12] – As with our asteroid behavior, we set up randomness to ensure it works correctly.
[14–18] – This table references our .goc files. Notice the path of the .goc files, they correspond to where our game objects are located.
[20] – A variable that will act as a timer.
[21] – This variable will be our countdown.
[22] – Finally, we store the number of asteroids to spawn, so we know how many to create
Let’s implement our timer. The timer needs to increase until it reaches the wait_time variable. When that happens, it should reset and spawn an asteroid.
So, let’s create an update function just after the init function and write the following code:
[26] – We increase the timer by the delta time.
[27–28] – If the timer is greater than or equal to our wait_time, we reset it.
[29–30] – If there are still asteroids left to spawn, we call our future spawn_asteroid() function.
Let’s create our spawn_asteroid() function.
Go back to the top of the script, just before the init function, and create a new function called spawn_asteroid().
[11] – A simple print statement to confirm in the console that the spawn function is working.
[12] – We decrease the remaining number of asteroids to spawn.
[14] – We create a variable called position. This variable will be assigned the result of a function named random_spawn(), which returns a random position around the screen.
We're going to implement the random_spawn function and come back to the spawn_asteroid function after.
So, how will the random_spawn function work?
We want to spawn an asteroid outside the screen, but near a side of the game screen, and we have four sides: top, right, bottom, and left.
Our function will choose a random side and spawn an asteroid along the axis of the chosen side then return this off‑screen position so the spawner can use it .
Go back to the script and create the random_spawn function just before the spawn_asteroid function.
Then, write the following code:
[10] – Declare a position vector.
[11] – Pick a random side with math.random(): 1 = top, 2 = right, 3 = bottom, 4 = left.
[13–29] – Use an if / elseif block for each side:
• Example (top): choose a random x between 0 and the screen width, and set y just off-screen on the top side.
• Do the same for the other sides: randomize the coordinate along the chosen edge, then place the object just beyond the boundary on the perpendicular axis.
[31] – Return the position.
Go back to the spawn function, and now we’ll reference our Factory component and spawn an asteroid.**
[41] – We store the URL of the factory in a variable.
[42] – rand_type will generate a random value to choose one of the asteroids stored in the self.asteroids table.
[43] – We retrieve the path of the asteroid .goc from the table.
[45] – We need to unload the previous game object.
[46] – set_prototype allows us to set a new prototype for the factory.
[47] – Finally, we use the factory’s create method to spawn our asteroid. Note that in the last parameter, we pass the type.
You can now close the script and our asteroid_factory is ready!
But before we launch the game, we need to add the asteroid_factory to the main collection.
Open the main collection, delete all the asteroids we placed earlier, then right‑click in the Outline panel and add the asteroid_factory game object.
It’s time to launch our game!
We should now see our asteroids spawning outside the screen and moving toward the center!
🎉 Congratulations! You’ve successfully completed this part of the course. Take a moment to enjoy your game, you’ve earned it!
You can download it :Download Project: Part 4
But now… how about a challenge? 💪
Can you figure out how to make small asteroids spawn when a big one is destroyed?
I’m sure you can do it on your own! Think about what we’ve learned:
Use a factory
Trigger the spawn of small asteroids when a big asteroid explodes
Give it a try! 🚀
And don’t worry, in the bonus part of this module, we’ll tackle this together step by step.