Skip to content
AI Sprite Maker

Pixel art animation

How to Make a Walk Cycle Sprite Sheet (Pixel Art, 4 to 8 Frames)

Published November 6, 202614 min read
On this page
  1. The four key poses
  2. 4, 6 or 8 frames
  3. Frame timing
  4. Match the animation speed to movement speed
  5. Keep the feet anchored
  6. Horizontal position: walk in place
  7. Pivot, bounding box and why sprites jitter
  8. Canvas size: 32, 48 or 64
  9. Side view vs top-down, and 4-direction sheets
  10. Front and back walks are different animations
  11. Mirroring left and right
  12. Common mistakes
  13. Previewing a strip in the browser
  14. Three ways to make one
  15. 1. Draw it by hand in Aseprite
  16. 2. Rotoscope from video
  17. 3. Generate it with AI from a motion library
  18. Before you call it done

The walk cycle is the animation players watch most. It plays every time the character moves, often for hours. A stiff idle can get away with it. A walk that slides, bobs too much or pops by one pixel every loop will be noticed within a minute.

The good news is that a pixel-art walk needs very few frames. Four can work, eight is plenty, and the same four key poses sit under all of them. This guide covers those poses, how to lay out a 4, 6 or 8-frame cycle, how fast to play it, how to keep the feet planted, how to arrange a 4-direction sheet, and three ways to produce one: by hand, from video, or with AI.

The four key poses

Every walk cycle is two steps, left and right, and each step passes through the same four poses. Get these four right and the in-betweens almost draw themselves.

  1. Contact. Both feet on the ground, legs at their widest. Front heel just touching down, back toe about to lift. Arms at their widest swing, opposite to the legs: right leg forward means left arm forward. This pose defines the stride length.
  2. Down (recoil). The front foot takes the weight, the knee bends, and the whole body drops to its lowest point. The back foot lifts off. This is where the weight sells.
  3. Passing. The supporting leg is straight under the body. The other leg swings past it, knee bent, foot off the ground. Arms are close to the body as they pass.
  4. Up (high point). The supporting leg pushes off. The body rises to its highest point, and the swinging leg reaches forward ready for the next contact.

Then repeat the four poses with the legs and arms swapped, and you’re back at the first contact. That’s eight poses for a full cycle, which is why eight frames is the classic count.

Here are the four poses in a real 8-frame cycle: the base walk from our motion library, frame by frame. The legs are widest at the two contacts (frames 2 and 6) and closest together at the passings (frames 0 and 4), and the head bobs by about a pixel over the cycle.

The base walk from the AI Sprite Maker motion library, 8 frames at 9 fps. Frame numbers are 0-based, the way engines count them.
Walk (mannequin)
Armored Knight - Walk
Old Wizard - Walk
The same poses played back: the base mannequin, then two characters fitted onto it. Same rhythm, same foot contacts, different silhouettes.

Tip Draw the two contact poses first and test them flipping back and forth. If the stride reads at that point, the rest is filling in. If it doesn’t, no amount of in-betweens will save it.

4, 6 or 8 frames

Fewer frames isn’t lazy in pixel art. At 32 px tall, a leg is 8–10 px long, and there aren’t enough pixels to show subtle in-betweens anyway. Choose the frame count by sprite size and how much screen time the walk gets.

FramesPoses used (one full cycle)Good for
4contact R, passing, contact L, passing16–32 px sprites, NES/Game Boy style, top-down RPG NPCs
6contact R, down, passing, contact L, down, passing32–48 px, a good default for most indie games
8contact, down, passing, up × 248–64 px heroes, side-scrollers where the walk is on screen a lot

With 4 frames, you lose the up and down poses, so put the bob into the passing frame: the body sits one pixel higher there than in contact. Classic RPG walks work as “step, stand, step, stand,” which is 4 frames with the standing frame used twice: contact R, neutral, contact L, neutral.

With 6 frames, dropping the up pose costs the least. The down pose carries most of the weight.

Going above 8 frames for a pixel walk rarely helps. Extra frames at small sizes become near-duplicates that make the motion look floaty rather than smooth.

Frame timing

Think in milliseconds per frame, not just FPS, because engines and tools disagree on which one they ask for. Aseprite stores milliseconds per frame. Godot’s SpriteFrames and Phaser ask for frames per second. Unity’s Animation window uses samples per second.

A full walk cycle (two steps) for a normal-paced character takes around 0.8–1.0 seconds. Divide by your frame count:

FramesFPSms per frameCycle length
46–8125–165 ms0.5–0.67 s
68–10100–125 ms0.6–0.75 s
810–1283–100 ms0.67–0.8 s
8 (run)12–1567–83 ms0.53–0.67 s

Pixel walks usually run a bit faster than the real-life one second. They read better snappy.

You can also hold frames unevenly. Holding the contact pose 1.5× longer than the others gives a heavier, more deliberate walk. A sneak works the other way round, with long passing frames and short contacts.

Match the animation speed to movement speed

The number that actually matters is how far the character moves per cycle. If one cycle has a stride of 10 px per step (20 px per cycle) and the cycle lasts 0.8 s, the character should move at 25 px/s. Move faster than that and the feet slide forward along the ground, like ice-skating. Move slower and they slide backwards, the “moonwalk”.

Measure the distance between the front foot at contact and the same foot at the next contact, then set either the movement speed or the animation speed so they match. Most engines let you scale playback speed at runtime (speed_scale in Godot, timeScale in Phaser, Animator.speed in Unity), so tie it to the character’s velocity for walks that never slide.

Keep the feet anchored

Treat the ground line as sacred. In every frame of a side-view walk, whichever foot is supporting the weight sits on exactly the same pixel row. Pick a baseline, usually the bottom row of the frame or one or two pixels above it for a shadow, and never let a planted foot leave it.

The bob happens to everything above the hips. On a 32 px character:

  • Down pose: head, torso and arms 1 px lower than in contact.
  • Up pose: 1 px higher than contact.
  • Hair, capes and loose cloth trail by one frame. They hit their lowest point on the frame after the body does.

One pixel of bob at 32 px is plenty. Two pixels starts to look like hopping. At 64 px, 2–3 px is right.

Horizontal position: walk in place

For game sprites, the walk is drawn in place: the character treads on the spot and the engine moves the sprite. The hips stay at the same x position in every frame (give or take one pixel of natural sway), and the feet move forward and back around them.

If you animate the character actually travelling across the canvas, like a film animation, you’ll have to remove that motion later. It’s far easier to draw it in place from the start.

Pivot, bounding box and why sprites jitter

Each frame of the sheet is a fixed-size cell, and the engine places that cell, not your character. If the character sits 1 px further left in frame 3 than in frame 2, the engine faithfully draws it 1 px further left. The result is a jitter that no code will fix.

Rules that prevent it:

  • One cell size for the whole character, across every animation: walk, idle, attack, hurt. If the attack needs a 64 px wide cell for the sword swing, the walk uses a 64 px wide cell too, with empty space. Otherwise switching animations shifts the character.
  • One pivot for the whole character. For most games that’s bottom-centre: the point between the feet on the baseline. Every frame puts the body’s centre of mass over that pivot.
  • Never auto-trim frames without saving offsets. Packers that trim transparent borders (TexturePacker, Aseprite’s “Trim”) are fine only if the engine reads the offsets back from the JSON. If it doesn’t, trimming moves the pivot frame by frame.
  • Check centre of mass, not bounding box. A forward-reaching arm widens the bounding box, but the body shouldn’t move. Align on the hips and the planted foot.

If you already have a jittery sheet, the free Sprite Pivot Editor helps you set a common pivot so frames line up without redrawing them.

Canvas size: 32, 48 or 64

CellCharacter heightNotes
16×1614–16 pxVery stylised. 2–3 px legs, walk is mostly a sway and an alternating foot pixel.
32×3224–30 pxThe most common size. Leaves a few pixels of headroom for the bob.
48×4836–44 pxEnough room for readable arm swing and a hand-held weapon.
64×6448–58 pxRoom for real anatomy and cloth. Needs 8 frames to look smooth.

Leave at least 1–2 px above the head for the up pose, and keep the baseline at the same row in every frame. For top-down games, 32×32 tiles with characters that overlap the tile above (32 wide, 40–48 tall) is a common, good-looking compromise.

Side view vs top-down, and 4-direction sheets

A side-scroller needs one walk, facing right, and the engine flips it for left. A top-down RPG needs at least four: down (toward the camera), left, right and up (away from the camera).

The usual layout is one row per direction, one column per frame. The common row order, used by RPG Maker and plenty of asset packs, is down, left, right, up:

row 0: down   [f0][f1][f2][f3][f4][f5]
row 1: left   [f0][f1][f2][f3][f4][f5]
row 2: right  [f0][f1][f2][f3][f4][f5]
row 3: up     [f0][f1][f2][f3][f4][f5]

The order itself doesn’t matter much, as long as it’s documented and consistent across all of the character’s sheets. Write it in the JSON or the file name: knight_walk_dlru_48x48.png saves future-you a guessing session.

For 8 directions, add the diagonals. A common order is clockwise from south: S, SW, W, NW, N, NE, E, SE.

frame → 01234567 down01234567left89101112131415right1617181920212223up2425262728293031
A 4-direction, 8-frame walk: one row per direction, frames left to right. The numbers are the frame indices most engines assign (row × columns + column).

The four directions are four different drawings of the same character, not rotations of one. Here’s one character from each side:

Armored knight facing down (front)
down
Armored knight facing left
left
Armored knight facing right
right
Armored knight facing up (back)
up

Note the shield: it’s on the knight’s back arm in every view, which is exactly why a flipped left walk wouldn’t work for this character.

Front and back walks are different animations

Down and up walks aren’t side walks seen from another angle. The legs move toward and away from the camera, so the stride shows as legs shortening and lengthening and feet alternating left and right of centre. The bob does more of the work. The arms swing toward the camera, so they overlap the body.

Mirroring left and right

Drawing only the right-facing walk and flipping it in the engine halves the work. It’s fine when the character is symmetrical. Don’t flip when:

  • the character holds something in one hand (sword, shield, torch), because flipping moves it to the other hand;
  • the design is asymmetrical: an eye patch, a side parting, a one-shoulder pauldron, a logo or text;
  • your shading uses a consistent light direction, since flipping moves the light to the other side. Many games accept this; some art directors don’t.

For diagonals in 8-direction sets, the same applies: draw SE, NE and E, flip for SW, NW and W, unless one of the above rules it out.

Common mistakes

  • Sliding feet. Movement speed doesn’t match the stride. Fix it with the maths in the timing section, not by redrawing.
  • Jitter from shifting bounding boxes. Covered above. Fix the pivot, not the code.
  • Too much bob. Two pixels of vertical bounce on a 32 px character looks like skipping. Use one.
  • Arms swinging with the legs. Right leg forward means left arm forward. Same-side swing looks robotic and is easy to miss at small sizes. Flip through the contact frames and check.
  • Knees that never bend. Straight-legged contact and passing poses make a stilt walk. The passing leg must bend, and the supporting knee bends in the down pose.
  • Too many colours. Each in-between tends to pick up a few anti-aliasing colours. Across eight frames and four directions, your 12-colour character becomes 40 colours of noise. Lock the palette before you animate. Our palette guide covers how, and the free Color Reducer can pull a drifting sheet back into line.
  • Inconsistent outline. A one-pixel outline that thickens on some frames makes the silhouette flicker. Check by viewing the sheet as a solid silhouette (fill all non-transparent pixels black).
  • First and last frame identical. In a loop, frame 8 flows into frame 1. If they’re the same pose, that pose shows for two frames and there’s a hitch every cycle. The last frame should be the pose just before the first.

Previewing a strip in the browser

You don’t need an engine to check a loop. If the sheet is a single horizontal strip, CSS can play it with steps(). This plays an 8-frame, 48 px strip at 10 FPS (8 frames × 100 ms = 0.8 s), scaled 4×:

<div class="walk"></div>

<style>
  .walk {
    width: 48px;
    height: 48px;
    background: url("knight_walk.png") 0 0 no-repeat;
    animation: walk 0.8s steps(8) infinite;
    image-rendering: pixelated;
    transform: scale(4);
    transform-origin: top left;
  }
  @keyframes walk {
    to { background-position: -384px 0; } /* 8 frames × 48px */
  }
</style>

For multi-row sheets, or to step through frames one by one, a few lines of canvas code do the job:

const img = new Image();
img.src = "knight_walk.png";
const cfg = { fw: 48, fh: 48, frames: 8, row: 0, fps: 10, scale: 4 };

const canvas = document.querySelector("canvas");
canvas.width = cfg.fw * cfg.scale;
canvas.height = cfg.fh * cfg.scale;
const ctx = canvas.getContext("2d");
ctx.imageSmoothingEnabled = false;

let frame = 0;
img.onload = () => setInterval(() => {
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  ctx.drawImage(img, frame * cfg.fw, cfg.row * cfg.fh, cfg.fw, cfg.fh,
                0, 0, canvas.width, canvas.height);
  frame = (frame + 1) % cfg.frames;
}, 1000 / cfg.fps);

Or skip the code: drop the PNG into the free Animation Previewer, set the grid, and scrub the FPS slider until the walk feels right. Then write that number down for the engine.

Three ways to make one

1. Draw it by hand in Aseprite

The traditional way, and still the best control you’ll get.

  1. Make a canvas the size of your cell (say 48×48) and draw the right-facing contact pose on frame 1.
  2. Turn on onion skin (View → Onion Skinning, or the button in the timeline) so you can see the previous and next frames faintly.
  3. Draw the opposite contact on frame 5, then passing poses on 3 and 7, then down and up poses on 2, 4, 6 and 8.
  4. Set every frame’s duration to 100 ms (select all frames, right-click → Frame Properties).
  5. Tag the frames (walk_right) so the export keeps animation names.
  6. For a 4-direction set, add tags for the other directions on the same timeline.
  7. File → Export Sprite Sheet: Sheet Type By Rows with Split Tags ticked puts each tag on its own row. Tick JSON Data with Array format and Tags in the meta, so engines and importers can read frame sizes and animations.

Expect a full 8-frame side walk at 48 px to take an experienced pixel artist a few hours, and a 4-direction set a day or more. Most of that time goes on in-betweens and keeping the character on-model across frames.

2. Rotoscope from video

Film the motion and trace or pixelate it. This gives you natural timing and weight for free, and it’s how plenty of 90s games got their fluid animation.

  • Film side-on, camera locked off on a tripod, against a plain wall. Walk on a treadmill or in place, since you want the body to stay in frame.
  • Keep the clip short: two or three full steps.
  • Drop it into the free Video to Sprite Sheet tool. It runs in your browser, so the video isn’t uploaded anywhere. Keep the frames for one clean cycle (contact to contact on the same foot) and export them as a strip. A plain wall makes the next step, the Sprite Background Remover, much cleaner.
  • Run the strip through Image to Pixel Art at your target size with a locked palette.
  • Then clean it up by hand. Raw pixelated video always needs it: lost limbs, noisy edges, a baseline that wanders by a pixel. Rotoscoping gets the motion right; you still provide the drawing.

3. Generate it with AI from a motion library

The approach we built AI Sprite Maker around. Instead of asking a model to invent a walk from scratch, which tends to produce wobbly limbs and feet that never quite land, the walk comes from a pre-made motion: a base walk cycle with the poses, timing and foot contacts already worked out. Your character is drawn onto that motion.

The result is a looping sheet with a fixed cell size and a fixed pivot, so the jitter and sliding problems above are handled before you get the file. It costs 10 credits per direction in the sprite animation tool. A 4-direction walk is four times that. Free accounts get 10 credits a day, so you can test a direction before paying for anything.

It isn’t magic. Check the output in a previewer like any other sheet, and expect to touch up a hand or a stray pixel on some frames. For a game with 20 characters that each need 6 animations in 4 directions, it changes the maths: you spend your hand-drawing time on the hero and the details, not on the 480th walk frame.

Before you call it done

Run through this list with the sheet playing in a previewer at 1× and at 4×:

  • Does it loop without a hitch? Watch the last-to-first transition.
  • Do planted feet stay on one pixel row?
  • Is the bob 1 px (or 2 px at 64 px size) and in time with the steps?
  • Do the arms swing opposite to the legs?
  • Is every frame the same cell size, with the pivot at the feet?
  • Is the colour count the same as your still sprite?
  • In game, at real movement speed, do the feet slide? Adjust speed or playback rate.

Once it passes, getting it into an engine is mechanical. See importing sprite sheets into Godot 4, Unity slicing and animation or Phaser 3. If you’re unsure which file format to export, sprite sheet formats explained compares PNG+JSON, Aseprite, TexturePacker and Godot SpriteFrames.

Sprites on this site were made with AI Sprite Maker

Tools used in this guide

All guides

Found a mistake or something out of date? Email hello@aispritemaker.com and we will fix it.