In this program when you tap on the object moon the function changeScene() should change scene from end.lua to start.lua (in order to restart the game).
But in the start.lua the moon remains on the display.
Therefore in changeScene() I add display.remove( moon ) but it does not work.
I tried moon:removeSelf() and sceneGroup:remove(3) too.
Furthermore I do not know why moon:removeSelf() gives this error:
ERROR: Runtime error
end.lua:13: attempt to index global 'moon' (a nil value)
stack traceback:
end.lua:13: in function '?'
?: in function <?:190>
What am I doing wrong?
end.lua
local composer = require( "composer" )
local scene = composer.newScene()
-- create()
function scene:create( event )
local sceneGroup = self.view
local function changeScene()
--moon:removeSelf()
--sceneGroup:remove(3)
display.remove( moon )
--moon = nil
composer.removeScene("end")
composer.gotoScene( "start", {effect = "slideUp", time = 500} )
end
local text = display.newText(correctAnswers .. "/10 correct ", display.contentCenterX, 280 ,native.systemFont, 50)
text.y = display.contentCenterY-100
sceneGroup:insert(text)
local text2 = display.newText("Press the moon to RESTART ", display.contentCenterX, 280 ,native.systemFont, 20)
text2.x = display.contentCenterX
text2.y = display.contentCenterY+200
transition.blink( text2, { time=2500 } )
sceneGroup:insert(text2)
local floor = display.newImageRect( "floor.png", 300, 50 )
floor.x = display.contentCenterX
floor.y = display.viewableContentHeight+100
local moon = display.newImageRect( "balloon.png", 112, 112 )
moon.x = math.random( 40,display.contentWidth-40 )
moon.y = 50
moon.alpha = 0.8
local physics = require( "physics" )
physics.start()
physics.addBody( floor, "static" )
physics.addBody( moon, "dynamic", { radius=50, bounce=0.5 } )
moon:addEventListener( "tap", changeScene )
end
It is fine to use local variables inside of functions. But variables can only be used when they are in scope.
Of course, variables that are in the parameter list of a function definition are in scope inside of the function. But variables which are not in the parameter list may also be used, provided that they are in scope at the time of function definition. In OP code, the changeScene function has no parameters, so any variables used in the function must be in scope at the time of function definition. The variable moon is a local variable, which is in scope in the block in which it is declared, after the point of definition. So, moon is not in scope when changeScene is defined. One way to fix this problem is to move the definition of moon to a point before the definition of changeScene:
local moon = display.newImageRect("balloon.png", 112, 112)
moon.x = math.random(40,display.contentWidth - 40)
moon.y = 50
moon.alpha = 0.8
local function changeScene ()
display.remove(moon)
composer.removeScene("end")
composer.gotoScene("start", {effect = "slideUp", time = 500})
end
in Lua, when we work with a function, whenever we are going to call a variable inside it, it must be local, but when we are inside a function calling a variable outside it, it must be global.
Remove the local in the moon variable declaration and see if that solves the problem
When using functions its fine to use a defined variable inside but you need to make sure 1 its local and 2 if its outside its global
try taking the local out of the defined moon variable and you might be able to fix it
:D
Related
i am making a tower defense game but it keeps saying argument 1 missing or nil
when i try to spawn the tower
this is a module script
(error at line 11)
local PhysicsServive = game:GetService("PhysicsService")
local ServerStorage = game:GetService("ServerStorage")
local ReplicatedStorage = game:GetService("ReplicatedStorage")
local PhysicsService = game:GetService("PhysicsService")
local events = ReplicatedStorage:WaitForChild("Events")
local Tower = {}
local SpawnTowerEvent = events:WaitForChild("SpawnTower")
function Tower.Spawn(player, Name, CFrame)
local towerExists = ReplicatedStorage.Towers:FindFirstChild(Name)
if towerExists then
local newTower = towerExists:Clone()
newTower.HumanoidRootPart.CFrame = CFrame
newTower.Parent = workspace.Towers
newTower.HumanoidRootPart:SetNetworkOwner(nil)
for i, object in ipairs(newTower:GetDescendants()) do
if object:IsA("BasePart") then
PhysicsService:SetPartCollisionGroup(object, "Tower")
object.Material = Enum.Material.ForceField
end
end
else
warn("Missing:", Name)
end
end
SpawnTowerEvent.OnServerEvent:Connect(Tower.Spawn())
return Tower
SpawnTowerEvent.OnServerEvent:Connect(Tower.Spawn())
Connect expects a function value, not a function call (unless that function call resolves to a function value). Remove the call operator ().
SpawnTowerEvent.OnServerEvent:Connect(Tower.Spawn)
You call Tower.Spawn without any arguments. Therefor you call FindFirstChild(nil) which causes the observed error.
Also it does not return a function value.
I am creating several display objects and using transition.to to move them horizontally. Everything works except the objects x positions get out of phase/position. The objects should have the same X positions forever but the longer it runs, the further out of position they get.
local function onLoopXListener( )
transition.to( platform, { time=2000, x=0, transition=easing.inOutSine, delay=0} );
transition.to( platform, { time=2000, x=320, transition=easing.inOutSine, delay=2000, onComplete=onLoopXListener} );
end
local function StartTransition( )
transition.to( platform, { time=2000, x=0, transition=easing.inOutSine, delay=1000 } );
transition.to( platform, { time=2000, x=320, transition=easing.inOutSine, delay=3000, onComplete=onLoopXListener} );
end
for i = 1, 4, 1 do
--create a new platform displayobject
--seperate it vertically
StartTransition( )
end
Forgive me if my code is ugly (I've removed irrelevant code - it all works except the positions) - it's the transition concept that I'm asking about here.
I have used "enterFrame" and it works fine. Here is my implementation:
local _lastTime = 0
local function OnEnterFrame( event )
deltaTime = event.time - _lastTime
_lastTime = event.time
MoveMyPlatformOnEnterFrame(deltaTime)
end
Runtime:addEventListener( "enterFrame", OnEnterFrame )
This is how I implemented the sin() transition:
Remember this needs to go above the function call.
local _loopTime = someValue
local _xRadians =0
local _amplitude = someOtherValue
local _platform --this is the Display Object I want to move
function MoveMyPlatformOnEnterFrame( deltaTime )
delta = deltaTime / _loopTime * (44/7)
_xRadians = _xRadians + delta
_xRadians = math.fmod( _xRadians, (44/7) )
_platform.x = _position.x + math.sin( _xRadians ) * _amplitude
end
I'm a new programmer with no much experience; as a good noob it's very probable that the next code lines you will see may show a wide number of errors or imprecisions thus I'm excusing myself ahead of time.
So, the situation is the following:
Lately I'm interfacing with a new programming language (new for me obviously) that is LUA (using corona sdk). I approached the language writing simple codes.
Now I'm trying to execute a program that has simply to display two rectangles affected by the gravity. When I try to emulate the applicarion on my PC with CORONA it works without any kind of problem; after having built it for android OS, having installed it on my phone and having run it the result is an error message that is the following:
This is the error message:
"main.lua.35: ERROR: table expected. If this is a function call you might have used '.' instead of ':' "
This is the code:
local physics = require("physics")
physics.start()
local _W = display.contentWidth
local _H = display.contentHeight
local platform = display.newRect(
--x =
_W/2,
--y =
_H/2,
--width =
100,
--height =
100
)
platform.surfaceType = "rectangle"
local myImage = display.newImage("icon.png",_W/2,50)
local iconCollision = {
friction = 0.0, --attrito
bounce = 0.0, --rimbalzo (forse)
isSensor = true --collisione con altri oggetti
}
physics.addBody(platform,"static")
physics.addBody(myImage,"dynamic",iconCollision) --this is line 35
platform.collision = onCollision
local function onGyroscopeDataReceived( event )
local deltaRadians = event.zRotation * event.deltaTime
local deltaDegrees = deltaRadians * (180/math.pi)
end
local function dragImage(event)
local t=event.target
print(event.phase)
if(event.phase == "moved") then
t.x = event.x
t.y = event.y
end
end
local function onCollision( event )
if ( event.phase == "began" ) then
print("toccato")
end
end
if system.hasEventSource( "gyroscope" ) then
Runtime:addEventListener( "gyroscope", onGyroscopeDataReceived )
end
Runtime:addEventListener("collision",onCollision)
myImage:addEventListener("touch",dragImage)
I will be very grateful with those who will try to help me.
I think maybe event.zRotation is null. On iOS, you can use the appropriate UIRequiredDeviceCapabilities. In building.settings add this UIRequiredDeviceCapabilities = { ["gyroscope"]=true }. On Android set the usesFeatures = { { name="android.hardware.sensor.gyroscope", required=true } }.
Look for the name of the image on the disk , "icon.png", uppercase and lowercase matters, on Android device it could lead to errors, not showed in simulators.
If it doesn't load myImage:addEventListener would display an errore, maybe the one you see.
Also try to exclude pieces of code and then run the program on device back. I found difference with simulator that way.
I just trying to add eventListener to a object, which should disappear when I tap on it. But I get error mentioned in the title. Here is my whole code at this point :
-- housekeeping stuff
display.setStatusBar(display.HiddenStatusBar)
local centerX = display.contentCenterX
local centerY = display.contentCenterY
-- set up forward references
local spawnEnemy
-- preload audio
-- create play screens
local function createPlayScreen()
local bg = display.newImage("background.png")
bg.y = 130
bg.x = 100
bg.alpha = 0
local planet = display.newImage("planet.png")
planet.x = centerX
planet.y = display.contentHeight +60
planet.alpha = 0
transition.to( bg, { time = 2000, alpha = 1, y = centerY, x = centerX } )
local function showTitle()
local gametitle = display.newImage("gametitle.png")
gametitle.alpha = 0
gametitle:scale (4, 4)
transition.to( gametitle, { time = 500, alpha = 1, xScale = 1, yScale = 1 })
spawnEnemy()
end
transition.to( planet, { time = 2000, alpha = 1, y = centerY, onComplete = showTitle } )
end
-- game functions
local function shipSmash(event)
local obj = event.target
display.remove( obj )
end
local function spawnEnemy()
local enemy = display.newImage("beetleship.png")
enemy.x = math.random(20, display.contentWidth - 20)
enemy.y = math.random(20, display.contentHeight - 20)
enemy:addEventListener ( "tap", shipSmash )
end
local function startGame()
end
local function planetDamage()
end
local function hitPlanet(obj)
end
createPlayScreen()
startGame()
And here is how error window looks like :
I'm kinda new in this area(LUA programming) so sorry for maybe dumb syntax error or something, but what I saw is that this error shows up after I write this line of code: enemy:addEventListener ( "tap", shipSmash )
Change local function spawnEnemy() to function spawnEnemy() as this variable was already declared earlier. Yes, this is typical Lua pitfall for beginners.
You've declared spawnEnemy as a local variable twice. That's allowed (the second one hides the first where ever the second one is in scope) but that's not what you wanted.
You have correctly declared a local variable and captured it in showTitle. To set that very same variable later, use an assignment statement without prefixing it with local. You can assign it a function definition using the "anonymous" function syntax:
spawnEnemy = function()
...
end
Actually, in Lua, all functions are anonymous since they are just values. But, for debugging, it is helpful to have a name associated with a function. In stack traces, the name of the variable used to call the function is used, where possible.
The main creates a simple 2d array. Now i want to create a addeventlistener for each object in the table. I presume i do this in the class? Although i have created a taps function and then defined addeventlistener but i ma getting errors.
--main.lua--
grid={}
for i =1,5 do
grid[i]= {}
for j =1,5 do
grid[i][j]=diceClass.new( ((i+2)/10),((j+2)/10))
end
end
--dice class--
local dice = {}
local dice_mt = { __index = dice } -- metatable
function dice.new( posx, posy) -- constructor
local a=math.random(1,6)
local b= true
local newdice = display.newText(a, display.contentWidth*posx,
display.contentHeight*posy, nil, 60)
--newdice:addEventListener("tap", taps(event))
return setmetatable( newdice, dice_mt )
end
function dice:taps(event)
self.b = false
print("works")
end
function dice:addEventListener("tap", taps(event))
This stumped me till today. The main problem is that you're making newdice a Corona display.newText object and then reassigning it to be a dice object. All the Corona objects act like ordinary tables, but they're actually special objects. So you have two options:
A. Don't use classes and OOP. As your code is now, there's no reason to have dice be a class. This is the option I'd go with unless you have some compelling reason to make dice a class. Here's how you would implement this option
--dice not a class--
local dice = {}
local function taps(event)
event.target.b = false
print("works")
end
function dice.new( posx, posy) -- constructor
local a=math.random(1,6)
--local b= true
local newdice = {}
newdice = display.newText(a, display.contentWidth*posx,
display.contentHeight*posy, nil, 60)
newdice:addEventListener("tap", taps)
newdice.b = true
return newdice
end
or B. Use a "has a" relationship instead of an "is a" relationship for the display object. Since you can't make them both a dice object and a display object, your dice object could contain a display object. Here's how that would look.
--dice class--
local dice = {}
local dice_mt = { __index = dice } -- metatable
local function taps(event)
event.target.b = false
print("works")
end
function dice.new( posx, posy) -- constructor
local a=math.random(1,6)
--local b= true
local newdice = {}
newdice.image = display.newText(a, display.contentWidth*posx,
display.contentHeight*posy, nil, 60)
newdice.image:addEventListener("tap", taps)
newdice.b = true
return setmetatable( newdice, dice_mt )
end
There were some other problems as well. In your taps function event handler you have to use event.target.b instead of self.b. Also, in dice.new b is a local variable so it's not a member of your dice class.
Remove the last line.
The addEventListener function should be called like this
newdice:addEventListener("tap", taps)