How to Make a 2D Fighting Game With AI in Your Browser

By Arron R.12 min read
How to make a 2D fighting game with AI in your browser comes down to two tools: WizardGenie writes the Phaser 4 state machine for idle, walk, punch, kick, block

How to make a 2D fighting game has always been the most state-machine-heavy 2D game project you can ship. Every character is a tiny program switching between idle, walking, jumping, blocking, throwing punches, throwing kicks, taking hits, getting knocked down, and standing back up. Each state has its own animation strip, its own hitbox, its own collision rules with the opponent. That is why how to make a 2D fighting game has historically meant “buy Aseprite, learn frame data, write a few thousand lines of state-management code, debug for a month.” In 2026 it is two browser tabs. WizardGenie writes the Phaser 4 state machine for both fighters. Quick Sprites generates the animated frame strips for every move. The hitbox math sits inside Phaser 4 Arcade Physics. The whole loop runs in a browser tab — no engine install, no Aseprite license, no manual frame-by-frame pixel art. Verified May 18, 2026 against Phaser 4.1.0 “Salusa” (released April 30, 2026), src/app/_home-v2/_data/tools.ts, and src/app/quick-sprites/page.tsx.

How to make a 2D fighting game with AI pipeline diagram showing prompt to sprite frames to state machine to playable Phaser 4 game, on dark navy background with purple, cyan, amber, and emerald accents
The how to make a 2D fighting game pipeline in 2026 — one prompt in, one playable two-fighter brawler out. Verified May 18, 2026.

What “how to make a 2D fighting game” actually means in 2026

The phrase how to make a 2D fighting game covers a specific game shape. Two characters face each other on a static or scrolling background. Each character has a health bar that drains when hit. A round timer ticks down. The winner is whoever drains the opponent first, or has more health when the timer hits zero. The fighting-game genre goes back to the 1980s arcade era, but the core loop has not changed since: input, animate, hit-test, react.

What changed in 2026 is who writes the code that runs that loop. Until late 2024, learning how to make a 2D fighting game meant downloading a free engine, picking up a sprite-editing tool, and grinding through six months of state-machine bugs and frame-data tuning before anything looked like a fighter. The published roundup on vibe-coding tools for games covers the broader shift: AI agents that write game code against engine APIs, and AI sprite generators that produce animated frame strips from text prompts.

Both halves of how to make a 2D fighting game now resolve to a tool call. The state machine and input handler get written by an agent inside WizardGenie. The frame strips for every move (idle, walk, punch, kick, block, hit, KO) get generated by Quick Sprites. The Phaser 4 runtime hosts everything in a browser tab. No engine install. No Aseprite. No drawing. The whole “how to make a 2D fighting game” problem reduces to picking the moves you want and tuning the values until the fight feels right.

The two-tool how to make a 2D fighting game pipeline

How to make a 2D fighting game in 2026 is a two-tool pipeline. The first tool writes code. The second tool draws frames. The runtime (Phaser 4) glues them together inside a browser tab.

Tool 1 — WizardGenie writes the state machine. WizardGenie is the Sorceress AI-first game editor, available on web at /wizard-genie/app and as a Windows desktop build for supporters. The editor wraps an AI agent around the Phaser 4 + Three.js runtime; the agent reads the project, plans the state machine, writes the JavaScript, and the build runs in the editor preview panel. The eight coding models in the WizardGenie picker, verified May 18, 2026 against src/app/_home-v2/_data/tools.ts, are Claude Opus 4.7, Claude Sonnet 4.6, GPT-5.5, Gemini 3.1 Pro, DeepSeek V4 Pro, Kimi K2.5, Grok 4.2, and MiniMax M2.7. The model-picker shootout covers when each one wins; for a fighting-game state machine, any of the top four handles the job. The cheap Planner-Executor pair (Opus 4.7 plans, DeepSeek V4 Pro types) lands at roughly one-fifth of single-frontier cost.

Tool 2 — Quick Sprites generates the frames. Quick Sprites is the pixel-art animated sprite generator at /quick-sprites. The tool wraps the retro-diffusion/rd-animation model behind a prompt input, an animation-style picker, and a credit-billing layer at nine credits per generation. The three animation styles are four_angle_walking (48x48 humanoid walk cycles in four directions), small_sprites (32x32 character poses including arm movement, looking, surprised, lay down), and vfx (24-96 pixel effects for fire, explosions, lightning, impact stars). For a 2D fighting game build, the first two styles cover idle, walk, attack, block, hit, and KO frames for both fighters.

The remaining piece is Phaser 4, the JavaScript runtime that hosts the game. Phaser 4.1.0 “Salusa” (released April 30, 2026) and the ground-up rebuild Phaser 4.0.0 “Caladan” (April 10, 2026) ship the spritesheet loader, the animation component, the Arcade Physics body system, and the keyboard input plugin a fighting game needs — everything required to wire two fighters into a working scene. The Sorceress Phaser game tutorial covers the full editor walkthrough.

Fighting game state machine diagram showing seven nodes (idle, walk, punch, kick, block, hit, KO) connected by transition arrows, with Phaser Arcade Physics, AABB hitboxes, frame data, and round timer pills at the bottom, on dark navy background
The fighting game state machine WizardGenie writes for you — seven states, deterministic transitions, Phaser Arcade Physics hit detection. Verified against Phaser 4 docs May 18, 2026.

The five-step workflow — how to make a 2D fighting game in your browser

This is the end-to-end workflow for how to make a 2D fighting game with WizardGenie + Quick Sprites + Phaser 4. Five steps, no install, no Aseprite, no Unity download.

  1. Step 1 — open WizardGenie. Load the web build inside any modern browser tab, or open the desktop build if you are on the Early Access tier. Create a new project, pick the “Phaser 2D game” template, and the agent scaffolds a working Phaser 4 scene with one example sprite.
  2. Step 2 — prompt the agent. In the chat panel, describe the game shape. A working starting prompt for how to make a 2D fighting game: “Build a two-fighter 2D street brawler in Phaser 4. Each fighter has states idle, walk, jump, light punch, heavy kick, block, hit-stun, and KO. Player one uses A/D to move, J for light punch, K for heavy kick, L for block. Player two uses arrow keys, numpad-1 punch, numpad-2 kick, numpad-3 block. Two health bars at the top, sixty-second round timer between them, KO when a bar hits zero. Use Arcade Physics for hit detection with rectangular hitboxes per attack frame.” The agent reads the project, plans the file structure (Fighter class, GameScene, HUD overlay, input handler), and generates every file. The build runs live in the preview panel inside ninety seconds.
  3. Step 3 — generate sprite frames in Quick Sprites. Open Quick Sprites in a second tab. For each fighter, generate six strips: one idle (4 frames), one walk (4 frames, the four_angle_walking style covers up-right-down-left in one strip), one light punch (4 frames), one heavy kick (4 frames), one block (1 frame static), one hit (3 frames). Each strip is nine credits via the retro-diffusion/rd-animation model. A two-fighter roster ships in roughly five minutes of generation time and ninety credits per fighter. The AI sprite generator deep-dive covers prompt patterns that produce consistent characters across strips.
  4. Step 4 — wire the sprites into the state machine. Drag the downloaded PNG strips into the WizardGenie project folder. Tell the agent: “Load the fighter sprite strips from the assets folder. Map idle to fighter1_idle.png at 4 frames, walk to fighter1_walk.png at 4 frames, light punch to fighter1_punch.png at 4 frames, heavy kick to fighter1_kick.png at 4 frames, block to fighter1_block.png at 1 frame, hit to fighter1_hit.png at 3 frames. Repeat for fighter2. Register each as a Phaser animation and call sprite.play(key) per state.” The agent edits the Fighter class to swap animations on every state transition.
  5. Step 5 — tune the fight. The build is playable. The remaining work is tuning: light punch damage 6, heavy kick damage 14, hit-stun duration 18 frames, block damage reduction 80 percent, walk speed 160 px/sec, jump velocity 420 px/sec, gravity 900 px/sec. Tell the agent to expose those as constants at the top of the Fighter class so the round-by-round tuning happens by editing numbers. The whole how to make a 2D fighting game flow lands at three to four hours from blank tab to playable build.

The Phaser 4 state machine WizardGenie writes for you

The state machine is the heart of any fighting game. WizardGenie writes it as a currentState string on the Fighter class, an update() method that dispatches per state, and per-state enter and exit hooks that swap the sprite animation. Finite-state machines are the standard model for this. Verified against the Phaser 4 Sprite documentation May 18, 2026:

class Fighter extends Phaser.Physics.Arcade.Sprite {
  constructor(scene, x, y, key) {
    super(scene, x, y, key);
    scene.add.existing(this);
    scene.physics.add.existing(this);
    this.health = 100;
    this.currentState = 'idle';
    this.stateTimer = 0;
  }

  setState(next) {
    if (this.currentState === next) return;
    this.currentState = next;
    this.stateTimer = 0;
    this.play(`${this.texture.key}_${next}`);
  }

  update(time, delta, input) {
    this.stateTimer += delta;
    switch (this.currentState) {
      case 'idle':
        if (input.left || input.right) this.setState('walk');
        if (input.punch) this.setState('punch');
        if (input.kick) this.setState('kick');
        if (input.block) this.setState('block');
        break;
      case 'walk':
        this.setVelocityX(input.right ? 160 : -160);
        if (!input.left && !input.right) this.setState('idle');
        if (input.punch) this.setState('punch');
        break;
      case 'punch':
        if (this.stateTimer > 320) this.setState('idle');
        break;
      case 'kick':
        if (this.stateTimer > 420) this.setState('idle');
        break;
      case 'hit':
        if (this.stateTimer > 300) this.setState('idle');
        break;
    }
  }
}

That is the skeleton the agent generates. The real version adds hit-stun, blockstun, knockdown, KO, jump arc, and a per-attack hitbox spawned during the active frames of the strike. Arcade Physics overlap callbacks handle the per-frame hit detection between the attacker hitbox and the defender body. The agent writes all of it on the first prompt; you read the code, ask for changes in plain English (“double the heavy-kick reach”, “add a low-block stance”), and the agent edits the file in place. That is what how to make a 2D fighting game looks like when the typing problem is solved for you.

Five-step how to make a 2D fighting game with AI workflow diagram showing open WizardGenie, prompt the agent, generate sprites in Quick Sprites, wire the state machine, then play, on dark navy background with purple cyan amber emerald accents
How to make a 2D fighting game in five steps inside the browser — open, prompt, generate, wire, fight. Three to four hours end-to-end.

The Quick Sprites frame strips a 2D fighting game needs

A fighter needs six frame strips per character to feel alive: idle (small breathing motion), walk (cycle of four steps), light punch, heavy kick, block (a single static guard pose), and hit (the recoil from taking damage). KO is the final pose at the end of the hit cycle. Optional extras: jump (rising and falling frames), crouch, special attack. Most playable prototypes ship with six strips per fighter and add the extras during tuning.

Quick Sprites handles every one of those with the retro-diffusion/rd-animation model, verified May 18, 2026 against src/app/quick-sprites/page.tsx. The four_angle_walking style at 48x48 is the right pick for the walk and idle strips on humanoid fighters because the model produces consistent four-direction motion in a single grid. The small_sprites style at 32x32 handles attacks, blocks, hits, and KO poses through its arm-movement and surprised / laying-down preset rows. Each strip costs nine credits. A full fighter (six strips) runs roughly fifty-four credits and ships in about five minutes of total generation time.

Prompt patterns that work: “pixel-art warrior in blue gi, idle stance, hands at sides, slight breathing motion, side view” for idle; “pixel-art warrior in blue gi, throwing a straight right punch, side view, four frames windup-strike-extend-retract” for the light punch; “pixel-art warrior in blue gi, throwing a high right kick, side view, four frames windup-strike-extend-retract” for the heavy kick. Match the prompt style across all six strips for the same fighter so the character identity stays consistent. The sprite-sheet walkthrough covers the consistency-trick prompt engineering in depth, and the Pokemon-style sprite generator post shows the same pattern applied to creature characters — same approach works for any humanoid fighter or original creature roster.

Drop the fighters into a Phaser 4 scene

With the sprites generated and the Fighter class written, the last step is loading the strips into a spritesheet and registering the animations. The agent writes this in the GameScene preload() and create() methods. Verified against the Phaser 4 spritesheet loader docs May 18, 2026:

class GameScene extends Phaser.Scene {
  preload() {
    this.load.spritesheet('p1_idle',  'assets/p1_idle.png',  { frameWidth: 48, frameHeight: 48 });
    this.load.spritesheet('p1_walk',  'assets/p1_walk.png',  { frameWidth: 48, frameHeight: 48 });
    this.load.spritesheet('p1_punch', 'assets/p1_punch.png', { frameWidth: 48, frameHeight: 48 });
    this.load.spritesheet('p1_kick',  'assets/p1_kick.png',  { frameWidth: 48, frameHeight: 48 });
    this.load.spritesheet('p1_block', 'assets/p1_block.png', { frameWidth: 48, frameHeight: 48 });
    this.load.spritesheet('p1_hit',   'assets/p1_hit.png',   { frameWidth: 48, frameHeight: 48 });
  }

  create() {
    this.anims.create({ key: 'p1_idle',  frames: this.anims.generateFrameNumbers('p1_idle'),  frameRate: 6,  repeat: -1 });
    this.anims.create({ key: 'p1_walk',  frames: this.anims.generateFrameNumbers('p1_walk'),  frameRate: 10, repeat: -1 });
    this.anims.create({ key: 'p1_punch', frames: this.anims.generateFrameNumbers('p1_punch'), frameRate: 14, repeat: 0  });
    this.anims.create({ key: 'p1_kick',  frames: this.anims.generateFrameNumbers('p1_kick'),  frameRate: 12, repeat: 0  });
    this.anims.create({ key: 'p1_hit',   frames: this.anims.generateFrameNumbers('p1_hit'),   frameRate: 12, repeat: 0  });

    this.p1 = new Fighter(this, 200, 400, 'p1_idle');
    this.p2 = new Fighter(this, 600, 400, 'p2_idle');
  }
}

That is the entire load + register step. Each animation gets a key, a frame array generated from the spritesheet, a frame rate, and a repeat count. The Fighter setState() method calls this.play(`${this.texture.key}_${next}`) per state transition; Phaser handles the animation crossfade and frame timing. With this scaffold in place the game runs — two fighters trade hits inside the browser, health bars drain, the round ends at zero. The how to make a 2D fighting game journey from blank tab to playable build is done.

Five mistakes that ruin a 2D fighting game build

  1. One giant state-machine switch instead of per-state classes. A six-state fighter fits in one switch. A twelve-state fighter (with jumping, crouching, blockstun, hit-stun variants, KO, special attacks) does not. Ask the agent to refactor to per-state classes with enter(), update(), exit() methods once you cross eight states. Code stays readable; bugs stop hiding in nested if-trees.
  2. Animation frame rates picked from intuition. Real fighting games use frame data: a fast jab might run 3 startup, 2 active, 6 recovery (11 frames at 60 fps = 183 ms total). A heavy kick runs 8 startup, 4 active, 18 recovery. The active window is when the hitbox is live. Tell the agent to use frame counts not seconds for state-timer math, and tune the active window separately from the visual frame rate. A hitbox that never matches the visual swing is the most common fighting-game bug.
  3. Hitboxes sized to the visual sprite. Match the hitbox to the limb tip, not the sprite bounding box. A 48x48 sprite of a punching warrior has a 12x12 hitbox at the fist during the active window, not a 48x48 box around the whole sprite. The agent will default to the full sprite if you do not tell it otherwise; correct it on the first iteration.
  4. Forgetting to clear input on state transition. If the player holds J during the punch animation, the state machine will re-trigger punch on the next idle frame and the fighter will punch endlessly without input. The fix is requiring a key-up between attacks (track justDown instead of isDown on the Phaser keyboard plugin). This is the second-most-common how to make a 2D fighting game bug after hitbox mismatch.
  5. Mixing sprite styles between fighters. Two fighters with visually inconsistent art (one detailed, one chibi) breaks the fight visually even when the code is correct. Lock the Quick Sprites prompt style (palette, line weight, proportions) across every strip for both fighters. Generate fighter two with the same prompt scaffold as fighter one, swapping only the costume description. Visual consistency reads as “real game”; visual inconsistency reads as “asset flip”.

The verdict on how to make a 2D fighting game with AI

How to make a 2D fighting game in 2026 is no longer the six-month project it used to be. The state-machine code, hitbox math, input handler, HUD, and round-timer logic come out of WizardGenie in one prompt-and-iterate session. The frame strips for every move come out of Quick Sprites in five minutes of generation time. The runtime is Phaser 4.1.0 inside a browser tab. The whole pipeline (open, prompt, generate, wire, tune) lands at three to four hours from blank tab to playable two-fighter brawler. The remaining work — balancing frame data, tuning hitbox sizes, adding specials — is the fun part. The boilerplate is gone. The pixel-art grind is gone. The engine install is gone. Vibe coding applied to fighting games is exactly this: AI writes the typing-heavy state machine, AI draws the labor-intensive sprite frames, you stay in the design seat and tune until the fight feels right.

Frequently Asked Questions

How long does it take to make a 2D fighting game with AI?

A playable 2D fighting game prototype with two characters, six moves each (idle, walk, light punch, heavy kick, block, hit), basic hitboxes, and health bars takes roughly three to four hours from blank tab to playable build using WizardGenie + Quick Sprites + Phaser 4. The state machine, input handler, hitbox math, and HUD code are generated by the WizardGenie agent in one prompt-and-iterate session. The sprite frame strips for both fighters come out of Quick Sprites in five minutes of generation time, billed at nine credits per strip. The remaining hours are tuning frame timings, hitbox sizes, and damage values until the fight feels right.

Do I need to know how to code to make a 2D fighting game with AI?

No. WizardGenie writes every line of code in the project — the Phaser 4 scene, the Fighter state machine, the input bindings, the hitbox overlap callbacks, the health-bar UI, the round-timer logic, the KO screen. You describe what you want in plain English, the AI agent generates the implementation against Phaser 4 API, and the build runs live in the editor browser preview. Reading the code helps you guide the agent on the next prompt, but you do not need to write it yourself. The eight coding models inside WizardGenie (Claude Opus 4.7, Sonnet 4.6, GPT-5.5, Gemini 3.1 Pro, DeepSeek V4 Pro, Kimi K2.5, Grok 4.2, MiniMax M2.7) all handle Phaser 4 fluently.

What about sprite art — do I need to draw the fighters myself?

No. Quick Sprites is the half of the workflow that handles every frame strip. The four_angle_walking style at 48x48 covers idle and walk for both directions. The small_sprites style at 32x32 covers attacks, blocks, hits, and KO poses. Each strip costs nine credits, and a full fighter (six moves) ships in roughly five minutes. The model behind Quick Sprites is retro-diffusion/rd-animation, tuned for pixel-art sprite sheets that drop straight into Phaser 4 spritesheet loader. AI-generated reference portraits via AI Image Gen feed Quick Sprites, so the fighter visual identity flows from one tool to the next without you opening Aseprite.

Can I use Phaser 4 to make a 2D fighting game?

Yes, and it is the cleanest pick in 2026. Phaser 4.1.0 Salusa (released April 30, 2026) and the prior Phaser 4.0.0 Caladan (April 10, 2026) ship the spritesheet loader, the Arcade Physics body system, the animation component, the keyboard input plugin, and the GameObject tree that a fighting game needs. WizardGenie agent is wired against the Phaser 4 API surface and can scaffold a working two-fighter scene in one prompt. Arcade Physics handles rectangular hitboxes for hit detection between attacks and bodies. The animation component plays the right strip per state. The whole game runs in a browser tab.

How does the fighting game state machine work in code?

Each fighter is a small finite-state machine. States are idle, walking, jumping, attacking (light/heavy), blocking, hit-stun, knockdown, and KO. Transitions are driven by inputs (keys), timers (frame counts inside an attack), and collisions (hit detection from the opponent). WizardGenie generates this as a currentState string field on a Fighter class, an update() method that dispatches per state, and per-state enter and exit hooks that swap the active sprite animation strip. The hit detection uses Phaser Arcade Physics overlap callback between an attack hitbox spawned during the active frames of a strike and the opponent body. Damage is applied on overlap, the opponent transitions to hit-stun, and the round-end check fires when a health bar reaches zero.

What models does WizardGenie use to write a 2D fighting game?

WizardGenie ships an eight-model picker for the coding side, verified May 18, 2026 against src/app/_home-v2/_data/tools.ts: Claude Opus 4.7, Claude Sonnet 4.6, GPT-5.5, Gemini 3.1 Pro, DeepSeek V4 Pro, Kimi K2.5, Grok 4.2, and MiniMax M2.7. For a fighting game build, the cleanest pick is the Planner-Executor pair: Claude Opus 4.7 plans the state machine and the hitbox math at five dollars input per million tokens and twenty-five dollars output, then hands the typing work to DeepSeek V4 Pro at zero point four three five input and zero point eight seven output per million tokens (75 percent promo through May 31, 2026; list one point seven four input and three point four eight output). The combined cost lands at roughly one-fifth of a single-frontier run. Pick any of the other six models if your project requires a specific context window or latency envelope.

Sources

  1. Phaser v4.1.0 release notes
  2. Phaser 4 Sprite documentation
  3. Phaser 4 Arcade Physics documentation
  4. Fighting game — Wikipedia
  5. Finite-state machine — Wikipedia
  6. Sprite (computer graphics) — Wikipedia
  7. Vibe coding — Wikipedia
Written by Arron R.·2,722 words·12 min read

Related posts