Jump to content

[TOPIC: topicViewTemplate]
[GLOBAL: userSmallPhoto]
Photo

attempt to compare nil with number stack traceback
Started by 340919695 Aug 19 2019 11:31 AM

7 replies to this topic

Best Answer XeduR @Spyric , 20 August 2019 - 09:33 AM

You are seeing that error simply because currStar does not exist.

 

You get that aforementioned error every time you try to access something inside a table when that table itself is nil. You can avoid crashes like this by always first checking if said table (or variable) exists, e.g.

if currStar and ((currStar.x < -20) or (currStar.x > display.contentWidth + 20) or (currStar.y < -20) or (currStar.y > display.contentHeight + 20)) then

Now, the reason why this is happening probably has something to do with how you remove the objects in your onCollision function. Your gameLoop runs ever half a second, but while it is running, if one of those objects is removed while the loop is running, then the object won't exist and the game will crash.

[TOPIC CONTROLS]
[/TOPIC CONTROLS]
[modOptionsDropdown]
[/modOptionsDropdown]
[reputationFilter]
[TOPIC: post.html]
#1

340919695

[GLOBAL: userInfoPane.html]
340919695
  • Observer

  • 4 posts
  • Corona SDK

i just started learning corona/lua yesterday, so i'm not exactly sure how to fix this. thanks for any and all help.

 

i finished the chapter one tutorial (the balloon one) and wanted the player to be able to collect stars to earn points. here is my code. i'm sorry there's no tabs, i can't seem to paste from sublime text to here with spaces.

if anyone knows how to fix that let me know.


--balloon tap
 
-- images
local sky = display.newImageRect("myassets/skywatercolour.jpg", 360, 570)
sky.x = display.contentCenterX
sky.y = display.contentCenterY
sky.id = "sky"
 
local balloon = display.newImageRect("myassets/hotairballoon.png", 300, 200)
balloon.x = display.contentCenterX
balloon.y = display.contentHeight - 170
balloon.id = "balloon"
 
local platform = display.newImageRect("myassets/platform.png", 230, 40)
platform.x = display.contentCenterX
platform.y = display.contentHeight
platform.id = "platform"
 
local pushes = 0
local score = display.newText("score: "..tostring(pushes), display.contentWidth -80, -10, native.systemFont, 25)
 
 
-- physics
local physics = require("physics")
physics.start()
 
physics.addBody(platform, "static", {bounce = 0.5})
physics.addBody(balloon, "dynamic", {radius=76, bounce=0})
 
-- walls
topWall = display.newRect(display.contentCenterX, -50, display.contentWidth, 2)
leftWall = display.newRect(0, 0, 2, display.contentHeight*2)
bottomWall = display.newRect(0, display.contentHeight*2, display.contentWidth*2, 2)
rightWall = display.newRect(display.contentWidth, 0, 2, display.contentHeight*2)
topWall.id = "topWall"
leftWall.id = "leftWall"
bottomWall.id = "bottomWall"
rightWall.id = "rightWall"
physics.addBody(topWall, "static")
physics.addBody(leftWall, "static")
physics.addBody(bottomWall, "static")
physics.addBody(rightWall, "static")
 
-- functions
local function pushBalloon()
balloon:applyLinearImpulse(0, -1, balloon.x, balloon.y)
pushes = pushes + 1
score.text = "score: "..tostring(pushes)
end
 
local newStar
local stars = {}
local starAssets = {"myassets/star1.png", "myassets/star2.png", "myassets/star3.png"}
leftAndRight = {0, display.contentWidth}
local function spawnStar()
newStar = display.newImageRect(starAssets[math.random(#starAssets)], 20, 20)
table.insert(stars, newStar)
newStar.id = "star"..#stars
physics.addBody(newStar, "kinematic", {bounce = 0})
newStar.x = leftAndRight[math.random(#leftAndRight)]
newStar.y = math.random(20, display.contentHeight - 200)
if (newStar.x == 0) then
newStar:setLinearVelocity(math.random(display.contentWidth/10, display.contentWidth-15), math.random(0, display.contentHeight/4))
elseif (newStar.x == display.contentWidth) then
newStar:setLinearVelocity(math.random(-display.contentWidth-15, -display.contentWidth/10), math.random(-display.contentHeight/4, 0))
end
newStar:applyTorque(math.random(-6, 6))
end
 
local function onCollision(self, event)
if (event.phase == "began") then
local object = event.other.id 
if string.match(object, "star") then
pushes = pushes + 2
display.remove(event.other)
table.remove(stars, tonumber(string.sub(object, -1)))
elseif (object == "platform") then
pushes = 0
end
score.text = "score: "..tostring(pushes)
end
end
-- events
balloon.collision = onCollision
balloon:addEventListener("collision")
balloon:addEventListener("tap", pushBalloon)
 
 
-- game loop
 
local function gameLoop()
if (#stars < 10) then
spawnStar()
end
for i = #stars, 1, -1 do
local currStar = stars[i]
-- local xpos = tonumber(currStar.x)
-- local ypos = tonumber(currStar.y)
-- local width = tonumber(display.contentWidth)
-- local height = tonumber(display.contentHeight)
print(type(currStar.x))
print(type(currStar.y))
print(type(display.contentWidth))
print(type(display.contentHeight))
if (currStar.x < -20) or (currStar.x > display.contentWidth + 20) or (currStar.y < -20) or (currStar.y > display.contentHeight + 20) then
display.remove(currStar)
table.remove(stars, i) 
end
end
end
loopTimer = timer.performWithDelay(500, gameLoop, 0)

 
i get the error Attempt to compare nil with number stack traceback on line 106 or
 if (currStar.x < -20) or (currStar.x > display.contentWidth + 20) or (currStar.y < -20) or (currStar.y > display.contentHeight + 20) then
 
as you can see, i checked the type of all the variables and they're all numbers. i tried creating new variables hat are numbers and the same error occurred.
am i reading the error message wrong? is there a problem elsewhere? thank you for any help :)


[TOPIC: post.html]
#2

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 892 posts
  • Corona SDK

  Best Answer

You are seeing that error simply because currStar does not exist.

 

You get that aforementioned error every time you try to access something inside a table when that table itself is nil. You can avoid crashes like this by always first checking if said table (or variable) exists, e.g.

if currStar and ((currStar.x < -20) or (currStar.x > display.contentWidth + 20) or (currStar.y < -20) or (currStar.y > display.contentHeight + 20)) then

Now, the reason why this is happening probably has something to do with how you remove the objects in your onCollision function. Your gameLoop runs ever half a second, but while it is running, if one of those objects is removed while the loop is running, then the object won't exist and the game will crash.



[TOPIC: post.html]
#3

340919695

[GLOBAL: userInfoPane.html]
340919695
  • Observer

  • 4 posts
  • Corona SDK

Oh, I see, thanks. Is there any work around for this? Would I have to check if the star exists on every step?



[TOPIC: post.html]
#4

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 892 posts
  • Corona SDK

I'm not sure what you mean. I already provided the code to prevent those crashes, so I am not sure what you are referring to.

By the way, out of curiosity. Did you personally choose the username "340919695" or is it some bug or something entirely different?



[TOPIC: post.html]
#5

340919695

[GLOBAL: userInfoPane.html]
340919695
  • Observer

  • 4 posts
  • Corona SDK

Oh.. when I put it in, the crashes still occur with the same error.

 

I put in my school e-mail when I signed up so it just automatically chose that as my username. Definitely makes me look like a bot. I should probably change it.



[TOPIC: post.html]
#6

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 892 posts
  • Corona SDK

Did you copy it exactly as I put it and is it exactly that line that is crashing?

 

It first checks if currStar exists and is not false or nil, and if this condition is met, then it proceeds. The only way that line of code would crash is if currStar somehow existed and wasn't false, nil OR a table. However, since you don't assign any other values than tables to it, I don't see how it could crash.



[TOPIC: post.html]
#7

340919695

[GLOBAL: userInfoPane.html]
340919695
  • Observer

  • 4 posts
  • Corona SDK

Oh, I fixed it! currStar remained a table but currStar.x and currStar.y were nil.

thank your so much for your help!!

final if statement was

 if currStar and currStar.x and currStar.y and ((currStar.x < -20) or (currStar.x > display.contentWidth + 20) or (currStar.y < -20) or (currStar.y > display.contentHeight + 20)) then



[TOPIC: post.html]
#8

XeduR @Spyric

[GLOBAL: userInfoPane.html]
XeduR @Spyric
  • Contributor

  • 892 posts
  • Corona SDK

While it is good that you got that sorted, just keep this in mind:

 

What you are doing now is basically just sweeping the problem under a rug. You should still go ahead and work on preventing the problem from ever occurring in the first place.


  • 340919695 likes this


[topic_controls]
[/topic_controls]