Isolating spawned objects

Hi all.

I’m making an endless runner. The ground is made up of MANY ‘tiles’ (all the same). I would like to apply a collision event that operates at a single-tile-level, ie; It drops off the screen when the ‘ball’ bounces on it… I’m struggling to apply events to the tile where the collision happens.

I managed to find a few tutorials that handle event.target, but from what I can gather this is a touch-based trigger, not a collision.

Also, there’s a strong possibility I’ll spawn a LOT of tiles, so indexing each (via a table), is not viable.

Hopefully this code will explain a little better what I’m trying to achieve:

for j = 1,21 do tile = display.newRect( display.contentCenterX, 0, 50, 50) tile.x = 20 + (j\*50) tile.y = 469 tile:setFillColor( 1, 1, 1 ) tile.strokeWidth = 1 tile:setStrokeColor( 0, 0, 0 ) physics.addBody(tile, "static",{ density=2, friction=0.3, bounce=0.0 } ) tile.collision = bounceEventGround tile:addEventListener( "collision", tile ) local groundGroup = display.newGroup() groundGroup:insert(tile) end

And the collision handler looks something like this:

local function bounceEventGround(event) if event.phase == "began" then event.target:setFillColor( 0.2, 0.1, 0.1 ) end return true end

Obviously event.target doesn’t work… is there a kind of equivalent?

All the best

You want this:

local function bounceEventGround(self, event) if event.phase == "began" then self:setFillColor( 0.2, 0.1, 0.1 ) end end

Also, you can index every tile. You just need to make their original variable a table from the outset. Also, I don’t know if you are intending this, but your code above is creating 21 tiles, and each tile is getting it’s own unique groundGroup display.newGroup to insert itself into. Try this:

local tile = {} local groundGroup = display.newGroup() for j = 1,21 do tile[j] = display.newRect( display.contentCenterX, 0, 50, 50) tile[j].x = 20 + (j\*50) tile[j].y = 469 tile[j]:setFillColor( 1 ) tile[j].strokeWidth = 1 tile[j]:setStrokeColor( 0, 0, 0 ) physics.addBody(tile[j], "static",{ density=2, friction=0.3, bounce=0.0 } ) tile[j].collision = bounceEventGround tile[j]:addEventListener( "collision", tile[j] ) groundGroup:insert(tile[j]) end

Ah thanks, yes I see what I was doing wrong now… I didn’t want to create multiple display groups… That could’ve ended up being a real problem. Thanks. 11 stars :slight_smile:

Just following on (I may start this as another topic). Can I apply conditional logic to ‘self’… I’ve been trying, but can’t seem to get a response.

This is just an example, I hope it conveys what I’m trying to achieve.

local function bounceEventGround(self, event) if event.phase == "began" and self.alpha == 1 then self:setFillColor( 0.8, 0.4, 0.3 ) self.apha = 0.9 elseif event.phase == "began" and self.alpha == 0.9 then self:removeSelf() end return true end

I hope you can see, that I want an event (self:removeSelf) to occur on the second collision, I’m sure there’s a better way to achieve this, but I’m not sure how… I tried having a local variable, like local hasBounced = 0, but after applying a change to it, it’s obviously not ‘object specific’, so I’m not getting the desired results.

Thanks

I’ve never tried this using an alpha property, but I don’t see why it can’t work. However, if the above is your actual code, you have the listener set with a variable of ‘apha’ and not’alpha’.

You can do this with unique object variables by setting in the spawn logic. Try this:

tile[j].hasHit = 0

Then later during collisions you would want to increase it, usually like this:

if event.phase == “began” then

self.hasHit = self.hasHit + 1

end

Thanks for this… Taking it a step further, how would I reference the object with a piece of code that was out of scope, like this:

 local function remove(event) j:removeSelf() ---assuming tile[j].ID = j end local function bounceEventGround(self, event) if event.phase == "began" and self.alpha == 1 then self:setFillColor( 0.8, 0.4, 0.3 ) self.alpha = 0.9 self.hasHit = self.hasHit + 1 elseif event.phase == "began" and self.hasHit == 1 then transition.to( self, { time=500, y=(550), alpha=0, onComplete=remove}) end return true end

Referencing spawned objects is a new challenge for me, I’m finding it quite tough.

Just found a useful post concerning the issue above. If anyone is looking for a similar solution, try this:

http://forums.coronalabs.com/topic/25866-question-about-transitionto-and-eventtargetremoveself/

You want this:

local function bounceEventGround(self, event) if event.phase == "began" then self:setFillColor( 0.2, 0.1, 0.1 ) end end

Also, you can index every tile. You just need to make their original variable a table from the outset. Also, I don’t know if you are intending this, but your code above is creating 21 tiles, and each tile is getting it’s own unique groundGroup display.newGroup to insert itself into. Try this:

local tile = {} local groundGroup = display.newGroup() for j = 1,21 do tile[j] = display.newRect( display.contentCenterX, 0, 50, 50) tile[j].x = 20 + (j\*50) tile[j].y = 469 tile[j]:setFillColor( 1 ) tile[j].strokeWidth = 1 tile[j]:setStrokeColor( 0, 0, 0 ) physics.addBody(tile[j], "static",{ density=2, friction=0.3, bounce=0.0 } ) tile[j].collision = bounceEventGround tile[j]:addEventListener( "collision", tile[j] ) groundGroup:insert(tile[j]) end

Ah thanks, yes I see what I was doing wrong now… I didn’t want to create multiple display groups… That could’ve ended up being a real problem. Thanks. 11 stars :slight_smile:

Just following on (I may start this as another topic). Can I apply conditional logic to ‘self’… I’ve been trying, but can’t seem to get a response.

This is just an example, I hope it conveys what I’m trying to achieve.

local function bounceEventGround(self, event) if event.phase == "began" and self.alpha == 1 then self:setFillColor( 0.8, 0.4, 0.3 ) self.apha = 0.9 elseif event.phase == "began" and self.alpha == 0.9 then self:removeSelf() end return true end

I hope you can see, that I want an event (self:removeSelf) to occur on the second collision, I’m sure there’s a better way to achieve this, but I’m not sure how… I tried having a local variable, like local hasBounced = 0, but after applying a change to it, it’s obviously not ‘object specific’, so I’m not getting the desired results.

Thanks

I’ve never tried this using an alpha property, but I don’t see why it can’t work. However, if the above is your actual code, you have the listener set with a variable of ‘apha’ and not’alpha’.

You can do this with unique object variables by setting in the spawn logic. Try this:

tile[j].hasHit = 0

Then later during collisions you would want to increase it, usually like this:

if event.phase == “began” then

self.hasHit = self.hasHit + 1

end

Thanks for this… Taking it a step further, how would I reference the object with a piece of code that was out of scope, like this:

 local function remove(event) j:removeSelf() ---assuming tile[j].ID = j end local function bounceEventGround(self, event) if event.phase == "began" and self.alpha == 1 then self:setFillColor( 0.8, 0.4, 0.3 ) self.alpha = 0.9 self.hasHit = self.hasHit + 1 elseif event.phase == "began" and self.hasHit == 1 then transition.to( self, { time=500, y=(550), alpha=0, onComplete=remove}) end return true end

Referencing spawned objects is a new challenge for me, I’m finding it quite tough.

Just found a useful post concerning the issue above. If anyone is looking for a similar solution, try this:

http://forums.coronalabs.com/topic/25866-question-about-transitionto-and-eventtargetremoveself/