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]