Simple question regarding collisions, probably regarding to collisionBit.

Hi,

I want to have a top border in my game that objects can get through it if they are moving downward but if they want to pass it from it’s bottom, i.e. moving upward, they would get removed.

I was trying to do this with collisionBit and maskedBits but I think I can either make Corona (in fact, Box2D) to ignore the collision with them or check the collision.

What I tried so far is to detect if object is going upward or downward with getting it’s linear velocity and check tag of the object it collided with but I can’t make it ignore the collision and go through the object if it’s moving downward and whatever I do, it bounces off from the border.

The effect I want to make can be thought similar to doodle jump, because in that game when object is moving from downward towards a platform, it can get through it but if it’s moving from up to down, it gets collided to the platform.

How can I achieve this?

It’s possible with disabling the collision and utilizing preCollsiion event. More info @ http://www.coronalabs.com/blog/2012/11/27/introducing-physics-event-contact/

I solved the problem with the preCollision event but sometimes game crashes in the preCollsision handler, saying that the “contact” is nil. Code seems to be OK because it works and I see my object going through my border but after a 2-3 of them going through the border, it suddenly crashes.

Here is the error message:

...lds)/trunk(default)/trunk/vertical\_sixty\_seconds.lua:377: attempt to index field 'contact' (a nil value) message stack traceback: ?: in function \<?:218\> [C]: ? ...lds)/trunk(default)/trunk/vertical\_sixty\_seconds.lua:377: in function \<...lds)/trunk(default)/trunk/vertical\_sixty\_seconds.lua:368\> ?: in function \<?:218\> 2013-05-25 17:38:09.164 Corona Simulator[2969:f03] Runtime error ...lds)/trunk(default)/trunk/vertical\_sixty\_seconds.lua:377: attempt to index field 'contact' (a nil value) stack traceback: [C]: ? ...lds)/trunk(default)/trunk/vertical\_sixty\_seconds.lua:377: in function \<...lds)/trunk(default)/trunk/vertical\_sixty\_seconds.lua:368\> ?: in function \<?:218\>

And here is my code:

local function PurpleFoodPreCollisionHandler(self, event) local collideObject = event.other if (collideObject.myType == "TopWall") then vx, vy = self:getLinearVelocity() if vy \> 0 then event.contact.isEnabled = false --disable this specific collision! print("asd isEnabled false for currnet collision") end end end

Strange thing is, even though I disable the collision, regular collision handler is still called, was it intentional by design? Because it’s kinda strange to me that when I explicitly disable a collision in pre collision, the regular collision handler is also called.

Thanks.

 

I checked the sample code form that page and I see that Corona guys used isSensor as well, do I have to do this? I thought setting isEnabled = false does the job and at least from outside standpoint, setting both isEnabled AND isSensor is too much.

I believe they are setting isSensor to prevent constant call to preCollision.

I tested my game even more but there STILL ARE some times that game crashes at the preCollision event, saying that “contact” is nil.

*deep sigh*.

What am I doing wrong?

Is it that “setAsSensor” that Corona’s sample code has? Is it because I’m not defining my preCollision handler function inline?

Why it happens so randomly?

I’m using 1076 build on Mac.

I modified my code to generate 1000 objects and move them fast across the border and I caught one of the situations that contact is nil. I checked the “event” with Glider and found that yes, there is actually no “contact” variable in “event” table, but the other parts are like a working event:

A buggy “event”: (notice how it lacks the “contact” field)

32431696092530814756.png

A working “event” with “contact”:

50854664863091810166.png

Are you still having this issue?

If so then have you set event listeners on all your objects or just the two way platform?

Collisions are a pain. I just fixed one of my own today, so I know how you feel. In my case I did not have the listeners setup correctly.

Some of the Samples online are correct it seems, so I looked at the provided samples and found the correct code to use.

[lua]

local function onCollision(self, event)
  --print(tostring(event.object1.myName))
  --print(event.phase, event.object2:getLinearVelocity())
  print( self.myName … ": collision began with " … event.other.myName )
 
  if ( event.phase == “began” ) then
      print(event.phase)
  else
      print(event.phase)
  end
 – print( self.myName … ": collision began with " )
 
end

oCollisionBarrier = display.newRect(0, _H-30, _W, 3)
oCollisionBarrier.myName = “oCollisionBarrier”

physics.addBody( oCollisionBarrier, “static”, { friction=0.7, isSensor = true} )

oCollisionBarrier.collision=onCollision
oCollisionBarrier:addEventListener(“collision”, oCollisionBarrier)

[/lua]

Good luck

Larry Meadows

Hi Larry, thanks for your reply.

I’m afraid that I’m still struggling with the bug. Worst thing is I have no idea which side is bug from, mine or Corona, because it happens like 98% of times.

I added collision event listener to objects that will collide with the TopWall object.

It’s funny that in the code sample of “preCollision” and “contact” tutorial, Corona guys still use isSensor, isn’t purpose of setting a isEnabled of a collision to false to not to use isSensor and just disable a collision event?!

Maybe I’m wrong somewhere here.

Thanks Larry but I don’t see anything strange with your code, would you please elaborate on the point you intended?

What caught my eye from that code is you using isSensor which, as Corona docs say, is not necessary.

After another sleepless night, I found Corona doc regarding this, at here we can read that:

One-sided platforms

In older versions of Box2D, you used to be able to set this property in a preCollision listener to create a “one-sided platform” case, where a character should pass through a platform only in one direction.

Instead of setting the sensor property, you need to set the isEnabled property of the PhysicsContact object.

So that code I was referring to was old and as I suspected I do not need to use isSensor.

What I’m not sure is why my preCollision is getting called constantly from the moment my object enters the top wall from the moment that it leaves it. Wish one of the staff would shed some light on this that is it supposed to be this way?

EDIT:

The contact is only disabled for the current time step.

So the only problem that still persists is that why there are times my collision has no “contact” within it.

Hi there,

wouldn’t it help just to check if event.contact exists and only if it does to set event.contact.isEnabled ?

Also I assume you won’t notice that one missing event, cause you got plenty of preCollision events for a single collision event.

if event.contact then event.contact.isEnabled = false end

Greetings

Torben

No because even checking something that is “nil” will throw system exceptions and may lead to crashes and more importantly will affect the game because the moment that I don’t disable the contact, the collision will get handled and object will get destroyed.

I “solved” this by setting isSensor to true and doing some other dirty work but I’m very unhappy with things I learned about Corona and events that it misses and other bugs that I faced in past 3 days which I don’t believe were from my side because I based Corona blog posts and documentations on them.

Sorry but that’s definetly not true.

If I check for a variable that doesn’t exist, the system won’t chrash. You can print it as well.

The only problem you could have is, if the variable you’re checking is a table entry and the table does not exist.

[LUA]

local variable = nil

print(variable)  --> nil

local table = nil

print(table.variable)  --> Will crash the system. Some error like “Tried to index field … does not exist”

[/LUA]

Did you test what I mentioned? Especially the point that you get several precollision events for one collision event?

It’s possible with disabling the collision and utilizing preCollsiion event. More info @ http://www.coronalabs.com/blog/2012/11/27/introducing-physics-event-contact/

I solved the problem with the preCollision event but sometimes game crashes in the preCollsision handler, saying that the “contact” is nil. Code seems to be OK because it works and I see my object going through my border but after a 2-3 of them going through the border, it suddenly crashes.

Here is the error message:

...lds)/trunk(default)/trunk/vertical\_sixty\_seconds.lua:377: attempt to index field 'contact' (a nil value) message stack traceback: ?: in function \<?:218\> [C]: ? ...lds)/trunk(default)/trunk/vertical\_sixty\_seconds.lua:377: in function \<...lds)/trunk(default)/trunk/vertical\_sixty\_seconds.lua:368\> ?: in function \<?:218\> 2013-05-25 17:38:09.164 Corona Simulator[2969:f03] Runtime error ...lds)/trunk(default)/trunk/vertical\_sixty\_seconds.lua:377: attempt to index field 'contact' (a nil value) stack traceback: [C]: ? ...lds)/trunk(default)/trunk/vertical\_sixty\_seconds.lua:377: in function \<...lds)/trunk(default)/trunk/vertical\_sixty\_seconds.lua:368\> ?: in function \<?:218\>

And here is my code:

local function PurpleFoodPreCollisionHandler(self, event) local collideObject = event.other if (collideObject.myType == "TopWall") then vx, vy = self:getLinearVelocity() if vy \> 0 then event.contact.isEnabled = false --disable this specific collision! print("asd isEnabled false for currnet collision") end end end

Strange thing is, even though I disable the collision, regular collision handler is still called, was it intentional by design? Because it’s kinda strange to me that when I explicitly disable a collision in pre collision, the regular collision handler is also called.

Thanks.

 

I checked the sample code form that page and I see that Corona guys used isSensor as well, do I have to do this? I thought setting isEnabled = false does the job and at least from outside standpoint, setting both isEnabled AND isSensor is too much.

I believe they are setting isSensor to prevent constant call to preCollision.

I tested my game even more but there STILL ARE some times that game crashes at the preCollision event, saying that “contact” is nil.

*deep sigh*.

What am I doing wrong?

Is it that “setAsSensor” that Corona’s sample code has? Is it because I’m not defining my preCollision handler function inline?

Why it happens so randomly?

I’m using 1076 build on Mac.

I modified my code to generate 1000 objects and move them fast across the border and I caught one of the situations that contact is nil. I checked the “event” with Glider and found that yes, there is actually no “contact” variable in “event” table, but the other parts are like a working event:

A buggy “event”: (notice how it lacks the “contact” field)

32431696092530814756.png

A working “event” with “contact”:

50854664863091810166.png

Are you still having this issue?

If so then have you set event listeners on all your objects or just the two way platform?

Collisions are a pain. I just fixed one of my own today, so I know how you feel. In my case I did not have the listeners setup correctly.

Some of the Samples online are correct it seems, so I looked at the provided samples and found the correct code to use.

[lua]

local function onCollision(self, event)
  --print(tostring(event.object1.myName))
  --print(event.phase, event.object2:getLinearVelocity())
  print( self.myName … ": collision began with " … event.other.myName )
 
  if ( event.phase == “began” ) then
      print(event.phase)
  else
      print(event.phase)
  end
 – print( self.myName … ": collision began with " )
 
end

oCollisionBarrier = display.newRect(0, _H-30, _W, 3)
oCollisionBarrier.myName = “oCollisionBarrier”

physics.addBody( oCollisionBarrier, “static”, { friction=0.7, isSensor = true} )

oCollisionBarrier.collision=onCollision
oCollisionBarrier:addEventListener(“collision”, oCollisionBarrier)

[/lua]

Good luck

Larry Meadows

Hi Larry, thanks for your reply.

I’m afraid that I’m still struggling with the bug. Worst thing is I have no idea which side is bug from, mine or Corona, because it happens like 98% of times.

I added collision event listener to objects that will collide with the TopWall object.

It’s funny that in the code sample of “preCollision” and “contact” tutorial, Corona guys still use isSensor, isn’t purpose of setting a isEnabled of a collision to false to not to use isSensor and just disable a collision event?!

Maybe I’m wrong somewhere here.

Thanks Larry but I don’t see anything strange with your code, would you please elaborate on the point you intended?

What caught my eye from that code is you using isSensor which, as Corona docs say, is not necessary.

After another sleepless night, I found Corona doc regarding this, at here we can read that:

One-sided platforms

In older versions of Box2D, you used to be able to set this property in a preCollision listener to create a “one-sided platform” case, where a character should pass through a platform only in one direction.

Instead of setting the sensor property, you need to set the isEnabled property of the PhysicsContact object.

So that code I was referring to was old and as I suspected I do not need to use isSensor.

What I’m not sure is why my preCollision is getting called constantly from the moment my object enters the top wall from the moment that it leaves it. Wish one of the staff would shed some light on this that is it supposed to be this way?

EDIT:

The contact is only disabled for the current time step.

So the only problem that still persists is that why there are times my collision has no “contact” within it.