No collision state?

Is there a way to know if object doesn’t collide with other objects on the screen.

There is “ended” phase of collision event but it doesn’t help too much if object collides with manu overlapping objects. So, while collision ends for some objects it starts for some other (or it already started)…

Thanks in advance


S [import]uid: 101952 topic_id: 24523 reply_id: 324523[/import]

I solved this issue recently. The best method is to set a “counter” with each of your physical objects, for example “object.collideCount = 0”. When any object collides/overlaps with another, in the BEGAN phase you increase this counter +1. Likewise (important!) in the ENDED phase, you decrease it -1. Then, also in the “ended” phase, you can check if it’s == 0. If yes, then the object is “clear” of all other objects.

So, let’s imagine you have 4 “clouds” which can collide AND overlap. If cloud1 touches cloud2, its counter is 1 (both are 1, in fact). Then cloud1 drifts into cloud3 and cloud4, so its counter is now 3. Next, cloud1 exits cloud2, so it’s counter reduces to 2. Finally, it exits cloud3 and cloud4, and its counter is 0. Now you know cloud1 is in a state on non-collision.

I should also mention that for MULTI-ELEMENT physics bodies, you will receive a “began” collision every time that ANY element touches something it can collide with! I was confused for hours before I realized this was happening. You can’t just treat MULTI-element bodies as “one body” when it collides. Fortunately, my “counter” method solves this issue too; in this case the counter will represent how many of the body’s elements are currently in collision with something else.

Brent Sorrentino [import]uid: 9747 topic_id: 24523 reply_id: 99303[/import]

Simple and clean!

Thank you Brent [import]uid: 101952 topic_id: 24523 reply_id: 99334[/import]

Well I’m trying your suggestion but I’m not sure I’ve got the counter working right. Here’s a simple example where I’ve made a rectangle be a sensor object with a crate being dragged into the sensor region. But my counter isn’t working. Please advice.

local physics = require(“physics”)
physics.start()

display.setStatusBar( display.HiddenStatusBar )

local counter = 0

– A basic function for dragging physics objects
local function startDrag( event )
local t = event.target

local phase = event.phase
if “began” == phase then
counter = counter + 1
display.getCurrentStage():setFocus( t )
t.isFocus = true

– Store initial position
t.x0 = event.x - t.x
t.y0 = event.y - t.y

– Stop current motion, if any
event.target:setLinearVelocity( 0, 0 )
event.target.angularVelocity = 0

elseif t.isFocus then
if “moved” == phase then
t.x = event.x - t.x0
t.y = event.y - t.y0

elseif “ended” == phase or “cancelled” == phase then
display.getCurrentStage():setFocus( nil )
t.isFocus = false
counter = counter - 1

end
end
print (counter)

– Stop further propagation of touch event!
return true
end

local crate = display.newImage( “crate.png” )
crate.x = 90; crate.y = 90
physics.addBody( crate, “kinematic”, { friction=0.7} )

local rect = display.newRect( 50, 50, 100, 100 )
rect.x = 150; rect.y = 200
rect:setFillColor( 255, 255, 255, 100 )
rect.isVisible = true
physics.addBody( rect, “kinematic”, { friction=0.7, isSensor = true } )

crate:addEventListener( “touch”, startDrag ) [import]uid: 168506 topic_id: 24523 reply_id: 121597[/import]

Hi Betsy,

Can you be more specific about what’s not working in your code? Is the counter not keeping the proper count? You actually need to use a counter for every object (every shape in your tangram), not a “master” counter. Each shape must keep track of how many boundaries it’s overlapping.

You also must subtract from the counter during the “ended” phase, as in, when the tangram shape exits the boundaries, its counter reduces until it’s 0, meaning that it’s clear of all boundaries.

So, please let me know more specifically what’s happening and we should be able to narrow it down!

EDIT: Oops, just saw that you are subtracting from the counter! Next time you post code, can you also surround it with code tags? This helps me and others read it much easier.

Best regards,
Brent [import]uid: 9747 topic_id: 24523 reply_id: 121600[/import]

Sorry about the code. I just cut and paste it into the forum. Anyhow this is what I tried to do. I defined an object called rect which has the .isSensor = true. I also have an object called crate which I want to fit within the rect object. They both are defined as kinematic with the same friction value. So I set up a drag function which when the phase == “began” increments the variable counter by 1. When the drag function’s phase == “ended”, the counter subtracts 1. Within the function, I have a print function showing what the counter value is.
This is what I see. As I start to drag the crate object, the console keeps printing 1 even though the crate has never entered the boundaries of the rect object. When I stop dragging the crate object, the counter prints out the value of 0. Doesn’t matter whether I have drag the crate object into the rect object or not. Counter stays 1 and goes to 0 when I stop dragging. That’s why I don’t know if I have set up the objects right and whether I have the counter working right. Does that make sense? Sorry if I’m not using the right phrase but I really new to this.
Thanks. [import]uid: 168506 topic_id: 24523 reply_id: 121679[/import]

Hi Betsy,
That really clears it up. Here’s what is slightly wrong so far, that I can see.

  1. I don’t think kinematic bodies react (collide) with other kinematic bodies. There are some fairly obscure “rules” about this, and I can’t remember exactly what they are for every case. What I can say for certain is that a “dynamic” body will always react with another body type (assuming you haven’t excluded it with collision filters or something). The point is, you should make your boundaries into dynamic shapes, and also sensors. This way, your shapes (tangram pieces) will always react with the boundaries, even if you’re changing those draggable pieces from dynamic to kinematic at different times. I assume you don’t have any gravity in this game, so your boundary shapes won’t be affected by that and fall off the screen.

  2. Biggest point: you need to handle your counter actions in the collision function , not in the dragging function. You’re getting a value of “1” on the counter during the “began” phase, because that’s when you first grab the piece. Where you need to manage your counter is in the collision function, so when it overlaps a boundary (or exits a boundary) the counter is adjusted accordingly.

I like “local” collisions, personally, versus “global”, but it’s largely a matter of preference. Both handle collisions in a similar manner, just that “local” puts a collision listener on objects individually, while “global” checks the whole physical world’s collision states during runtime.
http://developer.coronalabs.com/content/game-edition-collision-detection

Anyway, build your collision function based on the examples and let me know what happens. Just increase the counter during the “began” phase of the collision, and reduce it during the “ended” phase. Go ahead and keep using the master counter for testing, but eventually you’ll want to attach a counter to each shape, for example “shape1.collCount = 0”.

Best of luck!
Brent
[import]uid: 9747 topic_id: 24523 reply_id: 121686[/import]

Hey Brent,
I’m close … I think. I made the rect object a dynamic shape and the crate object kinematic. Moved the counter to collision function and it worked … kinda of. I don’t know how to make the rect object not use gravity. It drops off the screen but as it drops, it passes through the crate object. The counter goes up 1 as it touches the crate and then goes to 0 as it passes through the crate. So I think I got that right thanks to your help but can’t figure out where gravity is set.
Thanks,
Betsy [import]uid: 168506 topic_id: 24523 reply_id: 121690[/import]

Sorry … figured out the physics.setGravity. Now the rect doesn’t fall. [import]uid: 168506 topic_id: 24523 reply_id: 121692[/import]

Well I’m trying your suggestion but I’m not sure I’ve got the counter working right. Here’s a simple example where I’ve made a rectangle be a sensor object with a crate being dragged into the sensor region. But my counter isn’t working. Please advice.

local physics = require(“physics”)
physics.start()

display.setStatusBar( display.HiddenStatusBar )

local counter = 0

– A basic function for dragging physics objects
local function startDrag( event )
local t = event.target

local phase = event.phase
if “began” == phase then
counter = counter + 1
display.getCurrentStage():setFocus( t )
t.isFocus = true

– Store initial position
t.x0 = event.x - t.x
t.y0 = event.y - t.y

– Stop current motion, if any
event.target:setLinearVelocity( 0, 0 )
event.target.angularVelocity = 0

elseif t.isFocus then
if “moved” == phase then
t.x = event.x - t.x0
t.y = event.y - t.y0

elseif “ended” == phase or “cancelled” == phase then
display.getCurrentStage():setFocus( nil )
t.isFocus = false
counter = counter - 1

end
end
print (counter)

– Stop further propagation of touch event!
return true
end

local crate = display.newImage( “crate.png” )
crate.x = 90; crate.y = 90
physics.addBody( crate, “kinematic”, { friction=0.7} )

local rect = display.newRect( 50, 50, 100, 100 )
rect.x = 150; rect.y = 200
rect:setFillColor( 255, 255, 255, 100 )
rect.isVisible = true
physics.addBody( rect, “kinematic”, { friction=0.7, isSensor = true } )

crate:addEventListener( “touch”, startDrag ) [import]uid: 168506 topic_id: 24523 reply_id: 121597[/import]

Hi Betsy,

Can you be more specific about what’s not working in your code? Is the counter not keeping the proper count? You actually need to use a counter for every object (every shape in your tangram), not a “master” counter. Each shape must keep track of how many boundaries it’s overlapping.

You also must subtract from the counter during the “ended” phase, as in, when the tangram shape exits the boundaries, its counter reduces until it’s 0, meaning that it’s clear of all boundaries.

So, please let me know more specifically what’s happening and we should be able to narrow it down!

EDIT: Oops, just saw that you are subtracting from the counter! Next time you post code, can you also surround it with code tags? This helps me and others read it much easier.

Best regards,
Brent [import]uid: 9747 topic_id: 24523 reply_id: 121600[/import]

Sorry about the code. I just cut and paste it into the forum. Anyhow this is what I tried to do. I defined an object called rect which has the .isSensor = true. I also have an object called crate which I want to fit within the rect object. They both are defined as kinematic with the same friction value. So I set up a drag function which when the phase == “began” increments the variable counter by 1. When the drag function’s phase == “ended”, the counter subtracts 1. Within the function, I have a print function showing what the counter value is.
This is what I see. As I start to drag the crate object, the console keeps printing 1 even though the crate has never entered the boundaries of the rect object. When I stop dragging the crate object, the counter prints out the value of 0. Doesn’t matter whether I have drag the crate object into the rect object or not. Counter stays 1 and goes to 0 when I stop dragging. That’s why I don’t know if I have set up the objects right and whether I have the counter working right. Does that make sense? Sorry if I’m not using the right phrase but I really new to this.
Thanks. [import]uid: 168506 topic_id: 24523 reply_id: 121679[/import]

Hi Betsy,
That really clears it up. Here’s what is slightly wrong so far, that I can see.

  1. I don’t think kinematic bodies react (collide) with other kinematic bodies. There are some fairly obscure “rules” about this, and I can’t remember exactly what they are for every case. What I can say for certain is that a “dynamic” body will always react with another body type (assuming you haven’t excluded it with collision filters or something). The point is, you should make your boundaries into dynamic shapes, and also sensors. This way, your shapes (tangram pieces) will always react with the boundaries, even if you’re changing those draggable pieces from dynamic to kinematic at different times. I assume you don’t have any gravity in this game, so your boundary shapes won’t be affected by that and fall off the screen.

  2. Biggest point: you need to handle your counter actions in the collision function , not in the dragging function. You’re getting a value of “1” on the counter during the “began” phase, because that’s when you first grab the piece. Where you need to manage your counter is in the collision function, so when it overlaps a boundary (or exits a boundary) the counter is adjusted accordingly.

I like “local” collisions, personally, versus “global”, but it’s largely a matter of preference. Both handle collisions in a similar manner, just that “local” puts a collision listener on objects individually, while “global” checks the whole physical world’s collision states during runtime.
http://developer.coronalabs.com/content/game-edition-collision-detection

Anyway, build your collision function based on the examples and let me know what happens. Just increase the counter during the “began” phase of the collision, and reduce it during the “ended” phase. Go ahead and keep using the master counter for testing, but eventually you’ll want to attach a counter to each shape, for example “shape1.collCount = 0”.

Best of luck!
Brent
[import]uid: 9747 topic_id: 24523 reply_id: 121686[/import]

Hey Brent,
I’m close … I think. I made the rect object a dynamic shape and the crate object kinematic. Moved the counter to collision function and it worked … kinda of. I don’t know how to make the rect object not use gravity. It drops off the screen but as it drops, it passes through the crate object. The counter goes up 1 as it touches the crate and then goes to 0 as it passes through the crate. So I think I got that right thanks to your help but can’t figure out where gravity is set.
Thanks,
Betsy [import]uid: 168506 topic_id: 24523 reply_id: 121690[/import]

Sorry … figured out the physics.setGravity. Now the rect doesn’t fall. [import]uid: 168506 topic_id: 24523 reply_id: 121692[/import]