I'm new to Pico 8
I've been developing this simple game as a first project where you play as "GeK" a simple character that has animations when walking around, however i've found that when moving diagonally it makes the character faster than usual. This issue is very confusing to me and I know it has something to do with the Pythagorean theorem, and I need something called a "movement vector" My code is simple as it has a variable known as speed that is set to 1 and is used when pressing a direction to move by 1 pixel. The character also has a hat and tail that follows it and is supposed to be locked on at all times.
I'd really appreciate it if anyone knows the solution to my problem.
Here's my code if it helps with anything:
function _init()
-- setting up variables
ismoving = false
mainxposition = 63
mainyposition = 63
hatxoffset = 0
hatyoffset = -8
tailxoffset = 8
tailyoffset = 0
walkcycle = 1
animtime = 0
animspeed = 3
tailanim = 2
directionx = "left"
directiony = "up"
hatanim=18
uptailx=0
uptaily=0
uptailanim=0
uptailxoffset=0
uptailyoffset=8
upand=false
downand=false
speed=1
end
function _update()
-- player movement
ismoving = false
if btn(➡️) or btn(⬅️) then
uptailanim=0
ismoving = true
animtime += 1
if animtime > animspeed and directionx=="right" and not upand then
animtime = 0
walkcycle = walkcycle == 3 and 4 or 3
end
if animtime > animspeed and directionx=="right" and not upand then
animtime = 0
walkcycle = walkcycle == 3 and 4 or 3
end
if animtime > animspeed and directionx=="left" and not upand then
animtime = 0
walkcycle = walkcycle == 19 and 20 or 19
end
end
if btn(⬆️) or btn(⬇️) then
ismoving = true
tailanim=0
uptailanim=37
animtime += 1
if animtime > animspeed and directiony=="up" then
animtime = 0
walkcycle = walkcycle == 35 and 36 or 35
end
if animtime > animspeed and directiony=="down" then
animtime = 0
walkcycle = walkcycle == 51 and 52 or 51
end
end
if btn(➡️) then
mx=1
hatanim=34
directionx = "right"
tailanim = 5
mainxposition += speed
end
if btn(⬅️) then
mx=-1
hatanim=18
directionx = "left"
tailanim = 2
mainxposition -= speed
end
if btn(⬆️) then
my=-1
directiony="up"
mainyposition -= speed
if directionx=="right" then
hatanim=34
end
if directionx=="left" then
hatanim=18
end
end
if btn(⬇️) then
my=1
directiony="down"
mainyposition += speed
uptailanim=0
end
--talk--
if btn(❎) then
walkcycle=17
end
if btn(❎) and directiony=="up" then
walkcycle=49
end
--update hat position--
hatxposition = mainxposition + hatxoffset
hatyposition = mainyposition + hatyoffset
-- adjust tail position based on direction--
if directionx == "left" then
tailxposition = mainxposition + tailxoffset
else
tailxposition = mainxposition - tailxoffset
end
tailyposition = mainyposition + tailyoffset
if directiony == "up" then
uptailx= mainxposition + uptailxoffset
uptaily= mainyposition + uptailyoffset
else
uptailx = mainxposition - uptailxoffset
end
tailyposition = mainyposition + tailyoffset
--checking moving for animation--
if not ismoving and not btn(❎) then
walkcycle = 1
upand=false
end
if btn(⬇️) and directionx=="right" then
hatanim=22
end
if btn(⬇️) and directionx=="left" then
hatanim=21
end
if btn(⬆️) and btn (➡️) or btn(⬆️) and btn(⬅️) then
tailanim=0
upand=true
else
upand=false
end
if btn(⬇️) and btn (➡️) or btn(⬇️) and btn(⬅️) then
tailanim=0
downand=true
else
downand=false
end
if btn(⬆️) and btn (➡️) and ismoving then
uptailanim=38
end
if btn(⬆️) and btn (⬅️) and ismoving then
uptailanim=37
end
if not ismoving and not btn(❎) and uptailanim==37 then
walkcycle = 33
end
end
function _draw()
-- draw sprites--
cls()
spr(walkcycle, mainxposition, mainyposition)
spr(hatanim, hatxposition, hatyposition)
spr(tailanim, tailxposition, tailyposition)
spr(uptailanim,uptailx,uptaily)
end |
So, here's a brief summary of why your character moves too fast when going diagonally in case you want to understand. If your character goes 1 pixel to the right, then 1 pixel up, then their movement is going along the sides of a 1 pixel square from corner to corner. If your character goes the length of 1 pixel's side, but moving diagonally, then they're destination would land on the edge of a quarter-circle (this is literally part of the definition of a circle). Here's an image to show this:
If I had it with more precision, the purple arrows would be the same size as the red arrow.
You're right that the pythagorean theorem is relevant, but it's more generally that trigonometry is relevant. A movement vector is just one way to frame the problem that's useful in a lot of games. If your game only allows 8 directions of linear movement, without any acceleration, then movement vectors are overkill in my opinion.
Instead, let me just tell you the answer to how the movement works out: to move a character diagonally at a 45 degree angle for a length of 1 pixel, you move that character approximately .7 pixels along each axis. The exact amount is the square root of 2 divided by 2, so you want more precision just use a calculator, but .7 is usually good enough. If you want to move that character more than 1 pixel, then just multiply the amount of pixels by .7.
That said, depending on your game mechanics, especially your handling of the camera and collision detection, using non-whole numbers for position might cause other problems. If that happens, feel free to ask for further help.
I see what you mean, I changed the speed variable to .7 and it seems to have fixed the problem. Thank you so much! This is overall going to just be a test game and it's mainly just meant for me to understand this new programming language so I can develop full games in the future. An additional problem I am now trying to figure out is that when moving diagonal the animation for walking speeds up for some reason.
There’s another approximation that works well if you are updating the game 60 times per second :
Orthogonal moves stay at 1 pixel per frame, diagonal movements a 1 horizontal and one vertical pixel per frame, but every three frames diagonal movement is disabled.
That makes diagonal movements slightly slower but has the big advantage that every variable stays as an integer which is is a lot less headache for things like collisions or display.
[Please log in to post a comment]




