Log In  

I'm new to Pico 8

Cart #gekwalking748neworange-0 | 2024-03-31 | Code ▽ | Embed ▽ | License: CC4-BY-NC-SA


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
P#145310 2024-04-01 01:19

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.

P#145316 2024-04-01 01:59

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.

P#145321 2024-04-01 02:34 ( Edited 2024-04-01 02:37)

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.

P#145349 2024-04-01 08:42

[Please log in to post a comment]

Follow Lexaloffle:          
Generated 2024-04-16 17:34:12 | 0.011s | Q:20