Question About "if" and "elseIf"

I don’t buy the idea that there are multiple ‘began’ phases for a single instance of beam.

Adjust your print statement like this:

print( self.objType, " colliding with ", other.objType, " phase: ", phase, tostring(other), tostring(self) )

Then run again and please dump the log here.

10:25:52.451 zombie colliding with beam phase: began table: 0EAE5670 table: 0EAEB0E8
10:25:52.451 beam
10:25:52.538 zombie colliding with beam phase: began table: 0EAE5E68 table: 0EAEB0E8
10:25:52.538 beam
10:25:55.619 zombie colliding with hero phase: began table: 0EAEB548 table: 0EAEB0E8
10:25:56.061 zombie colliding with hero phase: ended table: 0EAEB548 table: 0EAEB0E8

If you read the first two ‘zombie colliding’ lines of that log you can see that there are two different beam objects getting a began, so there are no two objects colliding with each other getting multiple begans between them, without first seeing an end. In short, collisions are working correctly.

For reference, the print statement:
print( self.objType, " colliding with ", other.objType, " phase: ", phase, tostring(other), tostring(self) )

The trimmed and marked-up log:

1 - zombie colliding with beam phase: began table: 0EAE5670 table: 0EAEB0E8
2 - zombie colliding with beam phase: began table: 0EAE5E68 table: 0EAEB0E8

The two beam IDs (highlighted above):

  1. other == beam - 0EAE5670
  2. other == beam - 0EAE5E68

If were to hazard a guess… You’re probably deleting the beams after collision began phase, so there is no end.

If you’ve got two beams and expect only one, then you may have created two at the same time through incorrect logic.

It would be interesting to see the sime time on those collisions:

print( self.objType .. " id: " .. tostring(self) .. " collided with 'other' " .. other.objType .. " id: " .. tostring(other) .. "; phase == " ..  phase .. " @ " .. tostring(system.getTimer())   )

20:58:02.373 zombie id: table: 0E7C3E70 collided with ‘other’ beam id: table: 0E6D51F8; phase == began @ 9728.3
20:58:02.373 beam
20:58:02.456 zombie id: table: 0E7C3E70 collided with ‘other’ beam id: table: 0E7C2110; phase == began @ 9811.7
20:58:02.456 beam

And here is code where I am adding beam:

          local beam = display.newRect( display.contentCenterX + 50, display.contentCenterY - 130, 15, 100 )
          beam.fill = {1,0,0}
          beam.alpha = 0
          beam.objType = "beam"
          physics.addBody(beam,"static")
          timer.performWithDelay(700, function()
            beam:removeSelf()

This code is in function what runs after button is pressed

I can’t tell because you didn’t give all the code, but if you aren’t paying attention to phases in the touch, then that code will get called for all phases:

  • began, moved, ended

at the very least began and ended, which means it gets called twice in short order.

which part of code should I give?

Just look at your touch listener on your own and see if you’re paying attention to phases. I think that is the issue.

Tip: I quickly reviewed the long code dump further up, but didn’t immediately see a function that looked like a touch listener so I bailed on the analysis.

You should use names that are linked to events for easy of debug (for you and others).

e.g. A touch listener function should probably have the word touch in it. For example, I create buttons like this and it is very clear what the touch listeners is when reviewing the code.

local obj = create button code

function obj.touch( self, event )
... body of listener
end

obj:addEventListener('touch')

or I do this sometimes, also easy to find and debug:

-- single listener used by multiple objects
local function onTouch( self, event )
... body of listener
end

local obj1 = create button code
local obj2 = create button code
local obj3 = create button code

obj1.touch = onTouch
obj1:addEventListener('touch')

obj2.touch = onTouch
obj2:addEventListener('touch')

obj2.touch = onTouch
obj2:addEventListener('touch')

Sorry to be terse, but I’m short on time and have to run. So I hope this will get you closer to the issue.

Yeah, that was the issue, thanks for help! And sorry for lost time on this issue. :sweat_smile:

And I have one more question, can I do self:removeSelf() in a function when self is zombie?
Or I need to remove it some other way?

  1. Yes.

  2. Safer to not use obj:removeSelf(), but use display.remove( obj ) instead. Just get in the habit now and you’ll save yourself a LOT of pain in the future.

In case it is not 100% clear from #2, you your question you would literally replace

self:removeSelf()

with

display.remove( self )

This is safer because, if for some reason, self was already deleted or is nil, the display.remove() will do nothing and NOT crash, but the prior code would crash.

ok, thanks :slight_smile: