Attempt to index field '?' a nil value error (a different one)

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

Or should I use event.selfElement?

Hi @sdktester15,

Are you using “local” or “global” collisions detection? The Collision Detection guide summarizes the difference… note that the syntax is slightly different for each method, especially in how you either detect collisions on a per-object basis, or in the global Runtime.

Depending on which method you’re using, the properties will be either “selfElement / otherElement” or “element1 / element2”, so first confirm which method you’re using before coding up which properties to detect.

In both methods, it’s the order in which the body elements were added to the object that determines the “index” of that element. I assume Physics Editor just loops through its table of data from top to bottom, adding them in order. You can probably just test that too by tossing in some print() statements in the collision handler and then check what value is output when something collides with the “stinger” part or the “back” part or whatever. Then you’ll know for sure. :slight_smile:

IMPORTANT:

I just noticed you’re detecting “event.object1.element1” in your code. That actually isn’t right… just use “event.element1” (or whatever the correct property is based on my tips). By using your syntax, it indicates that you’ve added a custom property to the object itself, but these properties are internal to the collision itself.

Hope this helps,

Brent

I am using global collision detection, so I will be using event.element1 and event.element2. Thanks for the help!

I am very close to what I am hoping to achieve, just one problem: 

 if((event.object1.id == "enemy" and event.element1 == 1) and (event.object2.id == "character")) then showPlayerHit() removeOnPlayerHit(event.object1, nil) print("back hit") elseif((event.object1.id == "character") and (event.element2 == 2 and event.object2.id == "enemy")) then showPlayerHit() removeOnPlayerHit(nil, event.object2) print("stinger hit") end

If the player hits the back, there is no collision, but if they hit the stinger there is.

EDIT: I got it working finally, I will test on a few more enemies and see how it works. This is my code:

 if((event.object1.id == "character") and (event.element2 == 1 and event.object2.id == "enemy")) then showPlayerHit() removeOnPlayerHit(event.object1, nil) print("back hit") elseif((event.object1.id == "character") and (event.element2 == 2 and event.object2.id == "enemy")) then showPlayerHit() removeOnPlayerHit(nil, event.object2) print("stinger hit") end

Great to hear! Post back if you need more help. :slight_smile: