Yes.
Did these happen all at once or was one the began’s from earlier? If they came in together, I would have expected 3 lives to have been lost. It’s more helpful to copy/paste the entire log conversation. In this case I could have looked at the time stamp and answered my own question.
Thanks
Rob
Hi @sdktester15,
Each body element in a multi-element body will generate a collision event. I thought that it was mentioned specifically in the Collisions guide, but it looks like I didn’t state it clearly enough (I’ll add a note for that).
For your case, you should probably set a property (flag) upon the first collision, and then ignore further collisions until you consider things “resolved”, i.e. the player dies, the enemy is removed, after a short amount of time like 100 milliseconds, etc.
Brent
They happened all at once.
Using a boolean variable right? But, how would I check for the first began phase?
Something like:
local isColliding = false function onCollision(event) local function removeOnPlayerHit(obj1, obj2) if((obj ~= nil ) and ((obj.id == "enemy") or (obj.id == "enemy2") or (obj.id == "enemy3") or (obj.id == "enemy4"))) then display.remove(obj) end end local function showPlayerHit() local tmr\_onPlayerHit = timer.performWithDelay(1, playerHit, 1) end if event.phase == "began" then if isColliding then return end if((event.object1.id == "enemy" or event.object1.id == "enemy2" or event.object1.id == "enemy3" or event.object1.id == "enemy4") and event.object2.id == "character") then showPlayerHit() removeOnPlayerHit(event.object1, nil) elseif(event.object1.id == "character" and (event.object2.id == "enemy" or event.object2.id == "enemy2" or event.object2.id == "enemy3" or event.object2.id == "enemy4")) then showPlayerHit() removeOnPlayerHit(nil, event.object2) end elseif event.phase == "ended" then isColliding = false end end
or something like that. (untested). You might want to the body part ID that trigger the first collision instead of a boolean and ignore any “began” phases from the different body parts. That information would be in event.element1 for object1 and event.element2 for object2.
Now to expand your game, this last idea could offer you a cool feature. You could go back into Physics Engine and re-generate your scorpion in a way that one physics body is its pinchers, one physics body is its body and another is it’s tail/stinger. If your hero collides with the pinchers/tail he looses a life. If he collides with the body, he kills the scorpion.
["scorpion"] = { { pe\_fixture\_id = "", density = 2, friction = 0, bounce = 0, filter = { categoryBits = 1, maskBits = 65535, groupIndex = 0 }, shape = { -33.5, 0 , -78.5, 48 , -77.5, 0 } } , { pe\_fixture\_id = "", density = 2, friction = 0, bounce = 0, filter = { categoryBits = 1, maskBits = 65535, groupIndex = 0 }, shape = { 81.5, -52 , 81.5, 48 , 15.5, -5 , 15.5, -52 } } , { pe\_fixture\_id = "", density = 2, friction = 0, bounce = 0, filter = { categoryBits = 1, maskBits = 65535, groupIndex = 0 }, shape = { -78.5, 48 , -33.5, 0 , 15.5, -5 , 81.5, 48 } } , { pe\_fixture\_id = "", density = 2, friction = 0, bounce = 0, filter = { categoryBits = 1, maskBits = 65535, groupIndex = 0 }, shape = { -33.5, -5 , 15.5, -5 , -33.5, 0 } } }
Your code did not work. Is there anything strange about this code, it is responsible for making the physics shape for the scorpion?
“Now to expand your game, this last idea could offer you a cool feature. You could go back into Physics Engine and re-generate your scorpion in a way that one physics body is its pinchers, one physics body is its body and another is it’s tail/stinger. If your hero collides with the pinchers/tail he looses a life. If he collides with the body, he kills the scorpion.”
This sounds like a great idea, however, what if the player hits both the stinger and the body at the same time?
As far as the code goes you will have to try different things. Your PE created code is fine.
What if they hit the stinger and body at the same time? If it were me, I’d kill both. Give the player points for the scorpion and take away a life. You will want to re-do the shapes they are not now conducive for this. You may find it too hard and that players won’t attempt to kill the scorpion in which case it won’t matter.
Ok, Thank you.
How could I write code for different parts of there physics bodies?
I found this tutorial: https://coronalabs.com/blog/2013/01/08/working-with-multi-element-physics-bodies/, but where can I find it in the Corona documentation, or if it is not found, could you provide any other tutorials on this, thank you. I found this tutorial a bit confusing.
How would I create an if statement checking this, would I have to find a way to get the fixture’s names?
I also have another question, will there be any more documentation released for the following topics:
https://docs.coronalabs.com/api/event/collision/element1.html
https://docs.coronalabs.com/api/event/collision/element2.html
https://docs.coronalabs.com/api/event/collision/object1.html
https://docs.coronalabs.com/api/event/collision/object2.html
Is there something specific you’re looking for?
Yes, I want to know how I could do a check to determine if the character hit one element or the other.
For instance:
if (character hits element one) then KillEnemy() elseif(character hits element two) then KillPlayer() elseif(character hits both) then KillEnemy() KillPlayer()
For now I just want to print messages to the console every time one or the other element is hit, how could I check to see which was hit?
Have you looked at our Getting Started guide? It has examples of how to detect collisions.
Rob
Yes, but there were no multi-element collisions.
Hi @sdktester15,
If you’re using multi-element bodies and collision detection, those additional properties will exist (i.e. selfElement/otherElement or element1/element2 depending on if you’re using “local” or “global” collision detection), and they will be non-1. If you’re not using multi-element bodies, those properties will always be 1 because there’s only one body element. Does that help or is there something else I can clarify?
This guide section clarifies things better as well:
https://docs.coronalabs.com/guide/physics/collisionDetection/index.html#multi-element-collisions
Best regards,
Brent
Thank you, can you clarify how I can check if the character hits a specific element?
Is it something like this:
if (event.object1.element1 == tail) end
I don’t know how to create an ID for the elements that are generated by Physics Editor:
local unpack = unpack local pairs = pairs local ipairs = ipairs local M = {} function M.physicsData(scale) local physics = { data = { ["Walk\_\_009 copy"] = { { pe\_fixture\_id = "back", density = 2, friction = 0, bounce = 0, filter = { categoryBits = 1, maskBits = 65535, groupIndex = 0 }, shape = { -1.5, -25 , 75.5, -25 , 75.5, 28 , -1.5, 28 } } , { pe\_fixture\_id = "stinger", density = 2, friction = 0, bounce = 0, filter = { categoryBits = 1, maskBits = 65535, groupIndex = 0 }, shape = { -82.5, 26 , -82.5, -48 , -1.5, -48 , -1.5, 26 } } } } } -- apply scale factor local s = scale or 1.0 for bi,body in pairs(physics.data) do for fi,fixture in ipairs(body) do if(fixture.shape) then for ci,coordinate in ipairs(fixture.shape) do fixture.shape[ci] = s \* coordinate end else fixture.radius = s \* fixture.radius end end end function physics:get(name) return unpack(self.data[name]) end function physics:getFixtureId(name, index) return self.data[name][index].pe\_fixture\_id end return physics; end return M
I use Physics Editor for my shapes: https://www.codeandweb.com/physicseditor
I reviewed the collision article you sent me. So technically the element “back” was declared before “stinger” here. So, if I check if the character hits the one of the enemy’s elements, is it like this:
if event.phase == began then if ((event.object1.element1 == 1 and event.object2.id == "character") or (event.object1.id == "character" and event.object2.element1 == 1)) then KillEnemy() UpdateScore() elseif ((event.object1.element1 == 2 and event.object2.id == "character") or (event.object1.id == "character" and event.object2.element1 == 2)) then KillPlayer() end end