Building a Stickman Shooter Platformer from Scratch
I spent about three weeks last year prototyping exactly this kind of game for a client who wanted a lightweight web-based shooter. The core loop is simple enough on paper—player moves left and right, jumps, aims with the mouse, shoots at incoming enemies—but the actual implementation has enough friction points that most people who try it for the first time hit a wall within a day. I am going to walk through how I actually got it working, including the stuff nobody writes about. The fundamental interaction model runs on WASD or arrow keys for movement, spacebar for jumping, and the mouse for aiming. The tricky part is making the stickman character rotate its upper body independently of its lower body while the legs stay planted or move with the stride animation. I used a two-part bone system where the torso is a pivot point and the arms are children of that pivot. You set the arm rotation equal to the angle between the player's center position and the mouse cursor position, then clamp it to a reasonable range so the character doesn't twist its arms into their own torso. For platforming, I went with a standard AABB collision system against predefined platform rectangles rather than trying to do polygon collision. It is faster to implement, faster to run, and easier to debug when your player suddenly starts falling through a floor because two rectangles are overlapping by a pixel or two. I keep a list of active platforms and check the player's bounding box against each one every frame. When a collision is detected, I resolve it by pushing the player out along the axis of least penetration. That detail matters—a lot of tutorials skip that and just snap the player to the platform edge, which causes jittering when the player is moving diagonally while grounded.
Enemy AI and Spawning Logic
Most beginners overcomplicate the enemy behavior. You do not need pathfinding. Your enemies are on platforms, so the relevant decisions are whether to move left or right and whether to jump. I gave each enemy a state machine with three states: idle, patrol, and attack. Patrol means moving toward the player's x-coordinate at a reduced speed. Attack triggers when the player is within a certain horizontal range, and the enemy switches to a shooting state where it fires a projectile toward the player's current position with a small accuracy offset. If the player jumps, the enemy occasionally jumps too, but I added a cooldown so they do not end up bouncing uselessly on the same platform forever. For spawning, I set up an object pool rather than instantiating and destroying enemy objects every time. Pre-allocate maybe twenty enemy sprites in a static array when the game loads, keep track of which ones are active with a boolean flag, and reset their positions whenever one dies. This avoids garbage collection stutter on lower-end machines, which is a real problem in browser-based games that people forget about until they test on something like a Chromebook.
Projectile System and Hit Detection
I made both player and enemy projectiles travel as moving circles with a defined radius. Each frame you advance the projectile by its velocity vector and then check whether that circle intersects any enemy hitbox or the player hitbox, respectively. For the stickman characters, I used a capsule shape—a rectangle for the torso with circles for the head and feet—because simple rectangle hitboxes look wrong when the character is rotated or jumping at angles. A capsule is roughly two to three lines of code and it feels noticeably fairer in combat. One edge case I ran into that took me half a day to figure out: when the player is moving at high horizontal velocity and fires a shot, the projectile spawns at the previous frame's position rather than the current one. The fix was to calculate the muzzle position based on the player's current frame transform before firing, not after. If you fire after updating position, the bullet appears slightly behind the character on fast movement frames. I also added a short invulnerability window after the player gets hit—about 0.3 seconds—which prevents the frustrating scenario where a single overlapping enemy bullet pair one-shots the player from full health due to frame timing.
Get the Full Details

Rendering the Stickman
Stick figures are deceptively hard to make look decent. I drew the character using line segments with rounded caps. The body consists of a vertical line for the torso, two angled lines for the legs, two lines for the arms, and a circle for the head. Everything is drawn relative to a pivot point at the hip joint. When the character runs, the legs oscillate based on a sine wave tied to the movement speed. When idle, the legs stay planted but there is a subtle breathing animation where the torso line lengthens and shortens by a couple of pixels. The head circle bobs slightly with the movement too. For the gun, I attach it to the hand joint and rotate it along with the arm. The barrel extends forward from the hand by a fixed distance. When firing, I add a brief muzzle flash sprite at the barrel tip position for about two frames. This gives visual feedback that the weapon is discharging and helps players track their own firing rate. I skipped particle effects for blood or damage because the whole aesthetic is clean and minimal, and adding them would have required a whole extra rendering layer that slowed down the prototype on older hardware.
Level Design and Platform Layout
I structured the levels as a series of horizontal platforms at varying heights with gaps that require timing jumps to cross. The player cannot shoot while jumping, which creates meaningful risk-reward decisions. Do you hold position and risk being flanked, or jump to a new platform and leave yourself exposed in midair? I placed cover elements—low walls that the player can crouch behind—in later levels to give shooters a reason to stay in place. One thing I learned the hard way: wide gaps that require a running jump feel fine on your local machine but are nearly impossible to judge consistently across different screen sizes and framerates. I solved this by making the jump trajectory deterministic and independent of framerate. Instead of applying gravity per frame, I apply it per second and multiply by delta time. This way a player who locks in at 60fps gets the exact same jump arc as someone running at 30fps or fluctuating between the two. Without this fix, the same gap would feel easy on some machines and impossible on others, and players would blame the game rather than their setup.
Common Pitfalls and What I Would Do Differently
The biggest problem I encountered was the player's horizontal momentum carrying them into walls. When you press right and the player runs into a platform edge, they should stop, but floating point imprecision can leave them slightly embedded in the wall. On the next frame, the engine detects no collision anymore and the player floats free. The fix is to snap the player's x-position to the platform edge when a horizontal collision is resolved, not just push them out. This is a standard technique in platformer physics but easy to overlook in a quick prototype. Another issue is sound management. Browser audio with multiple simultaneous bullet sounds, jump sounds, and impact sounds creates audio clipping very quickly. I routed all sound through a simple master volume ducking system that lowers non-essential audio channels when more than four sounds are playing at once. It is not a perfect solution, but it prevents the audio from turning into noise during heavy firefights. For a more polished experience, you would want to use the Web Audio API with proper buffer management instead of triggering raw Audio objects, but that adds a significant amount of code. The game also has a hard limit on how many enemies you can comfortably put on screen before performance degrades on weaker devices. In my testing, anything above thirty simultaneous active enemies caused visible frame drops on integrated graphics. If you are targeting mobile browsers specifically, keep the active enemy count under twenty and use aggressive culling to remove off-screen enemies from the update loop entirely. They should still exist in your object pool, just not be processed.

Where to Get the Source
Stickman Shooting Platformormer source code and completed builds are available on GitHub. I published the full prototype with comments on every major system, including the collision resolution code, the state machine implementation, and the level data format. If you just want to play it, there is a WebGL build hosted on Itch.io. The repository is licensed under MIT, so you can fork it and modify it for your own projects without worrying about legal issues. The level editor I built for this project is separate from the game engine itself. It is a simple HTML canvas tool where you place platforms by clicking and dragging, then export the layout as a JSON file that the game loader reads at runtime. The export format is straightforward: an array of platform objects with x, y, width, and height properties, plus an array of spawn point objects with x, y, and direction properties. If you are building your own version, the JSON structure will adapt to whatever framework you are using.
Alternatives if This Is Too Much Work
If you do not want to build this from scratch, Unity and Godot both have platformer shooter templates that handle the physics and rendering plumbing for you. Godot in particular has a lightweight export path to WebGL that works well for stick-figure style games because the rendering overhead is minimal. The tradeoff is that you lose full control over the architecture and you have to work within the engine's conventions, which can be frustrating if you want something specific like the deterministic jump physics I described earlier. For a custom game like this, starting from scratch in a framework like Phaser or even raw Canvas API usually ends up being faster than fighting a general-purpose engine, unless you are already comfortable with that engine.