0 Favourites

8-Way directional - Retaining diagonal angle

  • You can see my game here: doobiedoctor5000.allalla.com/shootTheMonsters/index.html

    Controls: Arrow keys to move, space to shoot

    My current issue is I don't know why I can't get the player sprite to face diagonally without actually moving diagonally. If I release the buttons, it will either face along the x or y axis, but not both at the same time. I'm using the 8Direction behavior for the player. How do I get it so the player remains facing diagonally after the arrow keys are released?

  • Disable the "set angle" setting of the behavior. Then do the following to set the angle based on what directions were pressed last.

    global number joyx=0

    global number joyy=0

    every tick

    --- set joyx to 0

    --- set joyy to 0

    key up is down

    --- subtract 1 from joyy

    key down is down

    --- add 1 to joyy

    key right is down

    --- add 1 to joyx

    key left is down

    --- subtract 1 from joyx

    joyx not equal to 0

    or

    joyy not equal to 0

    --- set player angle to angle(0,0,joyx,joyy)

  • Disable the "set angle" setting of the behavior. Then do the following to set the angle based on what directions were pressed last.

    global number joyx=0

    global number joyy=0

    every tick

    --- set joyx to 0

    --- set joyy to 0

    key up is down

    --- subtract 1 from joyy

    key down is down

    --- add 1 to joyy

    key right is down

    --- add 1 to joyx

    key left is down

    --- subtract 1 from joyx

    joyx not equal to 0

    or

    joyy not equal to 0

    --- set player angle to angle(0,0,joyx,joyy)

    Thanks for the reply! I was able to do everything down to a T, up until the last part where you set the angle. I keep getting a syntax error when I try to set the player angle to (0,0,gvar_checkAngleX,gvar_checkAngleY) (I used my own variable names). It has a problem with the first comma, saying that there should be something else before it?

  • Construct 3

    Buy Construct 3

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

    Buy Now Construct 3 users don't see these ads
  • The last bit uses the angle() expression, so the full expression would be:

    angle(0,0,joyx,joyy)

  • Thanks again! <img src="smileys/smiley1.gif" border="0" align="middle" />

    Unfortunately it only works here and there. Most of the time the player only faces directly on the x or y axis, and never diagonally. Sometimes it works as intended, where when you release the arrow keys it stays facing diagonally. I'm not sure why it doesn't work all the time.

  • It does that since it's hard to release two arrow keys on the same frame.

    One possible solution would be to use the angle from a few frames back. The idea being that it's easier to release two arrow keys over a few frames than one.

    http://dl.dropbox.com/u/5426011/examples17/8dir2.capx

  • It does that since it's hard to release two arrow keys on the same frame.

    One possible solution would be to use the angle from a few frames back. The idea being that it's easier to release two arrow keys over a few frames than one.

    http://dl.dropbox.com/u/5426011/examples17/8dir2.capx

    Thanks for showing me a working example. Is that the main character from Earthbound? :)

    I don't exactly understand everything you did, though. I see you used an array, which I have yet to fully understand/utilize. I will list my interpretation of what you did here. Please let me know where I'm going wrong:

    • Create global number variables joyx and joyy
    • System --> Every Tick --> set both global variables to 0
    • Up, Down, Left, Right Arrow Keys --> is down --> add/subtract 1 to each global variable in accordance with direction (+1 for down/right, -1 for Up/left)
    • if either global variable is not equal to 0 --> add the angle expression to the array
    • If the array has 5 or more entries on the x axis (width) --> move to the back of the array
    • if sprite is moving in any direction ---> set animation to walk & int(add 360 to the back of the array, divide it by 360, and divide the remainder by 45) from current frame
    • if sprite is not moving ---> set animation to first sprite in animation, and then reset/empty the array

    As you can see, I can understand a little bit of it, but I'm missing the meat of it.

  • I'm using the array as a queue. Values are added to one end and the other end is what is used and where values are removed.

    f either global variable is not equal to 0 --> add the angle expression to the arrayHere we know that some direction is being pressed, so the angle is added (pushed) to the front end of the queue. In simpler terms we are just saving the current angle pressed.

    f the array has 5 or more entries on the x axis (width) --> move to the back of the arrayYou have the first part right, but all it does is remove (pop) a value from the back end of the queue when there is 5 five or more values. This is limiting the number of angles saved to 4 by removing the extra values. The "back" is where we remove from since it's the oldest value.

    f sprite is moving in any direction ---> set animation to walk & int(add 360 to the back of the array, divide it by 360, and divide the remainder by 45) from current frameThis one is kind of two part. The bulk of the formula is converting an angle to the closest eight direction. Here is a topic that explains it pretty well:

    http://www.scirra.com/forum/sprite-movement-8-dir-troubles_topic47201.html

    The second part is what angle is used, which is the oldest value in the queue or the "back" value. The gist of this is we are effectively using the direction that was pressed four frames ago.

    f sprite is not moving ---> set animation to first sprite in animation, and then reset/empty the arrayWhen the sprite is not moving we want the animation to reflect this. Without this event the sprite would just walk in place. By setting the animation frame to 0 we prevent animation and use the image for standing. The effect of resetting the queue to be empty is not really noticeable and that action could be removed. I just thought it logical to fill the queue new every time instead of reusing existing values from a previous motion. But considering the time it takes to fill the array: 4 frames *dt ~= 0.07 seconds it's pointless as that's faster than human reaction time.

    And yeah that's the main character from Earthbound.

  • I'm using the array as a en.wikipedia.org/wiki/Queue_%28abstract_data_type%29

    The second part is what angle is used, which is the oldest value in the queue or the "back" value. The gist of this is we are effectively using the direction that was pressed four frames ago.

    f sprite is not moving ---> set animation to first sprite in animation, and then reset/empty the arrayWhen the sprite is not moving we want the animation to reflect this. Without this event the sprite would just walk in place. By setting the animation frame to 0 we prevent animation and use the image for standing. The effect of resetting the queue to be empty is not really noticeable and that action could be removed. I just thought it logical to fill the queue new every time instead of reusing existing values from a previous motion. But considering the time it takes to fill the array: 4 frames *dt ~= 0.07 seconds it's pointless as that's faster than human reaction time.

    And yeah that's the main character from Earthbound.

    Thanks yet again. That's a lot of information and I'm going to take a little time off of studying it for tonight. I get the queue idea, and how its first-in first-out (took me a while to get it). I'm having trouble grasping the formula, though. I don't have a lot of experience using modulus, so it doesn't come as second nature to me. I will be back on it tomorrow though.

    In the meantime, I attempted to make a demo by basically plagiarizing what you did, and I STILL didn't get it right! lol You can see by downloading my capx here: doobiedoctor5000.allalla.com/my8dirattempt/my8dirattempt.capx

    Movement works just fine, as does diagonal placement, but you can see how it's just NOT working how its supposed to lol. It's frustrating but I WILL get it!

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