isSensor causing multiple collisions?

Hi guys,
Just having a bit of trouble with objects.

I’ve got a kinematic object which is a sensor aswell. However when it collides with another object (dynamic), the collision is fired about 5 times. I say 5 but it is quite random - between 4-8 times!

Is there any way to have it fire only once? [import]uid: 40538 topic_id: 13795 reply_id: 313795[/import]

you can remove eventlistener for collision upon first collision
if it suits you- try it, but thats not something good to do i think) [import]uid: 16142 topic_id: 13795 reply_id: 50645[/import]

That won’t work because it’ll make the object stop colliding with anything else which is what I don’t want. [import]uid: 40538 topic_id: 13795 reply_id: 50669[/import]

renvis, my other thread (IF OR statement) is what I’ve been trying to do. I’ve tried giving the object names, but it doesn’t seem to register.

If I remove the EventListener upon collision, the objects stop receiving collisions, so how will that work?

I want the objects to continue receiving collisions. [import]uid: 40538 topic_id: 13795 reply_id: 50680[/import]

you can remove the eventlistener as darkconsoles said. if you want it to happen only when colliding with certain objects( give name to objects and check event.other.name)

other option is to set a variable when collision occurs.
eg
event.target.collision = 1

then in collision listener function use
[lua]if event.target.collision == 1 then return true end[/lua] [import]uid: 71210 topic_id: 13795 reply_id: 50677[/import]

try putting “and” in the if condition. [import]uid: 71210 topic_id: 13795 reply_id: 50684[/import]

renvis, I’m having trouble again lol - it’s not working and I’ve been trying to work it out for the past few days.
As I mentioned, I have 1 dynamic object and 1 kinematic - and all that is supposed to happen is that the dynamic object can “collect” the kinematic object - that’s it!

But the collision is still firing about 8 times, and so the score updates 8 times too! This has never happened on my other games before :frowning:
I don’t understand why this doesn’t happen with the pool sample as I am using sensors too. [import]uid: 40538 topic_id: 13795 reply_id: 51297[/import]

this will help you can see how circle printing only one time and rect every time

[lua]local physics = require “physics”
physics.start()

local circle = display.newCircle(30,30,10)
circle.myName = “circle”
physics.addBody(circle)

local rect = display.newRect(90,30,10,10)
rect.myName = “rect”
physics.addBody(rect)

local myObj = display.newRect(0,300,320,10)
myObj.myName = “ground”
physics.addBody(myObj,“kinematic”)

local function onCollision( event )
if event.object1.myName == “circle” or event.object1.myName == “rect” then

print( event.object1.myName … " & " … event.object2.myName )
if event.object1.myName == “circle” then
event.object1.myName = “asdasd”
end
end
end

Runtime:addEventListener( “collision”, onCollision )[/lua]
:slight_smile: [import]uid: 12482 topic_id: 13795 reply_id: 51300[/import]

@w.baig84 can you post the code please ? [import]uid: 71210 topic_id: 13795 reply_id: 51305[/import]

[code]

local function onLocalCollision( self, event )
if ( event.phase == “began”) then
if ( event.other.name == “coin 1” or event.other.name == “coin 2” ) then

local doCollision = function()

myCoinsNew = myCoinsNew + myCoinsVar
coinsText.text = "x "…myCoinsNew

print( self.name … ": collision began with " … event.other.name )

local coinAnim = movieclip.newAnim{ “images/coins/coin1@2x.png”,
“images/coins/coin2@2x.png”,
“images/coins/coin3@2x.png”,
“images/coins/coin4@2x.png”,
“images/coins/coin5@2x.png”,
“images/coins/coin6@2x.png”,
“images/coins/coin7@2x.png”,
“images/coins/coin8@2x.png”,
“images/coins/coin9@2x.png”,
“images/coins/coin8@2x.png”,
“images/coins/coin7@2x.png”,
“images/coins/coin6@2x.png”,
“images/coins/coin5@2x.png”,
“images/coins/coin4@2x.png”,
“images/coins/coin3@2x.png”,
“images/coins/coin2@2x.png”,
“images/coins/coin1@2x.png”,

}

coinAnim.x = event.other.x
coinAnim.y = event.other.y
coinAnim.xScale = 0.5
coinAnim.yScale = 0.5
coinAnim:play()
coinAnim:setReferencePoint(display.CenterReferencePoint)
localGroup:insert(coinAnim)

event.other.isBodyActive = false
event.other.isVisible = false

trans1 = transition.to( coinAnim, { time=1500, x=480, y=75, alpha = 0})

end

local collisionTimer = timer.performWithDelay( 1, doCollision, 1 )

end
end
end

[/code] [import]uid: 40538 topic_id: 13795 reply_id: 51313[/import]

can i have code for objects and collision registering also ? [import]uid: 71210 topic_id: 13795 reply_id: 51321[/import]

Full code:

  
local player = display.newImageRect(img1, playerW, playerH)  
 player:setReferencePoint(display.CenterReferencePoint)  
 physics.addBody( player, physicsData:get(physInfo) )  
 player.bodyType = "kinematic"  
 player.isFixedRotation = true  
 player.xScale = playerScale  
 player.yScale = playerScale  
 player.x = 50  
 player.y = \_H / 2  
  
 player.name = "player"  
  
local coin1 ={}  
 local coins1  
  
  
 coins1 = {2,2.25,2.5,2.75,3}  
 local rand3 = math.random (2, #coins1 )  
  
 local coin1 = movieclip.newAnim{ "images/coins/coin1@2x.png",  
 "images/coins/coin2@2x.png",  
 "images/coins/coin3@2x.png",  
 "images/coins/coin4@2x.png",  
 "images/coins/coin5@2x.png",  
 "images/coins/coin6@2x.png",  
 "images/coins/coin7@2x.png",  
 "images/coins/coin8@2x.png",  
 "images/coins/coin9@2x.png",  
 "images/coins/coin8@2x.png",  
 "images/coins/coin7@2x.png",  
 "images/coins/coin6@2x.png",  
 "images/coins/coin5@2x.png",  
 "images/coins/coin4@2x.png",  
 "images/coins/coin3@2x.png",  
 "images/coins/coin2@2x.png",  
 "images/coins/coin1@2x.png",  
  
 }  
 coin1.xScale = 0.5  
 coin1.yScale = 0.5  
 coin1:play()  
  
 coin1:setReferencePoint(display.CenterReferencePoint)  
 localGroup:insert(coin1)  
 physics.addBody( coin1,"kinematic", {isSensor = true, radius = 13})  
 coin1.name = "coin 1"  
 coin1.x = \_W \* 2 + \_W/2  
 coin1.y = \_H / rand3  
  
 local coin2 ={}  
 local coins2  
  
  
 coins2 = {2,2.25,2.5,2.75,3}  
 local rand4 = math.random (2, #coins2 )  
  
 local coin2 = movieclip.newAnim{ "images/coins/coin1@2x.png",  
 "images/coins/coin2@2x.png",  
 "images/coins/coin3@2x.png",  
 "images/coins/coin4@2x.png",  
 "images/coins/coin5@2x.png",  
 "images/coins/coin6@2x.png",  
 "images/coins/coin7@2x.png",  
 "images/coins/coin8@2x.png",  
 "images/coins/coin9@2x.png",  
 "images/coins/coin8@2x.png",  
 "images/coins/coin7@2x.png",  
 "images/coins/coin6@2x.png",  
 "images/coins/coin5@2x.png",  
 "images/coins/coin4@2x.png",  
 "images/coins/coin3@2x.png",  
 "images/coins/coin2@2x.png",  
 "images/coins/coin1@2x.png",  
  
 }  
 coin2.xScale = 0.5  
 coin2.yScale = 0.5  
 coin2:play()  
  
 coin2:setReferencePoint(display.CenterReferencePoint)  
 localGroup:insert(coin2)  
 physics.addBody( coin2,"kinematic", {isSensor = true, radius = 13})  
 coin2.name = "coin 2"  
 coin2.x = \_W \* 3 + \_W/2  
 coin2.y = \_H / rand4  
  
local function onLocalCollision( self, event )   
 if ( event.phase == "began") then  
 if ( event.other.name == "coin 1" or event.other.name == "coin 2" ) then  
  
  
 local doCollision = function()  
  
 myCoinsNew = myCoinsNew + myCoinsVar  
 coinsText.text = "x "..myCoinsNew  
  
 print( self.name .. ": collision began with " .. event.other.name )  
  
  
 local coinAnim = movieclip.newAnim{ "images/coins/coin1@2x.png",  
 "images/coins/coin2@2x.png",  
 "images/coins/coin3@2x.png",  
 "images/coins/coin4@2x.png",  
 "images/coins/coin5@2x.png",  
 "images/coins/coin6@2x.png",  
 "images/coins/coin7@2x.png",  
 "images/coins/coin8@2x.png",  
 "images/coins/coin9@2x.png",  
 "images/coins/coin8@2x.png",  
 "images/coins/coin7@2x.png",  
 "images/coins/coin6@2x.png",  
 "images/coins/coin5@2x.png",  
 "images/coins/coin4@2x.png",  
 "images/coins/coin3@2x.png",  
 "images/coins/coin2@2x.png",  
 "images/coins/coin1@2x.png",  
   
 }  
  
 coinAnim.x = event.other.x  
 coinAnim.y = event.other.y  
 coinAnim.xScale = 0.5  
 coinAnim.yScale = 0.5  
 coinAnim:play()  
 coinAnim:setReferencePoint(display.CenterReferencePoint)  
 localGroup:insert(coinAnim)  
  
 event.other.isBodyActive = false  
 event.other.isVisible = false  
  
 trans1 = transition.to( coinAnim, { time=1500, x=480, y=75, alpha = 0})  
  
 end  
  
 local collisionTimer = timer.performWithDelay( 1, doCollision, 1 )   
   
  
 end  
 end  
 end  
  
player.collision = onLocalCollision  
player:addEventListener( "collision", player)  
  

I want to add that although the player is kinematic to begin with, it does change to dynamic when the game starts. [import]uid: 40538 topic_id: 13795 reply_id: 51323[/import]

@ w.baig84 This seems like a bug. I’m getting this issue all over the place as well. Have you submitted a bug to Ansca? [import]uid: 27183 topic_id: 13795 reply_id: 51378[/import]

@don,

I’ve not no, but it’s become a real showstopper for me, and so I’ve tried amending the code.

I’ve gotten rid of the sensors for starters, but now, although it works, the simulator randomly crashes due to the colliding objects bugs.
As I’ve said, I’ve done this a number of times in previous games, and it has not once crashed.
With the sensor, it seems as though it’s been made so that if an object’s isSensor property = true then the collision will fire for as long as the objects are colliding, which makes sense.

Well, what if we want the object to be a sensor, but only fire once?

I think that’s where we’re sorta stuck. [import]uid: 40538 topic_id: 13795 reply_id: 51391[/import]

@w.baig84 I think it’s a bug since the events fire multiple times for the ‘began’ and ‘end’ phase when the object is a sensor. Imagine if sprite or touch events fired multiple times for their phases!

I think a bug report needs to be filed. Let me know if you’re going to do this otherwise, I will when I get a chance. [import]uid: 27183 topic_id: 13795 reply_id: 51427[/import]

Hmmm that’s true!
I’ve asked one of the Ansca staff member (Danny) who has posted in my other thread, to confirm what the isSensor property is really supposed to do.

[import]uid: 40538 topic_id: 13795 reply_id: 51436[/import]

It is not a bug. it is doing what it is supposed to do. when you give isSensor = true it will still collide but there won;t be any visible effects.

in a collision it is normal to have any event phase called many number of times. As I said before you should either remove the collision event on the began phase or can set a flag to denote that its already collided once.

@w.baig84 Am looking at your code… let me see whether I can put a fix for your problem. Just want to check a few things with you.
this is my understanding when i went through your code.
you have a player and 2 stars when player touches a star that stars visibility is set to false and a new star is spawned…
is this what u want to achieve ?
I can see a few glitches also in ur code…

  1. why are you declaring coin2 as a table ?
  2. why are you declaring coins1 and putting some numbers to it. where is it used ?
  3. is all your coins same ? then why can’t u just spawn a coin inside a function ? [import]uid: 71210 topic_id: 13795 reply_id: 51441[/import]

It is not a bug. it is doing what it is supposed to do.
* sorry a correction - it should happen only once for began and end. [import]uid: 71210 topic_id: 13795 reply_id: 51443[/import]

@renvis I still think it’s a bug. How does it make sense to have a ‘began’ and ‘end’ phase fired multiple times for a collision between the same two objects without separation?

To me that sounds like a touch event that has fired multiple times for its ‘began’ phase without lifting your finger. That most certainly is a bug.

What I would suggest is a new phase for the events in between like ‘colliding’. [import]uid: 27183 topic_id: 13795 reply_id: 51442[/import]

to knwo whats happening here I should know how the player is colliding with coin ?
are you dragging the player or is it moving affected by gravity ? [import]uid: 71210 topic_id: 13795 reply_id: 51444[/import]