Detecting which side of a player sprite has collided?

Discussion and feedback on Construct 2

Post » Sat Sep 06, 2014 8:14 pm

Hey guys,

Lets say I have 64x64 sprite that I call player. Then I put it in a level made out sprite tiles and I make the player move randomly around in it.

So I want to know which side of the player has hit a tile i.e. top, left, right and bottom.

Any ideas? (please give a short example based on the above)

Kind regards,
Wyrm
ImageImageImageImageImage
B
19
S
5
G
1
Posts: 614
Reputation: 2,542

Post » Sat Sep 06, 2014 10:00 pm

Howdy,

I have plenty of solutions laying around as there are many but my favorite way is the following:

Terminology:

ObjectCollider = the object that collides with solids and is the object that is moved around

ObjectState = The object that determines what direction collisions are occurring from. The size of the sprite should be one pixel greater on all sides as the objectCollider, with the same origin as well. The collision polygon should then be adjusted so that it is only on the right of the Sprite. Depending on the scenario, you will need to adjust the relative sizes of the boxes based on your needs. Also, the Object state needs the following instance variables: Up, Down, Left, and Right (they are booleans). This way will work if the object is square or round. (if other then see note below)

Whenever you create an ObjectCollider it creates an Object State (you can put these in containers so it happens automatically, but if you need them in families it gets a little more difficult as you would need to track UIDs and use parents)

Every Frame, ObjectState needs to be updated in the following ways:

1. Set its position to the parent ObjectCollider
2. If it is overlapping an object that is Solid set "Right" to true, else set it to false.
3. rotate ObjectState 90 degrees (now it is facing down) and test for overlapping solids...
4... I think you can figure out the rest...

If you are not using a round or square object, then you will need to create an ObjectStateUp, ObjectStateDown, and so on and attach them to respective image points on the ObjectCollider.

Any Questions? Overall, this is a pretty basic need in games and I am supprised their has not been made a behavior to get that data. I need this in every game I make so I created a blank project that uses families and does it all automatically when I create an object and put it in family SpriteColliders.
Image
B
33
S
11
G
2
Posts: 563
Reputation: 5,141

Post » Sun Sep 07, 2014 12:33 am

I've also experienced the same problem previously, and solved it after reading this post. Basically you just need to convert the pseudocode to C2 events.
B
23
S
9
G
3
Posts: 114
Reputation: 3,794

Post » Sun Sep 07, 2014 11:46 am

On collision player x greater than tile x. That's the left side. On collision player x less than tile x. That's the right side of the player.
B
5
S
1
Posts: 41
Reputation: 455

Post » Mon Sep 08, 2014 6:33 pm

Cheers guys. So I have tested all the above. I found with my situation the most reliable method was to create four simple sprites. Offset them from the player sprite position so you have one above, below, left and right. Then for each of the four sprites use the action 'is overlapping another object' with 'trigger once' Then set them to invisible.

Although I know this isn't the most efficient method it gave me perfect results when testing the player sprite moving at a high speed. With the others I found they would sometimes flag the wrong side. I suspect this is because when moving at the speeds I need the collision can be flagged when it is quite far into the object.

Thanks again for your help.
ImageImageImageImageImage
B
19
S
5
G
1
Posts: 614
Reputation: 2,542

Post » Tue Sep 09, 2014 12:12 am

@TheWyrm, you could also use the "Is Overlapping at Offset" condition check; to minimise collision checks you could use it to check if the player is overlapping a few pixels left or right of its current position. If your player moves at high speed then it might be worth checking an offset slightly greater than the number of pixels the player moves per tick (to ensure you don't get an erroneous overlap is true in both directions). This check could then only be made by a player On Collision trigger - thus minimising the number of collision checks per tick...
I only occasionally visit - I'm learning C# for Unity, but c2 is still a respectable game engine imo....
B
73
S
19
G
66
Posts: 2,198
Reputation: 42,183

Post » Tue Sep 09, 2014 11:49 am

I did the same thing when testing a similar event. It works fine on your computer but you just adds 4 collision checks to your game and 4 * the number of objects that need checking could make it hard on mobile. A better system has 1 collision check then tests what side its on after the collision.
B
5
S
1
Posts: 41
Reputation: 455

Post » Tue Sep 09, 2014 4:21 pm

@colludium Yeah, I tried that before implementing the 4 sprite system. I found that it caused some other unexpected issues. Basically I rotate to a specific angle depending on the edge that the collision occurred on. With 'Is overlapping at offset' it made my sprite spin. Which makes logical sense. This didn't happen with using 4 sprites. I would have to debug to find out more and is probably just a matter of tweaking. For now I have disabled those events and will come back to it when I need to optimise as right now I am prototyping.

@xach I agree, but I'll wait until it actually causes problems before I refine it ;)

Is there anyway to see collision checks in the debugger?
ImageImageImageImageImage
B
19
S
5
G
1
Posts: 614
Reputation: 2,542

Post » Tue Sep 09, 2014 7:57 pm

You can check collisions under performance in the debugger.
B
5
S
1
Posts: 41
Reputation: 455


Return to Construct 2 General

Who is online

Users browsing this forum: Cliffu and 2 guests