## DEV Community is a community of 750,997 amazing developers

We're a place where coders share, stay up-to-date and grow their careers.

Jess

Posted on • Updated on

# Link's Movement in The Legend of Zelda (Snapping to the Grid)

I recently spoke with someone about the original Legend of Zelda (my all-time fav game) and he mentioned how the developers kept Link's movement within a grid. I never thought about it before and I thought it was really cool. It's sort of subtle but you can see here how Link seems to snap into the grid when the player turns:

I wanted to know more so I googled a bit and came across a blog post called Movement Mechanics by Troy Gilbert in which he explains what's going on. To sum it up, the sprites that make up Link and the background tiles are 16x16 but Link moves along a half-tile grid that is 8x8. The player can move Link up, down, left, or right one pixel at a time and the game will always keep Link aligned to the 8x8 grid so he can walk between obstacles and through doorways without getting caught on the edges.

I also came across a YouTube video Making Zelda in Game Maker: E015 - Aligning Player to Grid by Code Workshop. I don't use Game Maker Studio but I followed what the instructor explained and adapted it for my needs so I could see how this technique works.

Code Workshop explains that when you move in a direction Link aligns to the grid on the other axis. So if you move left or right along the X-axis, Link aligns to the Y-axis and if you move up or down along the Y-Axis he aligns to the X-axis.

Since I created my demo in Pico-8 I'm going to show my re-creation of Code Workshop's `align_to_grid` function using Lua.

``````function align(val, alignTo)
local remainder = val % alignTo
local halfway = alignTo/2

if (remainder > halfway) then
return alignTo - remainder
else
return -remainder
end
end
``````

The `align` function takes 2 parameters: `val` which is the player's current x or y location (I'll explain more in a bit), and `alignTo`, which is the amount of pixels you want your player to align to. Since Link aligns to an 8x8 grid, 8 will get passed in for `alignTo`.

`remainder` is what's left from the x or y location divided by the `alignTo` value.

If the remainder is larger than the halfway point of the pixels you want to align to, then return `alignTo - remainder`, otherwise return `-remainder`.

The value returned from this function will be added to either the player's `x` or `y` value.

For example, if the player presses `left` they want to move along the negative X-axis (`vx` is multiplied by the player's `speed` and added to the `x` value further down in the function), which means they might need to be realigned along the Y-axis. In this instance, the value returned from `align()` will be added to the player's `y` value.

``````if (btn(⬅️)) then
vx = -1
y+=align(y, 8)
end
``````

The way I did this differs a bit from how Code Workshop did it so if you are interested you should definitely check out his video.

Here is a gif of my version in Pico-8 to show the player's 16x16 sprite snapping along an 8x8 grid.

A few months ago I entered a game jam and made a game (featuring that robot buddy in the gif above) where the player moves by pixels within a 16x16 grid but the movement was...well, bad. My character stuck to the corners every time I turned because the size of the player was just about equal to the space the sprite had to move and I wasn't sure at the time how to fix it. I can't wait to go back and update the movement logic with this technique!

## Discussion (3)

DarkWiiPlayer
``````function align(val, alignTo)
local remainder = val % alignTo
local halfway = alignTo/2

if (remainder > halfway) then
return alignTo - remainder
else
return -remainder
end
end
``````

This code can be simplified a bit:

• divide the value by the grid size
• add one half to the value
• get floor of the value
• multiply by the grid size again
• subtract the value
``````function align(val, grid)
return math.floor(val / grid+0.5) * grid - value
end
``````
DarkWiiPlayer

dev.to (or rather, whatever it sues for HL) can do syntax highlighting for Lua if you start your code blocks with `<3 backticks>lua` :D

``````local function example()
print("See? This code gets colours!")
end
``````
Jess

awesome, thanks for the tip!