8-Way directional - Retaining diagonal angle

Get help using Construct 2

Post » Sun Mar 24, 2013 6:55 am

You can see my game here: http://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?
B
6
S
1
Posts: 31
Reputation: 703

Post » Sun Mar 24, 2013 6:30 pm

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)
B
79
S
24
G
54
Posts: 4,746
Reputation: 40,755

Post » Mon Mar 25, 2013 3:05 am

[QUOTE=R0J0hound] 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)[/QUOTE]

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?
B
6
S
1
Posts: 31
Reputation: 703

Post » Mon Mar 25, 2013 4:34 am

The last bit uses the angle() expression, so the full expression would be:
angle(0,0,joyx,joyy)
B
79
S
24
G
54
Posts: 4,746
Reputation: 40,755

Post » Mon Mar 25, 2013 5:32 am

Thanks again!

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.
B
6
S
1
Posts: 31
Reputation: 703

Post » Mon Mar 25, 2013 6:40 am

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
B
79
S
24
G
54
Posts: 4,746
Reputation: 40,755

Post » Mon Mar 25, 2013 7:28 am

[QUOTE=R0J0hound] 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[/QUOTE]

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.DoobieDoctor50002013-03-25 07:29:46
B
6
S
1
Posts: 31
Reputation: 703

Post » Mon Mar 25, 2013 5:14 pm

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.

[quote]if either global variable is not equal to 0 --> add the angle expression to the array[/quote] Here 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.
[quote]If the array has 5 or more entries on the x axis (width) --> move to the back of the array[/quote] You 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.
[quote]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[/quote] This 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.
[quote]if sprite is not moving ---> set animation to first sprite in animation, and then reset/empty the array[/quote] When 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.R0J0hound2013-03-25 17:15:56
B
79
S
24
G
54
Posts: 4,746
Reputation: 40,755

Post » Tue Mar 26, 2013 6:55 am

[QUOTE=R0J0hound] I'm using the array as a http://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.
[quote]if sprite is not moving ---> set animation to first sprite in animation, and then reset/empty the array[/quote] When 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.[/QUOTE]

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: http://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!
B
6
S
1
Posts: 31
Reputation: 703


Return to How do I....?

Who is online

Users browsing this forum: fredriksthlm, MPPlantOfficial and 25 guests