# 8way custom grid movement, 360° / formula question

Get help using Construct 2

### » Thu Apr 19, 2012 10:05 am

/* edit: changed title */

Hi,

I'm currently toying around with ideas to calculate movement input and create movement functions (using Rex' function plugin).
(I can't post a cap right now as I'm on the go and can't access my pc for a while.)

Question 1
I have a LineOfSight for my Moving OBjects that connects to possible targets. In my current solution I check the angle of the LOS and use a switch case to determine the next movement (on a tiled grid with grid movement).
The move function is the same for my player MOB as well as NPC MOBs.

some pseudo code for my current 4way movement
switch LOS.angle
- case angle > 315 & angle < 45
- => call function(move, right, {distance})
- case angle > 45 and angle < 135
- => call function(move, down, {distance})
and so on...

As the move function translates right and down into the correct angle again, it would be easier to call the function with the correct value. I'm working with grid movement, so there are only 8 valid angles. I need a formula that takes the LOS angle and "snaps" it to the nearest valid angle for movement.

Is there a way to get this behaviour:
x = input -> output
x = 00.0 ->   0
x < 22.5 ->   0
x >= 22.5 -> 45
x = 45.0 -> 45
x < 67.5 -> 45
x >= 67.5 -> 90
x = 90.0 -> 90
...

I've seen formulas with ((X*Y)+Z)/N or something like that but except for the one time I copied a formula (i didn't understand but that magically worked anyway) I never worked with those in C2. It would save me a lot of events for my movement logic, when going from 4way to 8way movement.

Question 2a
I'm currently using 5 events to get the user input for movement (4way).
When enabling 8way movement, I'd need at least 9 events

some pseudo code for my future 8way movement
left pressed
- => set parameter movementAngle to 180
- => set parameter movementDistance to 16
- down pressed
- - => set parameter movementAngle to 135
- - => set parameter movementDistance to 22
- up pressed
- - => set parameter movementAngle to 215
- - => set parameter movementDistance to 22
right pressed
- => set parameter movementAngle to 0
- => set parameter movementDistance to 16
- down pressed
- - => set parameter movementAngle to 45
- - => set parameter movementDistance to 22
- up pressed
- - => set parameter movementAngle to 315
- - => set parameter movementDistance to 22
down pressed
- => set parameter movementAngle to 90
- => set parameter movementDistance to 16
up pressed
- => set parameter movementAngle to 270
- => set parameter movementDistance to 16
NOT up pressed
NOT down pressed
NOT right pressed
NOT left pressed
MOB.DistanceToMove = 0
- => idle stuff

Is there a way to simplify this?

Question 2b
For my 4way grid movement, I'm using the following

some pseudo code for my current 4way movement
MOB.DistanceToMove > 0
- => MobSprite: Set animation to MOB.MobType & "Walking"
- => MOB: Move 100*dt pixels at angle MOB.AngleToMove
- => MOB: Substract 100*dt from DistanceToMove
MOB.DistanceToMove < 0
- => MOB: Move 100*dt pixels at angle MOB.AngleToMove
- => MOB: Set DistanceToMove to 0
MOB.DistanceToMove = 0
- => MobSprite: Set animation to MOB.MobType & "Default"

As I'm using a 16 pixel grid, I simply set the MOB.DistanceToMove to 16 and I'm fine. If I implement 8way movement now, I don't know exactly what DistanceToMove I have to use. Pythagoras tells me it should be 22.62741699..... I think that might lead to problems on the long run.

I appreciate any help I can get that leads to cleaner code and less events. I'll be at my home pc again in 2 days, I'll add a capx then in case there's no good solution by then but judging from the stuff I read here, there ought to be someone smart enough to help me.
B
4
Posts: 19
Reputation: 363

### » Thu Apr 19, 2012 3:07 pm

/* edit: changed title */
I think mentioning math in the title might turn some people away...
B
4
Posts: 19
Reputation: 363

### » Thu Apr 19, 2012 8:40 pm

1)
round(((angle + 360)%360)/45)*45

2a)
+Every Tick:
--- set joyX to 0
--- set joyY to 0
+Left is pressed
--- sub 1 from joyX
+Right is pressed
+Up is pressed
--- sub 1 from joyY
+Down is pressed
+Every tick
--- set angle to angle(0,0,joyX,joyY)

This will also eliminate opposite key presses (left+right, up+down)

2b)
Just snap the position to the grid at the end of motion.

capx:
http://dl.dropbox.com/u/5426011/examples10/8dirGrid.capx
B
75
S
21
G
48
Posts: 4,668
Reputation: 37,201

### » Fri Apr 20, 2012 10:59 am

1) Thanks a lot! I'll have to learn all expressions and stuff, it will help me alot along the way.

2a) Thats an elegant way. I like it! I'll only change the angle to something like this to get rid of negative angles
(angle(0, 0, joyx, joyY)+360)%360

2b) This is the part where I'm still unsure. I had a look at your capx on a friends computer.
Set DistanceToMove to 16*distance(0,0,self.joyx,self.joyY)

I added a bunch of 32*32 sprites to your example like a chessboard. When I start moving around, the player sprite looses his position within the grid and ends up a bit off the grid cell he should end his movement. Happens both with straight as well as diagonal movement. Maybe there is some weird rounding error or it has to do with the movement itself (100*dt)?

By the way: I changed the value to 16 because my Player has a height of 16 and a width of 32. All objects snap to a 16*16 grid but may vary in size (using steps of 16). My collision handling is doing well so far.
I checked with your original capx but the movement is still a bit off.

Thanks for your help so far. Now it's only the DistanceToMove that I have to get right.ModalCore2012-04-20 11:01:20
B
4
Posts: 19
Reputation: 363

### » Fri Apr 20, 2012 6:40 pm

I made a logic error in event 2.
I changed
Sprite: Move -self.distToMove pixels at self.angToMove
to
Sprite: Move self.distToMove pixels at self.angToMove

self.distToMove is already negative in that event so the sprite would always overshoot the target.
B
75
S
21
G
48
Posts: 4,668
Reputation: 37,201

### » Mon Apr 23, 2012 1:24 pm

Works like a charm. I just tested your CAPX and implemented the changes in my game.

Thanks alot!
B
4
Posts: 19
Reputation: 363

### » Thu Jul 11, 2013 8:14 pm

My math skillz are uncanny I can turn a perfectly working example into rubble :) I'm using the grid thingie for a project and I'm using swipe(with weird calculations) to generate my "directions"... I'm messing something up and I can't figure it out. I need simple up down left right from swiping along... can you help clear my angle mess out. Here's the Capx As soon as I get a "better" version up I'll upload it as well for the aid of those who need something like this.
B
34
S
7
G
5
Posts: 255
Reputation: 5,146

### » Thu Jul 11, 2013 9:49 pm

After some hammering down on the situation i came to a possible cleaner solution. Here's my Generic Grid Walk I hope it helps for later use.
Capx
B
34
S
7
G
5
Posts: 255
Reputation: 5,146

### » Fri Jul 12, 2013 11:14 am

@R0J0hound how do you apply this sprite to stop moving when is overlapping at solid objects?
B
87
S
21
G
18
Posts: 3,045
Reputation: 20,989

### » Fri Jul 12, 2013 5:43 pm

@Joannesalfa
For interacting with solid objects you just need to check to see if a solid object is at it's destination before it moves. Yann made an example of grid movement with walls that should give a good idea how it could be done.
B
75
S
21
G
48
Posts: 4,668
Reputation: 37,201

Next