Guide

How to make a shooting game

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.

Getting your hero, your enemy and a bullet Three ways, all fine — pick whichever is quickest for you:
  • 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

  1. New projectCreate tab, new project, leave the first scene called scene1.
  2. 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:

ComponentSettings
Rigidbodydynamic, gravity scale 0, fixed rotation on
Box Colliderroughly 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:

  1. On Play
  2. Is Colliding Withobject wall
  3. 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:

  1. When Screen Touchedevent Touch Down, location Left
  2. 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.
  3. 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 1Create 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.

"Relative" means "measured from me" With relative switched on, the position you type is an offset from the object doing the creating, not a spot on the map. So −45 means "45 to my left", wherever the hero happens to be. Switch it off and those same numbers become a fixed point in the scene.

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:

  1. When Object LoadsRuns once, when a copy appears.
  2. If (True/False)expression velocity_x < 0 — "am I walking left?"
  3. Change Position/Size, on truescale x −1, so it faces the way it's going.

Second, die when shot — a separate chain:

  1. On Play
  2. Is Colliding Withobject bullet
  3. Set Variable, on truescope global first, then variable score, then num valueExpression solverscore + 1
  4. 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.

A spawn point needs a Rigidbody, or everything appears in the centre This one catches everybody. Create Object positions copies relative to the creator's physics body, and an object with no Rigidbody has no body at all — so its position reads as zero, and every enemy materialises dead centre, on top of your hero. Give the spawner a static Rigidbody and a small collider. It stays invisible; it just needs to exist in the physics world.

Now its four-block script:

  1. When Object Loads
  2. Create Objectobject enemy, relative on, position 0,0, velocity x 130. This is the enemy that greets the player immediately.
  3. Repeat (Timer)seconds 1.7
  4. 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:

  1. On Play
  2. Is Colliding Withobject enemy
  3. 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 PlaySet 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.

SymptomCause
Enemies appear in the centre, on top of youSpawner has no Rigidbody
Game flashes and restarts constantlySame thing — enemies spawning on the hero, triggering the collision
Nothing happens for the first few secondsMissing the Create Object before the Repeat (Timer)
Only one enemy ever appearsThe second Create Object is on the timer's green arrow instead of its async port
Enemies from one side walk backwardsThe velocity_x < 0 chain is missing or wired to the wrong port
Bullets appear inside the heroPosition x offset too small — push it past the edge of his collider
Bullets fly but nothing diesObject name typo — Is Colliding With needs exactly bullet
Enemies shove each other aroundis sensor is off on the enemy
Game slows down after a whileBullets aren't being destroyed — check the walls and the bullet's script
Score stays at 0Set 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 * 3 so 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 lives variable, 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.

Build a shooter tonight

No PC, no code, no licence. Free on Google Play.

Free onGoogle Play