Calculate X/Y speed for 8Dir behavior relative to facing direction

0 favourites
  • 9 posts
From the Asset Store
Rotate & Animation for 16 Direction & Mouse Direction
  • PROBLEM I need some help on how to calculate the proper X and Y speed in the 8 Direction behavior relative to the facing direction of the object.

    TYPICAL SCENARIO In a traditional 2D game with the 8 Direction behavior, pressing the Up arrow moves object up on the Y axis...etc, etc, etc. And doing so moves the object according to the given (max) speed set in the parameters.

    If, for example, you press up and left, the object will move up and left at the same pixels-per-second speed defined.

    CURRENT SCENARIO IN DETAIL I have the 3D camera set behind my Player object in a 3rd-person-shooter perspective. Using the Mouse, you can make the Player rotate its facing angle left or right. The goal is to use the WASD keys (or arrow keys but I'm using WASD for my project) to the Player forward & back and strafe left & right.

    Now, naturally, 8 Direction operates from within the fixed 2D plane of the layout. It does not factor in the 3D camera. So if the 3D Camera, fixed behind the Player's head at all times, is facing down (towards the bottom of the layout), pressing W will make the Player appear to move backward, even though from the camera perspective, one would expect to move forward.

    I am using 8 Direction because of its built-in check to stop when it encounters objects with a Solid behavior. I did have a custom movement system that worked but it failed to work properly when encountering Solid objects.

    ATTEMPTED SOLUTION Instead, I am trying to calculate how much speed to give to the X and Y vectors of 8 Direction (or even two instances of the behavior on the same object - one for X, the other for Y) based upon the facing direction of the Player.

    As you can see in my crude image, the idea is that if the Player is facing a certain direction, pressing W is to make the Player move in that direction and not simply up on the Y axis. (EDIT: I should have drawn the WASD squares correctly orientated to the Player's facing direction and not in line with the X/Y axes. That's my mistake.) Instead, W leads to a calculation that determines the proper speed in pixels/second for both the X and Y axes. If the movement speed for 8 Direction is normally 200, I would need less than 200 for each axes but it would have to be a value that still amounted to 200 total. Otherwise, moving in a diagonal direction would invariably result in the Player moving much faster than 200.

    In this setup, WASD is always relative to the Player's facing direction and not the traditional X/Y axes orientation the behavior is built around.

    ULTIMATE PROBLEM I believe I have the right idea but I am struggling to determine if I need to manipulate the behavior (max) speed, the behavior X/Y vectors, use instances variables for each movement direction (or just two variables for vertical and horizontal movement)... (I would include a screenshot of my current event sheet but I'm in the middle of making edits so I apologize for any confusion on my current efforts at a solution.)

    I am requesting some suggestions or specific solutions I can attempt (I don't mind doing the work but if you have a particular solution in mind, I just need pointed in the right direction), I would be so very grateful. THANKS!

  • You can set the velocity in a specific direction with a bit of trig:

    Vx=100*cos(a)

    Vy=100*sin(a)

    You can also combine two velocities by adding them.

    Vx=100*cos(a)+100*cos(b)

    Vy=100*sin(a)+100*sin(b)

    Then to limit the max speed you can do this

    Speed=distance(0,0,vx,vy)
    If speed>maxSpeed then
    — vx = vx/speed*maxSpeed
    — vy = vy/speed*maxSpeed
  • You can set the velocity in a specific direction with a bit of trig:

    As always, you are among the awesome people who come to the rescue. THANK YOU! I remember having only a semester of trig in high school (c/o 1999... I'm old-ish LOL). So, trig didn't immediately come to mind. But it makes sense now that it would apply.

    I'll work on adapting your solution after work today and let you know if that resolves the problem. Thanks again! God bless!

  • For the most part, I think I follow... But I have some clarifying questions.

    You can set the velocity in a specific direction with a bit of trig:

    Vx=100*cos(a)

    Vy=100*sin(a)

    To reword this in my own head (and how I am currently plugging into my project) in order to make sure I understand:

    Player.Velocity_X = Player.8Direction.MaxSpeed * cos( Player.Angle )
    Player.Velicity_Y = Player.8Direction.MaxSpeed * sin( Player.Angle )
    

    Then to limit the max speed you can do this

    Speed=distance(0,0,vx,vy)
    If speed>maxSpeed then
    — vx = vx/speed*maxSpeed
    — vy = vy/speed*maxSpeed
    1. Set (instance) variable Speed to the distance between coordinate (0,0) and (Player.Velocity_X , Player.Velocity_Y)
    2. If Player.Speed is greater than the Player.8Direction.MaxSpeed then...
    3. - Set Velocity_X to Velocity_X divided by Speed times MaxSpeed
    4. - (Do the same for Velocity_Y)

    Now, all of that I think I follow and I've got the variables plugged in.

    But I have two questions I'm having trouble figuring out...

    1. Why is Speed=distance(0,0,vx,vy) starting at (0,0)? Or should I just replace that with the Player's X/Y coordinates?

    2. Once I have Velocity_X and Velocity_Y set - I realize this may be a "DUH" answer - what do I do to use them? Like, where do they go in the event sheet after that? Say I just want to do Hold W to move forward, how do I type that up in the event sheet?

  • R0J0hound - I realize I have a tendency to over-explain everything. LOL

    So, hopefully, this better summarizes what my last comment was trying to get at.

  • First the distance(0,0,vx,vy) is correct. Vx,vy is the velocity vector and that gets the magnitude of that vector. For velocity the magnitude is the speed. You can also calculate it with sqrt(vx^2 + vy^2).

    Anyways for motion logic you’d set vx and vy to zero and just add any directions you want.

    The final step is to limit the speed to a max speed.

    Here’s another possible way to do it. I mean you can apple the speed of 100 as a last step.

    every tick
    -- vx=0
    -- vy=0
    
    if up pressed
    -- set a to player.angle
    -- add cos(a) to vx
    -- add sin(a) to vy
    
    if right pressed
    -- set a to player.angle+90
    -- add cos(a) to vx
    -- add sin(a) to vy
    
    ... etc for other directions
    
    if vx<>0 and vy<>0
    -- set mag to sqrt(vx^2+vy^2)
    -- set vx to 100*vx/mag
    -- set vy to 100*vy/mag
  • R0J0hound - As always, you are a lifesaver. Can't tell you enough how grateful I am for your help. THANK YOU.

    It's a funny thing (to me) - your explanations made sense on their own but when it came to applying them, I kept getting lost on details and I couldn't exactly articulate what those details were. But I finally got it! Some of it was just the logic order of the conditions/actions in light of all the trig calculations. Along with some extra review (thank you, Google), I was better able to understand what you were getting at.

    ANYWAY! Enough sentimentalism...

    Here's what I plugged in and it WORKS! (I'm 41 and feeling like a kid who just his Lego set put together. Good stuff.)

    Now, I'm not sure this was exactly what you had in mind, so if there is a more refined way of doing this, I'm not seeing it. The next step I need to do is to see if I can figure out how to make moving in diagonals possible. I believe this is what you meant by adding velocities together. I updated the logic to apply the trig calculations directly the 8 Direction behavior's velocity values instead of the instance variables I had been using (I think that was lending itself to some of my initial hang-ups).

    I think I need to try to think outside the box to figure this one out on my own. I will request some extra help if I can't figure it out for some reason.

    Thank you again!

  • That's close to what I meant. I think the 8direction behavior just gets in the way.

    The 8direction behavior already limits the speed to the maxSpeed so all you need to do should be:

    1. set velocity of x and y to 0.

    2. when a direction key is pressed add to the velocity a direction vector:

    maxSpeed*cos(a), maxSpeed*sin(a)

    That should handle diagonals and such, unless something I'm not aware of occurs in the behavior.

    An alternate idea is to have a hidden object with 8dir that you move normally but without collisions. The rotate that object's velocity and set the velocity of a visible object. It would give smoother speeding up and slowing down, but it still wouldn't update the velocity when hitting solids.

    dropbox.com/s/v41o4p8qxsd5tdh/rotated_8dir.capx

    Or here is an older example of the 8dir behavior done with events sans collisions. You just set the angle of the sprite and motion will be relative to that.

    There may be a simpler way. I guess I didn't really answer your question. But having a few example of various ways to do it could be useful?

  • Try Construct 3

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

    Try Now Construct 3 users don't see these ads
  • OH MY GOODNESS!! That may just be the solution (the Dropbox example)!!

    Yeah, the use of 8 Direction is because of my need to have a check against objects with the Solid behavior. The custom movement system I had before was similar to the trig solution you've provided (setting movement angle to +/-90, et al).

    Since going back to using 8 Direction, the whole problem was trying to get the keyboard input to reflect the 3D camera perspective (and therefore the facing angle of the Player) while taking into account that 8 Direction does not normally regard the camera perspective. That's why your trig solution was so pivotal.

    However, using the "ghost sprite" object is genius! I'm going to work on adapting that now. I think you just solved the problem.

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