Your hero stands in the middle. Tap the left of the screen and he turns left and fires; tap the right and he spins around and fires that way. Enemies keep walking in from both edges, and they never stop coming. This is the first guide where the game makes its own enemies instead of using ones you placed by hand, which is the single thing that turns a short level into a real game. About ten minutes in Max2D, free on Google Play, no coding anywhere.
- The Asset Store. Inside Max2D, open the Asset Store and browse ready-made characters, enemies and effects. Fastest route to something that looks like a real game.
- Your own images. Import any picture from your gallery — a drawing, a photo of a doodle, a character you already made.
- Draw them here. The built-in sprite editor is enough for a hero, an enemy and a bullet. A stick figure is genuinely fine.
Whatever you choose, none of the logic below changes, and you can swap the art at any point without rebuilding a single block.
How it works, in one paragraph
You build one enemy and one bullet, then park them off screen where the player never sees them. They're templates. A Create Object block makes copies: the hero copies the bullet each time you tap, and two invisible spawn points copy the enemy on a timer. Nothing you see during play was placed by you — it's all copies made while the game runs.
Step 1: Project and score
- New projectCreate tab, new project, leave the first scene called scene1.
- Make the score variable nowIn the scene's variables panel add a global number variable called score, starting at 0. Doing this first saves grief later: blocks pick variables from a dropdown, and a variable you haven't made yet can't be picked.
Step 2: The hero
Tap + → Sprite, pick your hero image (Asset Store, gallery, or one you drew), name the object player, put it in the middle of the screen, and give it:
| Component | Settings |
|---|---|
| Rigidbody | dynamic, gravity scale 0, fixed rotation on |
| Box Collider | roughly the size of the character |
Gravity scale 0 keeps him standing where you put him. He never moves in this game — only turns — so that's all he needs for now.
Step 3: The bullet
Tap + → Sprite, name it bullet, and drag it far below the visible area. It's a template, not a bullet: it sits off screen forever and only ever gets copied.
Give it a Rigidbody set to dynamic with gravity scale 0 and is sensor switched on, plus a small Box Collider.
Is sensor means it reports what it touches without physically shoving it. Bullets that shove would knock enemies backwards on every hit, and bullets would bump into each other in mid-air.
Two walls to catch spent bullets
Add two objects with + → Empty, name them both wall, and place one well off each side of the screen. Give each a static Rigidbody and a tall Box Collider. No sprite — they're invisible.
Then give the bullet a three-block script so it cleans itself up:
- On Play
- Is Colliding Withobject wall
- Destroy Objecton the blue true port
Without this, every bullet you ever fire keeps flying forever and the game slowly fills up with them.
Step 4: Turn and shoot
Now the hero's script. Two chains, one per side of the screen:
- When Screen Touchedevent Touch Down, location Left
- Change Position/Sizeset scale x to −1, everything else NaN. A negative scale mirrors the sprite — that's your character facing left, with no second drawing needed.
- Create Objectobject bullet, relative on, position x −45, velocity x −460. That's a bullet appearing just left of the hero and flying left.
Then the mirror image for the right: When Screen Touched (location Right) → Change Position/Size with scale x 1 → Create Object with position x 45 and velocity x 460.
Test now. Tapping each side should turn the hero and send a bullet that way. Nothing to shoot at yet.
Step 5: The enemy
Tap + → Sprite, name it enemy, and park it far below the screen next to your bullet. Another template. Give it a dynamic Rigidbody with gravity scale 0 and is sensor on, plus a Box Collider.
Its script does two jobs. First, face the right way:
- When Object LoadsRuns once, when a copy appears.
- If (True/False)expression
velocity_x < 0— "am I walking left?" - Change Position/Size, on truescale x −1, so it faces the way it's going.
Second, die when shot — a separate chain:
- On Play
- Is Colliding Withobject bullet
- Set Variable, on truescope global first, then variable score, then num value → Expression solver →
score + 1 - Destroy Object
Notice the enemy has no movement blocks at all. It gets its speed at the moment it's created, and nothing slows it down, so it keeps walking on its own.
Step 6: The spawn points
Add an object with + → Empty, name it spawner, and place it just off the left edge — far enough out that an enemy standing there is fully hidden.
Now its four-block script:
- When Object Loads
- Create Objectobject enemy, relative on, position 0,0, velocity x 130. This is the enemy that greets the player immediately.
- Repeat (Timer)seconds 1.7
- Create Object, on the timer's async portsame settings as above.
That first Create Object matters more than it looks. A Repeat (Timer) waits one whole period before its first tick, so without it the game opens with several seconds of nothing and reads as broken.
Now duplicate the spawner, move the copy just off the right edge, and change both its Create Object blocks to velocity x −130. Set its timer to 2.3 seconds rather than 1.7 — two different periods means the sides never fall into step, and the game stops feeling like a metronome.
Step 7: Losing, and the score
Back on the hero, a third chain:
- On Play
- Is Colliding Withobject enemy
- Load Scene, on trueset it to scene1 — the scene you're already in, which restarts everything.
Then + → Text near the top, with two blocks: On Play → Set Text, and in the text field choose Expression solver and enter score.
Play it
Enemies walk in from both sides, tapping a side turns and fires, hits score, and letting one reach you starts the round over. Twenty-seven blocks, and it plays forever.
| Symptom | Cause |
|---|---|
| Enemies appear in the centre, on top of you | Spawner has no Rigidbody |
| Game flashes and restarts constantly | Same thing — enemies spawning on the hero, triggering the collision |
| Nothing happens for the first few seconds | Missing the Create Object before the Repeat (Timer) |
| Only one enemy ever appears | The second Create Object is on the timer's green arrow instead of its async port |
| Enemies from one side walk backwards | The velocity_x < 0 chain is missing or wired to the wrong port |
| Bullets appear inside the hero | Position x offset too small — push it past the edge of his collider |
| Bullets fly but nothing dies | Object name typo — Is Colliding With needs exactly bullet |
| Enemies shove each other around | is sensor is off on the enemy |
| Game slows down after a while | Bullets aren't being destroyed — check the walls and the bullet's script |
| Score stays at 0 | Set Text has plain text instead of an Expression solver value |
Make it yours
- Harder over time. Change an enemy's velocity to an expression like
130 + score * 3so every kill speeds up the next wave. - Two enemy types. Duplicate the enemy template, give it different art and a different speed, and point one spawner at each. Two objects, no new blocks.
- Reloading. Put the shot on a Repeat (Timer) instead of a tap, and let tapping only turn — now timing your turns is the whole skill.
- Lives. Add a
livesvariable, subtract one on contact instead of reloading, and only load the scene at zero. - Sound. A Play Sound block on the shoot chain, another on the hit chain.
Newer to this? Start with a game in 2 minutes, then the 5-minute dodge game. For animation, saved high scores and a proper game over screen, build Flappy Bird.
Frequently asked questions
How do I make enemies keep coming?
A Create Object block on a Repeat (Timer). Build one enemy, park it off screen as a template, and let the timer copy it forever. That's the difference between a level with a fixed number of obstacles and a game that never runs out.
Why do my enemies spawn in the middle of the screen?
The spawn point has no Rigidbody. Create Object works relative to the creator's physics body, and without a Rigidbody there is no body, so the position counts as zero — the centre of the scene. Add a static Rigidbody and a small collider.
Why is nothing happening for the first few seconds?
A Repeat (Timer) waits a full period before its first tick. Put a Create Object before the timer so one enemy appears immediately.
How do I make a character face the other way?
Change Position/Size with scale x set to −1 mirrors the sprite. One drawing gives you both directions; set it back to 1 to face right again.
Do I need my own art?
No. Grab ready-made characters from the Asset Store inside the app, import an image from your gallery, or draw simple shapes in the sprite editor. Swap the art whenever you like — the logic never changes.