How to Import Sprite Strips into GameMaker
Import sprite strips into GameMaker with the _stripN naming rule, set the origin, pick a collision mask that does not snag on walls, and keep pixel art sharp.
By SpriteLab team9 min read
The short answer
Name the file so it ends in _stripN, where N is the number of frames (for example spr_player_walk_strip6.png), and import it into a sprite. GameMaker reads the suffix and cuts the image into N equal frames from left to right. Then set the origin to Bottom Centre for characters, give the sprite a manual rectangle collision mask (or a separate mask sprite), set the playback speed in frames per second, and turn off 'Interpolate colours between pixels' if the game is pixel art.
The rest of this guide explains each of those settings, the problems they prevent, and how to read per-frame hitboxes from a JSON file in GML. Menu names are from GameMaker 2024 releases; older versions of GameMaker Studio 2 use the same settings in slightly different places.
How the _stripN rule works
GameMaker checks the end of an image's file name when you import it. If the name ends in _strip followed by a number, the image is treated as a horizontal strip and split into that many frames of equal width. A 384×64 file called spr_slime_idle_strip6.png becomes a 64×64 sprite with six frames. The suffix is removed from the sprite name, so the resource is called spr_slime_idle.
The rule only works for single-row strips with frames of identical width. If the image width does not divide exactly by N, the last frame is cut short and the animation wobbles. Check the arithmetic before importing: 384 / 6 = 64, so every frame is 64 pixels wide.
- Good: spr_knight_attack_strip9.png — 9 frames, the suffix is the very last part of the name.
- Not recognised: spr_knight_strip9_attack.png — anything after the number breaks the rule.
- Not recognised: spr_knight_attack_9.png — the word strip is required.
- For multi-row sheets use Image → Convert to Frames in the Sprite Editor instead (set frame width, height, number of frames and frames per row).
Step-by-step import
This takes about a minute per animation once the file names are right:
- 01In the Asset Browser, create a new Sprite and name it after the animation, for example spr_player_walk.
- 02Click Import in the sprite window and choose the strip file ending in _stripN. GameMaker shows N frames in the frame strip at the bottom of the editor.
- 03Open the Origin drop-down and choose Bottom Centre for characters and enemies, Middle Centre for projectiles and pickups.
- 04In Collision Mask, set Mode to Manual and Type to Rectangle, then drag the rectangle so it covers the feet and torso but not the weapon or a flowing cape.
- 05Set the playback speed field to Frames per second and enter the speed you want (8–12 for most pixel art walks, see the frame-count guide).
- 06Repeat for each animation, keeping the same canvas size and origin across all of a character's sprites so swapping sprite_index never shifts the character.
Origin: why Bottom Centre
The origin is the point that sits at the instance's x and y. If idle and walk have their origins in different places, the character jumps by a few pixels every time the animation changes. Bottom Centre puts x, y between the feet, which makes ground checks simple (the ground is at y), makes depth sorting by y correct in top-down games, and keeps a horizontal flip with image_xscale = -1 from moving the character sideways.
This only works if every frame has the character standing on the same baseline. Strips exported by SpriteLab are built that way: each frame is the same size, the figure is aligned to a shared ground line, and the background is transparent. If you made the frames yourself, put a temporary 1-pixel line at the feet in your editor and check that it never moves.
Collision masks that do not snag on walls
By default GameMaker builds the mask automatically from the opaque pixels of each frame. That is convenient and almost always wrong for a moving character: when the sword swings out in an attack frame, the mask grows, and the character can get pushed into or stuck inside a wall. 'Precise per frame' makes this worse and is also slower.
The standard fix is to separate the body that collides with the world from the art that animates. Either give every character sprite the same manual rectangle, or create one plain sprite (for example spr_player_mask, a 12×20 rectangle with Bottom Centre origin) and assign it once:
// Collide with the world using one fixed box,
// whatever animation is playing.
mask_index = spr_player_mask;
sprite_index = spr_player_idle;
image_speed = 1; // play at the sprite's own fpsSwitching animations in GML
Set sprite_index when the state changes, and reset image_index only when you switch to a different sprite, otherwise the animation restarts every step and appears frozen on frame 0. For one-shot animations such as an attack, the Animation End event fires when the last frame has played; use it to return to idle.
var _move = keyboard_check(vk_right) - keyboard_check(vk_left);
hsp = _move * 2;
var _next = (_move != 0) ? spr_player_walk : spr_player_idle;
if (attacking) _next = spr_player_attack;
if (sprite_index != _next) {
sprite_index = _next;
image_index = 0;
}
if (_move != 0) image_xscale = sign(_move);Keeping pixel art sharp
Blurry pixel art in GameMaker almost always comes from texture interpolation or from a camera that scales by a fraction. Turn off interpolation in Game Options → (your platform) → Graphics → Interpolate colours between pixels, or call gpu_set_texfilter(false) at game start. Then make the camera size a whole-number fraction of the viewport: a 320×180 camera in a 1280×720 viewport is exactly 4×, and the same camera in a 1920×1080 window is 6×.
Texture pages can also bleed. If you see thin lines from a neighbouring sprite at the edge of a frame, increase the texture group border, keep sprites at whole-pixel positions (floor or round x and y before drawing), and avoid scaling individual sprites by non-integer amounts.
- Interpolate colours between pixels: off.
- Camera 320×180 or 640×360, viewport an exact multiple of it.
- Draw at whole-pixel coordinates; do not rotate pixel sprites by arbitrary angles.
- One pixel density for every sprite in the game.
Reading per-frame hitboxes from JSON
A collision mask is one shape per sprite; fighting and action games need different attack and damage boxes on different frames. SpriteLab's engine pack includes a hitboxes.json file next to the strips with, for every animation and frame, a hurtbox (the body) and a hitbox (the part that reaches out — a blade, a fist, a breath attack) in frame pixels measured from the top-left corner. A frame with no strike has a hitbox of null. The boxes are detected automatically from the pixels, so treat them as a solid first draft, not a final balance pass.
Add the file under Included Files, load it once, and convert a frame box into room coordinates using the sprite's origin offset. This example checks the strike against enemies during an attack:
var _buf = buffer_load("hitboxes.json");
global.hitboxes = json_parse(buffer_read(_buf, buffer_string));
buffer_delete(_buf);
// In obj_player's Step event, while attacking:
var _frames = global.hitboxes.animations.attack.frames;
var _box = _frames[floor(image_index)].hitbox;
if (is_struct(_box)) {
var _l = x - sprite_xoffset + _box.x;
if (image_xscale < 0) _l = x + sprite_xoffset - _box.x - _box.w;
var _t = y - sprite_yoffset + _box.y;
var _enemy = collision_rectangle(_l, _t, _l + _box.w, _t + _box.h, obj_enemy, false, true);
if (_enemy != noone) with (_enemy) take_hit(other.id);
}Using SpriteLab strips in GameMaker
SpriteLab does not make GameMaker projects or objects; it makes the art and a predictable file layout. When you animate a sprite in SpriteLab and download the engine pack, the gamemaker folder contains one strip per animation already named with the frame count, such as attack_strip6.png. A 4-direction walk comes out as four strips: walk_down_strip4, walk_right_strip4, walk_up_strip4 and walk_left_strip4. Import them as above; you still set the origin, the mask and the code yourself.
Animation frames are delivered at 256 pixels tall. For pixel art that is a 128-pixel grid scaled 2× with nearest-neighbour, so if your game uses a smaller sprite size, scale the strip down by a whole number in a pixel editor before importing rather than scaling the instance in GameMaker.

Frequently asked questions
Why did GameMaker import my strip as one wide frame?
The file name must end in _strip followed by the frame count, with nothing after the number except the extension, such as walk_strip8.png. Otherwise use Image → Convert to Frames in the Sprite Editor.
What origin should a GameMaker character sprite use?
Bottom Centre for characters and enemies, so x and y sit between the feet. Use the same origin and canvas size for every animation of the character.
Should I use precise collision masks for characters?
Usually not. Use a manual rectangle or a separate mask sprite assigned to mask_index, and handle attacks with separate per-frame hitboxes.
How do I stop pixel art from blurring in GameMaker?
Turn off 'Interpolate colours between pixels' in Game Options (or call gpu_set_texfilter(false)) and keep the camera at a whole-number fraction of the viewport size.