Bad Argument #1 Error

After executing this piece of code, it gives me an error: bad argument #1 to ‘rad’ (number expected, got nil).

Any idea how can I fix this?

With Respect,

Rui

local function firebullet(event)
        local bullet = display.newCircle( planet.x, planet.y, 2 )
        physics.addBody( bullet, { density=3.0, friction=0.5, bounce=0.05 } )
        bullet.isBullet = true
        local function rotateVector(x, y, angle)
        local radAngle = (math.rad(angle))
        local sinAngle = (math.sin(radAngle))
        local cosAngle = (math.cos(radAngle))
    
        local rotatedX = cosAngle*x - sinAngle*y
        local rotatedY = sinAngle*x + cosAngle*y
    
        return rotatedX, rotatedY
    end

Assuming it’s not a global (which it probably shouldn’t be), you’re not defining ‘angle’ that you’re passing into math.rad(angle). Therefore it’s nil.

Also, if that’s the entirety of your function you have other issues with your syntax in the line above that. 

Code formatting is critical to understand what’s going on. For instance, here is what your function looks like when really formatted:

local function firebullet(event) local bullet = display.newCircle( planet.x, planet.y, 2 ) physics.addBody( bullet, { density=3.0, friction=0.5, bounce=0.05 } ) bullet.isBullet = true local function rotateVector(x, y, angle) local radAngle = (math.rad(angle)) local sinAngle = (math.sin(radAngle)) local cosAngle = (math.cos(radAngle)) local rotatedX = cosAngle\*x - sinAngle\*y local rotatedY = sinAngle\*x + cosAngle\*y return rotatedX, rotatedY end -- missing an end here.

It looks like you’re trying to create a function “rotateVector” and you’re passing a value angle to it. However that value is nil. But we never see the call to rotateVector. Since its missing an end, perhaps we are not seeing the rest of the firebullet function.

Indenting your code is really important to help understand what’s going on. As you have it formatted, the rotateVector function declaration appears to be a peer to the lines below it, instead of the lines below it belonging to rotateVector.

Rob

local function firebullet(event)
        local bullet = display.newCircle( planet.x, planet.y, 2 )
        physics.addBody( bullet, { density=3.0, friction=0.5, bounce=0.05 } )
        bullet.isBullet = true
        local function rotateVector(x, y, angle)
        local radAngle = (math.rad(angle))
        local sinAngle = (math.sin(radAngle))
        local cosAngle = (math.cos(radAngle))
    
        local rotatedX = cosAngle*x - sinAngle*y
        local rotatedY = sinAngle*x + cosAngle*y
    
        return rotatedX, rotatedY
    end
        local rotatedOffsetX, rotatedOffsetY = rotateVector(offsetX, offsetY, angle)
        bullet:applyForce( rotatedOffsetX, rotatedOffsetY, bullet.x, bullet.y )
    end
    bg:addEventListener ( “tap”, firebullet)

So, I set the angle to 0 and now the error is “attempt to perform arithmetic on local ‘x’ (a nil value)” in this line " local rotatedX = cosAngle*x - sinAngle*y".

I am trying to shoot a bullet from a planet that is always rotating automaticly. But I am not really into it and I have been with very dificulties in doing so. The planet have a cannon and I want to shoot the bullet like it was shot by the cannon. I thought this function will work but I can’t even try it because it gives me always some error.

I still don’t see where you’re providing the angle here:

local rotatedOffsetX, rotatedOffsetY = rotateVector(offsetX, offsetY, angle)

You don’t have angle defined, so it’s nil. Also where are the values offsetX and offsetY coming from? They are also nil at the moment.

Next time, please click the blue <> button in the bar with Bold and Italics and paste your code in there.

The angle is defined a little above. But can I ask you if you have any idea how I can do the thing that I explained above? I am trying use this code but if you know any other way to do it would be very helpfull.

Thx for all btw.

First it would be helpful to see more code. You talk about setting the angle above and I still don’t know where offsetX and offsetY are being set. If any of these are nil, you’re going to get an error.

If you solve those and are getting other errors, you need to share those as well. We can’t magically see your code.

We have a saying: Help us help you.

Rob

display.setStatusBar( display.HiddenStatusBar ) local physics = require "physics" physics.start() physics.setGravity( 0, 0 ) -- Variables local centerX = display.contentCenterX local centerY = display.contentCenterY local xmin = display.screenOriginX - 50 local xmax = display.contentWidth + 50 local ymin = display.screenOriginY - 50 local ymax = display.contentHeight + 50 local spawnIncreaseTimer local spawnNumber=0 local speedBump = 0 local earthRotation local gametimer local nSeconds = 0 local nMins = 0 local nHours = 0 local numSec = 0 local nSecs = 0 local timervalue = 0 local spawnTimer local firebullet local bg = display.newImage("images/starbg.png") bg.x = centerX bg.y = centerY local logo = display.newImage("images/Logo.png") logo.x = centerX logo.y = centerY local begin = display.newImage("images/start.png") begin.x = centerX + 50 begin.y = centerY + 45 -- Functions -- Esta função faz o texto piscar function blink() if(begin.alpha \< 1) then transition.to( begin, {time=490, alpha=1}) else transition.to( begin, {time=490, alpha=0.1}) end end txt\_blink = timer.performWithDelay(500, blink, 0) -- Esta função aumenta, de 10 em 10 segundos, o numero de asteroides que aparecem por cada 2 segundos local function spawnIncrease() spawnNumber=spawnNumber+1 spawnIncreaseTimer = timer.performWithDelay( 15000, spawnIncrease) end -- Esta função faz com que os asteroides desapareçam se colidirem com a terra local function startcolision() function colision(event) timer.performWithDelay(1, function() display.remove(asteroids) end, 1) return true end asteroids:addEventListener("collision",colision) return asteroids end function colision(obj) display.remove( obj ) end -- Esta função faz com que os asteroides apareçam local function spawn() for i=1,spawnNumber do local allAsteroids = {"images/enemy1.1.png" , "images/enemy2.1.png"} asteroids = display.newImage(allAsteroids[math.random(#allAsteroids)]) asteroids.x = math.random(xmin, xmax) asteroids.y = math.random(ymin, ymax) if (asteroids.x \> display.screenOriginX and asteroids.x \< display.contentWidth + 1 and asteroids.y \> display.screenOriginY and asteroids.y \< display.contentHeight + 1) then display.remove(asteroids) else transition.to( asteroids, { time=math.random(3000-speedBump , 5000-speedBump), y = centerY, x = centerX , rotation = math.random(50 , 180), onComplete = colision }) speedBump = speedBump + 15 end end spawnTimer = timer.performWithDelay( 2000, spawn) end -- Esta função adiciona o score ao display local function startGame() scoreText = display.newText( "Score", 0, 0, "Helvetica", 22 ) scoreText2 = display.newText("0", 0, 0, "Helvetica", 22) scoreText.x = display.screenOriginX + 50 scoreText.y = display.screenOriginY + 20 scoreText2.x = display.screenOriginX + 50 scoreText2.y = display.screenOriginY + 45 spawnIncrease() spawn() end -- Esta função adiciona o timer ao display local function timerGame() timerTxt = display.newText("Time", 0, 0, "Helvetica", 22) timerTxt2 = display.newText("00:00:00", 0, 0, "Helvetica", 22) timerTxt.x = display.contentWidth - 15 timerTxt.y = display.screenOriginY + 20 timerTxt2.x = display.contentWidth - 15 timerTxt2.y = display.screenOriginY + 45 end -- Esta função dá inicio ao timer local function timeCount() nSeconds = timervalue if nSeconds == 0 then timerTxt2.text = "00:00:00"; else nHours = string.format("%02.f", math.floor(nSeconds/3600)); nMins = string.format("%02.f", math.floor(nSeconds/60 - (nHours\*60))); nSecs = string.format("%02.f", math.floor(nSeconds - nHours\*3600 - nMins \*60)); timerTxt2.text = nHours..":"..nMins..":"..nSecs end timervalue = timervalue + 1 gametimer = timer.performWithDelay( 1000, timeCount) end -- Esta função faz parar o aumento de asteroides que aparecem local function stopSpawnIncrease() timer.cancel( spawnIncreaseTimer ) end -- Esta função faz parar o aumento de rotação da terra local function stopRotationIncrease() timer.cancel( earthRotation ) end -- Esta função dá inicio ao jogo local function go(event) display.remove(logo) display.remove(begin) local planet = display.newImage("images/earth.png") planet.x = centerX planet.y = centerY -- Esta função faz a terra rodar e aumento a sua rotação por cada 10 segundos local function animate() planet.rotation = planet.rotation + 2 earthRotation = timer.performWithDelay( 10000, animate) end Runtime:addEventListener("enterFrame",animate); planet:scale(4, 4) transition.to( planet, { time = 200, xScale = 1, yScale = 1, onComplete = animate} ) startGame() timerGame() timeCount() local function firebullet(event) local bullet = display.newCircle( planet.x, planet.y, 2 ) physics.addBody( bullet, { density=3.0, friction=0.5, bounce=0.05 } ) end bg:addEventListener ( "tap", firebullet) end begin:addEventListener ( "tap", go)

So, this is my full code, everytime that I tap the screen a bullet spawns. Now, my problem is actually to shoot the bullet in the direction to where the cannon (in the earth) is pointing when I tap the screen. Any idea on how I can do that?

Where is all the code we’ve been discussing?

I had to delete it because it didn’t do what i wanted. It was something a bit diferent.

But if you want someone to help you fix it, we need to see what’s broken.

I didn’t delete it because it had errors to be fixed, well it had until I fix them, but after fixed I realized that the code was not correct to what i wanted. The right code was not that.

Assuming it’s not a global (which it probably shouldn’t be), you’re not defining ‘angle’ that you’re passing into math.rad(angle). Therefore it’s nil.

Also, if that’s the entirety of your function you have other issues with your syntax in the line above that. 

Code formatting is critical to understand what’s going on. For instance, here is what your function looks like when really formatted:

local function firebullet(event) local bullet = display.newCircle( planet.x, planet.y, 2 ) physics.addBody( bullet, { density=3.0, friction=0.5, bounce=0.05 } ) bullet.isBullet = true local function rotateVector(x, y, angle) local radAngle = (math.rad(angle)) local sinAngle = (math.sin(radAngle)) local cosAngle = (math.cos(radAngle)) local rotatedX = cosAngle\*x - sinAngle\*y local rotatedY = sinAngle\*x + cosAngle\*y return rotatedX, rotatedY end -- missing an end here.

It looks like you’re trying to create a function “rotateVector” and you’re passing a value angle to it. However that value is nil. But we never see the call to rotateVector. Since its missing an end, perhaps we are not seeing the rest of the firebullet function.

Indenting your code is really important to help understand what’s going on. As you have it formatted, the rotateVector function declaration appears to be a peer to the lines below it, instead of the lines below it belonging to rotateVector.

Rob

local function firebullet(event)
        local bullet = display.newCircle( planet.x, planet.y, 2 )
        physics.addBody( bullet, { density=3.0, friction=0.5, bounce=0.05 } )
        bullet.isBullet = true
        local function rotateVector(x, y, angle)
        local radAngle = (math.rad(angle))
        local sinAngle = (math.sin(radAngle))
        local cosAngle = (math.cos(radAngle))
    
        local rotatedX = cosAngle*x - sinAngle*y
        local rotatedY = sinAngle*x + cosAngle*y
    
        return rotatedX, rotatedY
    end
        local rotatedOffsetX, rotatedOffsetY = rotateVector(offsetX, offsetY, angle)
        bullet:applyForce( rotatedOffsetX, rotatedOffsetY, bullet.x, bullet.y )
    end
    bg:addEventListener ( “tap”, firebullet)

So, I set the angle to 0 and now the error is “attempt to perform arithmetic on local ‘x’ (a nil value)” in this line " local rotatedX = cosAngle*x - sinAngle*y".

I am trying to shoot a bullet from a planet that is always rotating automaticly. But I am not really into it and I have been with very dificulties in doing so. The planet have a cannon and I want to shoot the bullet like it was shot by the cannon. I thought this function will work but I can’t even try it because it gives me always some error.

I still don’t see where you’re providing the angle here:

local rotatedOffsetX, rotatedOffsetY = rotateVector(offsetX, offsetY, angle)

You don’t have angle defined, so it’s nil. Also where are the values offsetX and offsetY coming from? They are also nil at the moment.

Next time, please click the blue <> button in the bar with Bold and Italics and paste your code in there.

The angle is defined a little above. But can I ask you if you have any idea how I can do the thing that I explained above? I am trying use this code but if you know any other way to do it would be very helpfull.

Thx for all btw.

First it would be helpful to see more code. You talk about setting the angle above and I still don’t know where offsetX and offsetY are being set. If any of these are nil, you’re going to get an error.

If you solve those and are getting other errors, you need to share those as well. We can’t magically see your code.

We have a saying: Help us help you.

Rob

display.setStatusBar( display.HiddenStatusBar ) local physics = require "physics" physics.start() physics.setGravity( 0, 0 ) -- Variables local centerX = display.contentCenterX local centerY = display.contentCenterY local xmin = display.screenOriginX - 50 local xmax = display.contentWidth + 50 local ymin = display.screenOriginY - 50 local ymax = display.contentHeight + 50 local spawnIncreaseTimer local spawnNumber=0 local speedBump = 0 local earthRotation local gametimer local nSeconds = 0 local nMins = 0 local nHours = 0 local numSec = 0 local nSecs = 0 local timervalue = 0 local spawnTimer local firebullet local bg = display.newImage("images/starbg.png") bg.x = centerX bg.y = centerY local logo = display.newImage("images/Logo.png") logo.x = centerX logo.y = centerY local begin = display.newImage("images/start.png") begin.x = centerX + 50 begin.y = centerY + 45 -- Functions -- Esta função faz o texto piscar function blink() if(begin.alpha \< 1) then transition.to( begin, {time=490, alpha=1}) else transition.to( begin, {time=490, alpha=0.1}) end end txt\_blink = timer.performWithDelay(500, blink, 0) -- Esta função aumenta, de 10 em 10 segundos, o numero de asteroides que aparecem por cada 2 segundos local function spawnIncrease() spawnNumber=spawnNumber+1 spawnIncreaseTimer = timer.performWithDelay( 15000, spawnIncrease) end -- Esta função faz com que os asteroides desapareçam se colidirem com a terra local function startcolision() function colision(event) timer.performWithDelay(1, function() display.remove(asteroids) end, 1) return true end asteroids:addEventListener("collision",colision) return asteroids end function colision(obj) display.remove( obj ) end -- Esta função faz com que os asteroides apareçam local function spawn() for i=1,spawnNumber do local allAsteroids = {"images/enemy1.1.png" , "images/enemy2.1.png"} asteroids = display.newImage(allAsteroids[math.random(#allAsteroids)]) asteroids.x = math.random(xmin, xmax) asteroids.y = math.random(ymin, ymax) if (asteroids.x \> display.screenOriginX and asteroids.x \< display.contentWidth + 1 and asteroids.y \> display.screenOriginY and asteroids.y \< display.contentHeight + 1) then display.remove(asteroids) else transition.to( asteroids, { time=math.random(3000-speedBump , 5000-speedBump), y = centerY, x = centerX , rotation = math.random(50 , 180), onComplete = colision }) speedBump = speedBump + 15 end end spawnTimer = timer.performWithDelay( 2000, spawn) end -- Esta função adiciona o score ao display local function startGame() scoreText = display.newText( "Score", 0, 0, "Helvetica", 22 ) scoreText2 = display.newText("0", 0, 0, "Helvetica", 22) scoreText.x = display.screenOriginX + 50 scoreText.y = display.screenOriginY + 20 scoreText2.x = display.screenOriginX + 50 scoreText2.y = display.screenOriginY + 45 spawnIncrease() spawn() end -- Esta função adiciona o timer ao display local function timerGame() timerTxt = display.newText("Time", 0, 0, "Helvetica", 22) timerTxt2 = display.newText("00:00:00", 0, 0, "Helvetica", 22) timerTxt.x = display.contentWidth - 15 timerTxt.y = display.screenOriginY + 20 timerTxt2.x = display.contentWidth - 15 timerTxt2.y = display.screenOriginY + 45 end -- Esta função dá inicio ao timer local function timeCount() nSeconds = timervalue if nSeconds == 0 then timerTxt2.text = "00:00:00"; else nHours = string.format("%02.f", math.floor(nSeconds/3600)); nMins = string.format("%02.f", math.floor(nSeconds/60 - (nHours\*60))); nSecs = string.format("%02.f", math.floor(nSeconds - nHours\*3600 - nMins \*60)); timerTxt2.text = nHours..":"..nMins..":"..nSecs end timervalue = timervalue + 1 gametimer = timer.performWithDelay( 1000, timeCount) end -- Esta função faz parar o aumento de asteroides que aparecem local function stopSpawnIncrease() timer.cancel( spawnIncreaseTimer ) end -- Esta função faz parar o aumento de rotação da terra local function stopRotationIncrease() timer.cancel( earthRotation ) end -- Esta função dá inicio ao jogo local function go(event) display.remove(logo) display.remove(begin) local planet = display.newImage("images/earth.png") planet.x = centerX planet.y = centerY -- Esta função faz a terra rodar e aumento a sua rotação por cada 10 segundos local function animate() planet.rotation = planet.rotation + 2 earthRotation = timer.performWithDelay( 10000, animate) end Runtime:addEventListener("enterFrame",animate); planet:scale(4, 4) transition.to( planet, { time = 200, xScale = 1, yScale = 1, onComplete = animate} ) startGame() timerGame() timeCount() local function firebullet(event) local bullet = display.newCircle( planet.x, planet.y, 2 ) physics.addBody( bullet, { density=3.0, friction=0.5, bounce=0.05 } ) end bg:addEventListener ( "tap", firebullet) end begin:addEventListener ( "tap", go)

So, this is my full code, everytime that I tap the screen a bullet spawns. Now, my problem is actually to shoot the bullet in the direction to where the cannon (in the earth) is pointing when I tap the screen. Any idea on how I can do that?

Where is all the code we’ve been discussing?