Collision Detection

For questions about using Classic.

Post » Thu May 17, 2012 2:42 am

So i got this collision detection via events, goes like this:

+ System: [negated] Sprite.Right Lower or equal Sprite2.Left
+ System: [negated] Sprite2.Right Lower or equal Sprite.Left
+ System: [negated] Sprite.Bottom Lower or equal Sprite2.Top
+ System: [negated] Sprite2.Bottom Lower or equal Sprite.Top
-> System: Set global variable 'collision' to 1

+ System: Else
-> System: Set global variable 'collision' to 0


works fine, problem is though it has a 1px error,
for example, if i set move to stop it if detects collision,
it does but overlapping 1px into the other object.

any ideas on how to optimize this?
or invert it, so that it checks for non-collision, and if so it returns 1.

thanks
B
1
Posts: 3
Reputation: 231

Post » Thu May 17, 2012 3:27 pm

I used "is not overlapping at offset".
Posting your file always helps.
B
6
S
1
G
4
Posts: 66
Reputation: 1,532

Post » Thu May 17, 2012 5:01 pm

here it is, pretty much what i posted earlier. dropbox

anyways, i want to be able to do it via events.
i'm thinking that the problem might be that i'm checking for collision, instead of non-collision
B
6
S
1
G
1
Posts: 52
Reputation: 858

Post » Thu May 17, 2012 5:46 pm

I might overlook something, but from a quick look at the events, Construct does exactly what you order it to do.

Sprite.Right Lower or equal Sprite2.Left
If Sprite2.Left is 100, then this is true for 0 to 100, if you negate it, it becomes true as soon as Sprite.Right is 101, and that's 1 Pixel overlapping.

It should work, when you change all conditions to just 'lower than'
Sprite.Right Lower than Sprite2.Left
Is true for 0-99, if Sprite2.Left is 100. Negated it is true as soon as Sprite.Right is 100 == no overlapping

But in general pixel perfect condition testing can only be done reliable, when not using v-sync (have a look at TimeDelta on the wiki, if you are not sure if this is important to you)

Image
B
23
S
8
G
10
Posts: 1,820
Reputation: 8,242

Post » Thu May 17, 2012 8:30 pm

Thanks Tulamide, i did try that, but the same happened nevertheless.
I tried adding +1/-1 offsets to see if it fixed it, but it went from about 2px overlap without the offset, to it stopping 1px before collision with the offset,

the only one i got to work fine was this one:
+ System: Sprite2.Left Lower or equal Sprite.Right +1
but without the offset, it sometimes overlaps, and sometimes works pefect.

i'm leaning towards the thought that i'm missing some delta time element,
i've included dt in movement which basically goes like this:
if key down > set x = self.x + 120 + timedelta

how could i include delta in the coll detect?
i've tried every ticks, but didnt change anything
B
6
S
1
G
1
Posts: 52
Reputation: 858

Post » Fri May 18, 2012 12:49 am

ok, seriously, someone help me, couse i'm either missing something or construct is doing something wrong XD

no matter what i try, i always get like one offset to the left, and one to the bottom,

like it would look like this
   0
1     0
   1

i'm going nuts here
B
6
S
1
G
1
Posts: 52
Reputation: 858

Post » Fri May 18, 2012 1:51 am

ok, seriously, can someone please


how come
[QUOTE]
+ Sprite: [negated] Sprite: overlaps obj : offset (0,0)
-> Sprite: Set X to Sprite.x - (120 * TimeDelta)

+ Sprite: [negated] Sprite: overlaps obj : offset (0,0)
-> Sprite: Set X to Sprite.x + (120 * TimeDelta)

+ Sprite: [negated] Sprite: overlaps obj : offset (0,0)
-> Sprite: Set Y to Sprite.y - (120 * TimeDelta)

+ Sprite: [negated] Sprite: overlaps obj : offset (0,0)
-> Sprite: Set Y to Sprite.y + (120 * TimeDelta)
[/QUOTE]
does NOT work as intended?superpowerjoe2012-05-18 01:56:20
B
6
S
1
G
1
Posts: 52
Reputation: 858

Post » Fri May 18, 2012 6:33 pm

I really can't understand what you intended to do with this:

[quote]+ Sprite: [negated] Sprite: overlaps obj : offset (0,0)
-> Sprite: Set X to Sprite.x - (120 * TimeDelta)

+ Sprite: [negated] Sprite: overlaps obj : offset (0,0)
-> Sprite: Set X to Sprite.x + (120 * TimeDelta)

+ Sprite: [negated] Sprite: overlaps obj : offset (0,0)
-> Sprite: Set Y to Sprite.y - (120 * TimeDelta)

+ Sprite: [negated] Sprite: overlaps obj : offset (0,0)
-> Sprite: Set Y to Sprite.y + (120 * TimeDelta)[/quote]
In these conditions you set the Sprite object to move equally to right, left,top and down. Of course nothing will happen...



For the collision problem you have to use "For Loop" and make like this:

[quote]+ Sprite is moving
   + For 0 to ceil(120*TimeDelta)-1
      + If Sprite is moving right
        + [negated]Sprite is overlapping at offset ((ceil(120*TimeDelta)-LoopIndex),0)
          -> Sprite move (120*TimeDelta)-LoopIndex at 0 Degrees
          -> Break
      + If Sprite is moving top
        + [negated]Sprite is overlapping at offset (0,((ceil(120*TimeDelta)-LoopIndex)*-1))
          -> Sprite move (120*TimeDelta)-LoopIndex at 270 Degrees
          -> Break
      + If Sprite is moving Down
        ....
      + If Sprite is moving Left
        ....
        [/quote]

Do it to the four sides.
To make conditions for diagonal angles is a bit more complex.
Metal_X2012-05-18 19:39:08
B
22
S
7
G
5
Posts: 90
Reputation: 3,430

Post » Sat May 19, 2012 6:53 pm

[QUOTE=Metal_X] I really can't understand what you intended to do with this:
In these conditions you set the Sprite object to move equally to right, left,top and down. Of course nothing will happen...
[/QUOTE]

lol, i know, it's meant to represent individual movement on key presses,
i just skipped over the key press events when posting it.

the reasoning was something like:
- if key down
+ sprite is not overlapping object
-> move in given direction

however there's going to be a moment, where it isnt overlapping, but will move once more, and end up overlapping,
so i tried with an offset, but still sometimes stop before colliding, and at random occasions really, against the same wall it may or may not collide perfectly XD

[QUOTE=Metal_X]
For the collision problem you have to use "For Loop" and make like this:

[quote]+ Sprite is moving
   + For 0 to ceil(120*TimeDelta)-1
      + If Sprite is moving right
        + [negated]Sprite is overlapping at offset ((ceil(120*TimeDelta)-LoopIndex),0)
          -> Sprite move (120*TimeDelta)-LoopIndex at 0 Degrees
          -> Break
      + If Sprite is moving top
        + [negated]Sprite is overlapping at offset (0,((ceil(120*TimeDelta)-LoopIndex)*-1))
          -> Sprite move (120*TimeDelta)-LoopIndex at 270 Degrees
          -> Break
      + If Sprite is moving Down
        ....
      + If Sprite is moving Left
        ....
        [/quote]

Do it to the four sides.
To make conditions for diagonal angles is a bit more complex.
[/QUOTE]

cool, i'll try it out, however i do not see any "is moving" events,
thanks.

B
6
S
1
G
1
Posts: 52
Reputation: 858

Post » Sat May 19, 2012 7:52 pm

It will not collide perfectly because your sprite will move more than 1 pixel per frame, ex. if your sprite is 1 pixel from the object to collide and your FPS is 60 than, 120*1/60 = 2 pixels, it will move 1 pixel inside the collision object, with lower FPS is even wrost try to put it fixed aroud 15 fps and test, try it on unlimited too and you will see it work perfectly because it will move lower than 1 pixel per frame.
The way i discribed, using loops, will always move the exact pixels before collide with the object.

The "is moving" i mean to be your way to detect this, in your case you have to do "On keyboard: Left button is down", move to left, and so on...

Metal_X2012-05-19 20:05:57
B
22
S
7
G
5
Posts: 90
Reputation: 3,430

Next

Return to Help & Support using Construct Classic

Who is online

Users browsing this forum: No registered users and 1 guest