How do I keep speed consistent with 8-directional movement when moving diagonally

Not favoritedFavorited Favorited 0 favourites
  • 8 posts
From the Asset Store
This is a code so you can see the same skin on all screens (peers). Each peer gets a skin, in addition to 4 directions t
  • Couldn't fit it all in the title but I actually have two issues that are kind of related. I'll start with the first one.

    As I'm sure you know the 8 direction behavior doesn't keep a consistent speed when moving diagonally- it is often times much slower than going straight for example. Which is a bit of a problem for me since the game I'm making is a top down RPG with bullet hell elements. Main thing I'm tryin' to wrap my head around is how would I go about fixing that? I know it probably requires some sort of calculation on my end but I have no idea to go about doing that; better yet how to do it ONLY when the character is moving diagonally. I'll have some pictures attached of what my current set up for movement is. This is the MAIN problem that I need solved ASAP since having inconsistent movement in bullet hells is a VERY big deal. It can completely destroy the game feel and makes it harder to design around.

    Secondly, some animation trouble I've been running into. Not sure if I'm going to explain this well but... If you've ever played something like UNDERTALE or DELTARUNE you might notice that when pressing down your character doesn't just immediately go down. They still play on of their side animations. However once you let go of the left or right arrow keys they begin to do their proper up and down animations. Vice-versa for the opposite scenario. This is something I want to achieve because with the current system I have, the player can just keep pressing the up and down buttons rapidly while moving left or right and they'll keep switching back and fourth between their down and up animations to their side ones. It looks really awful and thats a bit of a problem.

    If anyone could me with these 2 I would be very grateful.

    (Sorry for the censored images by the way, don't want the project TOO public yet.)

  • When moving diagonally the x/y speed is slower but the total speed is equal to the max speed which is what most games want. Otherwise you’d actually be moving faster on a diagonal.

    Anyways, I guess one solution would be to give your object two 8direction behaviors. Set one the up and down and the other to left and right and you’ll be set.

    You could even skip the behaviors altogether and just do some events like:

    Key left is down
    — sprite: move self.speed*dt pixels at angle 180
    Key right is down
    — sprite: move self.speed*dt pixels at angle 0
    …etc for up and down

    As to the animation issue, I suppose you could solve that by somehow keeping track of the order the keys were pressed. I’m thinking you could do it with an array that you’d add the key to the end of when you press a key, and you remove the key from the array when you release it. Then you’d just play the animation of the key in index 0 of the array. It’s simple enough you can get away with implementing it with a text variable instead if you wanted like so:

    global text keys=“”
    
    On left pressed
    — add “L” to keys
    
    On left released
    — set keys to replace(keys, “L”, “”)
    
    On right pressed
    — add “R” to keys
    
    On right released
    — set keys to replace(keys, “R”, “”)
    
    Compare: left(keys,1) = “R”
    — set animation to “right”
    
    Compare: left(keys,1) = “L”
    — set animation to “left”

    That should get the idea across. Adding up and down can be added too with minimal effort.

  • Hey, thanks for the response! I tried the animation thing you suggested, it works for the most part. However, now I've run into a new problem. If I hold down the left and right arrow keys at the same time and then press down, they'll remain in their left animation. Same thing happens if I hold up and down and then press right. Not sure what's going on there. It only happens for those specific animations as well.

    Dunno if it'd help but here's the code I wrote down, it's basically the same as yours, though.

    Also I haven't tried the thing you gave for moving diagonally yet since I'm wondering if it'd be better to go with double 8 direction behaviors or just doing it from scratch. I'm just not sure if either one will cause problems for me down the line. Which one would you recommend?

  • I think instead of checking which keys are presses, you need to compare the angle in which the character is moving. For example:

    Player is moving
    
    ..Player.8direction.MovingAngle is within 22.5 degrees of 0: Set "WalkRight" animation
    
    ..Else Player.8direction.MovingAngle is within 22.5 degrees of 45: Set "WalkRightDown" animation
    
    ..Else Player.8direction.MovingAngle is within 22.5 degrees of 90: Set "WalkDown" animation
    
    .. and so on
    
    
  • A hybrid approach may be what he’s after. Use angle of motion in most cases, but when moving at a 45 favor the direction pressed first. That or I’m completely misreading what he’s after.

    Global number jx=0
    Global number jy=0
    Global text keys=“”
    
    On left pressed
    — add -1 to jx
    — add “L” to keys
    
    On left released
    — add 1 to jx
    — set Keyes to replace(keys, “L”, “”)
    
    On right pressed
    — add 1 to jx
    — add “R” to keys
    
    On right released
    — add -1 to jx
    — set Keyes to replace(keys, “R”, “”)
    
    …etc for other keys 
    
    Compare: abs(jx)+abs(jy) = 0
    — set anim to “idle”
    
    Else
    Compare: abs(jx)+abs(jy) = 1
    — set anim to tokenat(“right,down,left,up”, (angle(0,0,jx,jy)+360)%360/90,”,”)
    
    Else
    — set anim to tokenat(“right,down,left,up”, find(“RDLU”,left(keys,1)),”,”)

    Or maybe there’s a simpler way.

  • A hybrid approach would be ideal, yes... in fact thats the only way I can see it working out. Since I only have animations for 4 directions if I ONLY calculated by the angle, I'm pretty sure I'd just end up at square one.

    I tried the code you sent but it didn't seem to work for me, it kind of just completely broke the animations. Though, that's probably because I'm misreading it... The way I did my state machine might have also affected the way it works since animations are determined via a "direction" string. And if the player isn't moving their state is set to "idle" which sets the frame rate to 0. (I attached a screenshot of it in my first post if you need more details.)

    (Also should mention I'm a she, no offense taken dw.)

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Here's a demonstration of the hybrid approach. Basically it sets the animation from the angle of motion unless moving diagonally. When moving diagonally it keeps using the direction of whichever arrow key was pressed first. There are likely other ways to implement the idea.

    dropbox.com/scl/fi/tnk06c4xrpkfms75w3b7y/topdown_control_and_animation.capx

  • Wow, yeah this works perfectly for the most part. Had to do some tweaking since the from scratch 8 direction movement was acting weird with collisions. So, I'll still have to fix that up later. I think I'm gonna have to figure out a way to calculate how much to increase the speed when moving diagonally (however you do that, I have no idea).

    But I changed some stuff around to fit with the 8 direction behavior and it worked perfectly, thank you!

Jump to:
Active Users
There are 0 visitors browsing this topic (0 users and 0 guests)