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

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:

Thanks, if you get the chance, could you look at my other topic: https://forums.coronalabs.com/topic/65886-attempt-to-index-upvalue-score-a-number-value/

After many fruitless efforts, the problem of the character losing two lives is still present. At this point, I am not sure if anything else can be done. Sometimes, 2 lives are lost and the character hits the enemy at a flat surface.

The default Corona physics library works, but it looks like the character is colliding in mid-air.

I apologize that I am being repetitive.

Hi @sdktester15,

I’m not sure which question is related to what issue, or what to help answer… can you clarify please?

Brent

Yes, my question now is will I have to construct the physics bodies for my enemies with the Corona physics library via coordinates? And, will this possibly solve the issue of losing 2 or 3 lives that was caused when I was using PhysicsEditor?

If the answer is yes to the first question, please view my other question:

https://forums.coronalabs.com/topic/66283-how-to-use-the-auto-trace-for-corona-physics-library/

Hi again,

What is most likely happening is that, with multi-element physics bodies, all “fixtures” (elements) in the body will trigger a collison detection with another object. This is by design, since we wouldn’t want to disregard that happening in case the developer wants to handle those collisions separately.

Fortunately, there are some simple workarounds. Refresh my memory though… I thought we solved this at some point before now? Or am I mistaken? I can provide you some help on this issue if we haven’t already discussed it…

Take care,

Brent

I also thought this was solved, however I had discovered that the error was there the whole time, however, even before I was using multi-element physics bodies the error was still occurring. Also, I look forward to discovering what these workarounds are. 

Sure thing,

So basically, because there are multi-element bodies colliding, you won’t be able to prevent multiple collision events from happening… that’s just how it works. But what you can do is pull a little trick to make sure the player doesn’t get penalized 2 lives.

May I first ask what happens when your player dies? Do you animate the player sprite in some way to show it? Does the player “fall of the screen” or do some other motion upon death? I ask this because, depending on what you do when the player dies determines the solution I suggest. :slight_smile:

Brent

When the player loses a life, a heart is deducted form a counter that keeps track of their lives, also, all enemies on the screen are removed.

When the player dies, the game takes them back to the main menu.

Yes, but do you do anything else like run a “death” animation or something? I imagine the game doesn’t just instantly snap back to the menu instantly…

It actually does, I haven’t decided to do anything with that yet…

What that error more than likely is telling you, is that the object at that table location doesn’t exist. You might want to try printing out the value of “livesCount” before you try to alpha out that object, maybe even iterating through the “lives” table and identify which one you want to alpha/remove.

How would I iterate through the table?

Hi alex. You can try doing this
For i = 1,#lives do
Lives[i].alpha = 0
End
Hope that helps.
Because if you enter livesCount in lives table like this : lives[livesCount], then it will just enter the value of livesCount in lives table…for example, if your value of livesCount is 5 and you perform lives[livesCount], then it indirectly means like this: lives[5]. And therefore it the code will be somewhat like this:
Lives[5].alpha = 0
which means you are setting 5th lives alpha to zero
If you want to set each of the lives to zero alpha then do this:
For i=1, #lives do
Lives[i].alpha = 0
End
Hope that seems to work well and if there is something i went wrong with in my explanation, i am sorry :slight_smile:

EDIT:

Above code was for reducing alpha of each life.

But i think you want to reduce alpha of life.

So this error occurs because livesCount variable is nil i.e it’s value is zero…an you haven’t created lives[0], so therefore getting this error.

you could avoid this :

local function playerHit() character:setLinearVelocity(0, nil) timer.cancel(firstTimer) timer.cancel(secondTimer) timer.cancel(moveEnemiesTimer) -- you can try nilling out timers to improve performance firstTimer = nil secondTimer = nil moveEnemiesTimer = nil -- this will check if your livesCount is greater than zero or else if it is zero, it will give you error if livesCount \>= 1 then lives[livesCount].alpha = 0 livesCount = livesCount - 1 composer.gotoScene("level1-Try-Again") elseif livesCount \< 1 then gameOver() end end

This is working well, but occasionally the player loses two lives instead of one, could this be in the collision function?