Lua how to access global variable of another file - lua

I am trying to make a bird class in Bird.lua and require it in main.lua
However, Bird.lua makes use of a global variables VIRTUAL_WIDTH and VIRTUAL_HEIGHT defined in main.lua
I have tried requiring main.lua in Bird.lua as well, but I received loop or previous error loading module error.
How should I go about doing this?
main.lua
push = require 'push'
Bird = require 'Bird'
WINDOW_WIDTH = 1280
WINDOW_HEIGHT = 720
VIRTUAL_WIDTH = 512
VIRTUAL_HEIGHT = 288
local background = love.graphics.newImage('background.png')
local backgroundScroll = 0
local BACKGROUND_SPEED = 30
local BACKGROUND_LOOP_POINT = 413
local ground = love.graphics.newImage('ground.png')
local groundScroll = 0
local GROUND_SPEED = 70
...
Bird.lua
require 'main' --error
Bird = {}
function Bird:new(name)
o = o or {}
setmetatable(o,self)
self.__index = self
o.name = name
self.image = love.graphics.newImage('bird.png')
--returns width of image
self.width = self.image:getWidth()
--returns height of image
self.height = self.image:getHeight()
--centering the bird by default
self.x = VIRTUAL_WIDTH / 2 - (self.width / 2)
self.y = VIRTUAL_HEIGHT / 2 - (self.height / 2)
return o
end

For the sake of completion, I'm providing an answer based on Nifim's comment.
You should move the global variables in a separate file, e.g. constants.lua:
WINDOW_WIDTH = 1280
WINDOW_HEIGHT = 720
VIRTUAL_WIDTH = 512
VIRTUAL_HEIGHT = 288
Then, remove the require 'main' from Bird.lua and require 'constants' in your main.lua. Note that this will probably make the variables from constants.lua globally available which can be troubling (see also Nifim's comment).

Related

Unable to declare a new function in lua, compiler tells me to include an '=' sign near the name of the function

So i have this Util.lua file in which i am making all the functions which will be used across all the states of my game.
This is what my Util File is like
function GenerateQuads(atlas, tilewidth, tileheight)
local sheetWidth = atlas:getWidth() / tilewidth
local sheetHeight = atlas:getHeight() / tileheight
local sheetCounter = 1
local spritesheet = {}
for y = 0, sheetHeight - 1 do
for x = 0, sheetWidth - 1 do
spritesheet[sheetCounter] =
love.graphics.newQuad(x * tilewidth, y * tileheight, tilewidth,
tileheight, atlas:getDimensions())
sheetCounter = sheetCounter + 1
end
end
return spritesheet
end
function table.slice(tbl, first, last, step)
local sliced = {}
for i = first or 1, last or #tbl, step or 1 do
sliced[#sliced+1] = tbl[i]
end
return sliced
end
funtion GenerateQuadsPowerups()
local counter = 1
local quads = {}
return counter
end
note that the last function didn't work at all so i just returned counter for testing, the error message given is :
'=' expected near 'GenerateQuadsPowerups'
"Powerup" is a class i declared using a library class.lua. When i removed the problematic function from Util.lua, the same error was given on the first function i made in the Powerup.lua file.
Here's the class in case it is needed for reference
Powerup = Class{}
funtion Powerup:init()
self.x = VIRTUAL_WIDTH
self.y = VIRTUAL_HEIGHT
self.dx = 0
self.dy = -10
end
-- we only need to check collision with the paddle as only that collisionis relevant to this class
function Powerup:collides()
if self.x > paddle.x or paddle.x > self.x then
return false
end
if self.y > paddle.y or self.y > paddle.y then
return false
end
return true
end
funtion Powerup:update(dt)
self.y = self.y + self.dy * dt
if self.y <= 0 then
gSounds['wall-hit']:play()
self = nil
end
end
I can't understand what's going on here
Typo 1
funtion GenerateQuadsPowerups()
Typo 2
funtion Powerup:init()
Typo 3
funtion Powerup:update(dt)
self = nil achieves nothing btw. I guess you thought you could somehow destroy your PowerUp that way but it will only assign nil to self which is just a variable local to Powerup:update. It will go out of scope anyway.

Transition.to not moving object properly - Corona SDK

I have a table full of enemies and simple want them to move across the screen via gameLoop, however for some reason nothing seems to work. Its probably an easy fix but I have tried to fix it but am getting nowhere. Anyone know whats up?
gameLoop Function
local i
for i = 1, #enemies do--.numChildren,1, -1 do
local blocks = enemies[i]
if blocks ~= nil and blocks.x ~= nil then
enemyRate = 2.0 + (0.1 * wave)
transition.to( blocks, { time=1500, x=300} )
end
end
The Spawn Function
function spawnEnemy()
local spawnData = { -- Easily store spawns in a table to make it easier to add new enemies later
{name = "Blue", seq = "blueRect", frame = 3, imgSheet = imageSheetRectangle, seqData = sequenceDataRectangle},
{name = "Red", seq = "blueCross", frame = 1, imgSheet = imageSheetCross, seqData = sequenceDataCross},
{name = "Green", seq = "blueCirc", frame = 2, imgSheet = imageSheetCircle, seqData = sequenceDataCircle}
}
local xPos = display.contentWidth - 150
local r = math.random(1, #spawnData)
local sd = spawnData[r] -- get the spawn data for this enemy
local s = display.newSprite(sd.imgSheet, sd.seqData)
s.name = sd.name
physics.addBody(s, { isSensor = true })
s:setSequence(sd.seq)
s:setFrame(sd.frame)
s.y = display.contentHeight - 400
s.x = xPos
enemies[#enemies+1] = s
enemyGroup:insert(s)
In this related answer: transition.to( ) doesn't work within a function and with a Runtime:addEventListener( "enterFrame", method) listener in Corona / Lua you can see a similar issue as I stated above. You are creating an animation right as one is starting - making it seem as though it is not moving. As I suggested above, if it suits your game, begin the transition when you spawn the object; not every gameloop.

Receiving "Attempt to index global 'sprite' (a nil value)" in Lua

Im attempting to make a simple game app and keep running into this problem. I stopped programming in Lua for a few years so I don't exactly remember how to fix this. Anyway, my code is as follows:
EDIT: Here is the entire file. Still trying to figure out the formatting of Stack Overflow. Error occurs at line 76.
module(..., package.seeall)
-- Main function - MUST return a display.newGroup()
function new()
local localGroup = display.newGroup()
---------
local Rad = math.rad
local Sin = math.sin
local Cos = math.cos
local Pi = math.pi
local Atan2 = math.atan2
local radD = 180 / Pi
local DegR = Pi / 180
local touchPoint = display.newCircle(localGroup, -50, -50, 20)
touchPoint.isFocus = false
touchPoint.alpha = 0
function GetDistanceFromObjects(obj1, obj2)
local xDist = obj1.x - obj2.x
local yDist = obj1.y - obj2.y
local dist = Sqrt((xDist * xDist) + (yDist * yDist))
return dist
end
function getAngleDeg(inX1, inY1, inX2, inY2)
local xDist = inX2 - inX1
local yDist = inY2 - inY1
local angRad = Atan2(yDist, xDist)
return angRad * radD + 90
end
require "sprite"
function VectorFromAngle(inAngle, inVelocity)
local vx = Cos(Rad(inAngle-90))
local vy = Sin(Rad(inAngle-90))
if(inVelocity ~= nil)then
vx = vx * inVelocity
vy = vy * inVelocity
end
return vx,vy
end
require ( "physics" )
physics.start()
physics.setGravity( 1, 1 )
--( x, y )
--physics.setDrawMode ( "hybrid" )
math.randomseed(os.time())
local background = display.newImage("yazd.jpeg")
localGroup:insert(background)
--width of image divided by # of pics lined up from left to right (in the sprite) = the first #
--height of image divided by # of pics lined up from top to bottom (in the sprite) = the second #
local birdSheet = sprite.newSpriteSheet( "enemy.jpg", 59, 50 )
local birdSet = sprite.newSpriteSet(birdSheet, 1, 1)
-- images 1-14
sprite.add( birdSet, "bird", 1, 1, 200, 0 )
-- play 1-14, each image every 200 ms, 0 = loop count, which is infinite
local bird1 = sprite.newSprite( birdSet )
bird1.x = 40 -- starting point
bird1.y = 40 -- starting point
bird1.xScale = 0.5 --scale down x
bird1.yScale = 0.5 --scale down y
bird1:prepare("bird") --prepare sprite sequence
bird1:play() --play sprite
localGroup:insert(bird1)
--only local to this group
local killSheet = sprite.newSpriteSheet("explosion.png", 100, 100)
local killSet = sprite.newSpriteSet(killSheet, 1, 9)
sprite.add(killSet, "kill", 1, 9, 200, 1)
local birdCount = 1
local transDirection12
local function transDirection1()
bird1.xScale = 0.5
transition.to(bird1, {time=math.random(200,500), x = math.random(200,490), y = math.random(10,310), alpha = (math.random(9,100))/100, onComplete = transDirection12})
end
transDirection12 = function()
bird1.xScale = 0.5
transition.to(bird1, {time= math.random(200,500), x = math.random(200,490), y = math.random(10,310), alpha = (math.random(9,100))/100, onComplete = transDirection1})
end
transDirection1()
-- local transDirection1 declares what will be used (local function)
-- transDirection1 = function
-- following it are the function qualities
-- declares it will use object/image called bird1 and scales it to .5
-- time = ____ means it will take a certain time, between ____ and ____ to complete the transition
-- x=____ means that is where it will move to on the x axis
-- y=____ means that is where it will move to on the y axis
-- alpha = ___ means the is how transparent it will be
-- onComplete = ________ means that when the action is complete, it will call another function
-- The next function has the same qualities as transDirection1, but the onComplete part calls transDirection1 and they continue to loop
-- transDirection1() declares transDirection1 so the app knows about it and can use it
-- the other trans do not need to be declared because they are part of transDirection1, which is already declared
--(x, y, size.x, size.y)
local player = display.newImage( "mk11.png" )
player.x = 240
player.y = 260
player.xScale = .5
player.yScale = .5
localGroup:insert( player )
-- add physics to all the objects wanted: (object wanted, "static" or "dynamic")
physics.addBody(player, "static", {radius=30, isSensor = true})
physics.addBody(bird1, "static", {radius=23})
local function shoot(inPointX, inPointY)
-- (start at the x of the player + 10, also start at the y of the player, the radius of the circle is 5)
local bullet = display.newImage( "bullet2.png" )
bullet.x = player.x
bullet.y = player.y
-- add physics to the object, which is the bullet.
-- Make the bullet "dynamic" or moving
physics.addBody(bullet, "dynamic")
bullet.isFixedRotation = true
localGroup:insert( bullet )
local velocity = 300
local vx, vy = VectorFromAngle(player.rotation, velocity)
bullet.rotation = player.rotation
bullet:setLinearVelocity(vx, vy)
end
function RotateToTouchPoint(inPointX, inPointY)
local ang = getAngleDeg(player.x, player.y, inPointX, inPointY)
player.rotation = ang
end
local function ScreenTouchListener(event)
local phase = event.phase
if(phase == "began")then
if(touchPoint.isFocus == false)then
touchPoint.alpha = 1
touchPoint.x = event.x
touchPoint.y = event.y
display.getCurrentStage():setFocus(touchPoint, event.id)
touchPoint.isFocus = true
RotateToTouchPoint(event.x, event.y)
shoot(event.x, event.y)
end
elseif(touchPoint.isFocus)then
if(phase == "moved")then
touchPoint.x = event.x
touchPoint.y = event.y
RotateToTouchPoint(event.x, event.y)
elseif(phase == "ended" or phase == "cancelled")then
display.getCurrentStage():setFocus(touchPoint, nil)
touchPoint.isFocus = false
touchPoint.alpha = 0
end
end
return true
end
local function gotShot (event)
event.target:removeSelf()
event.other:removeSelf()
local explosion = sprite.newSprite(killSet)
explosion.x, explosion.y = event.target.x, event.target.y
explosion:prepare("kill")
explosion:play()
localGroup:insert( explosion )
birdCount = birdCount - 1
-- when there are no more birds, remove the runtime event listener and perform the
-- function with a delay of 500 m.s. The function changes the scene to test.lua
if "ended" then
if birdCount == 0 then
Runtime:removeEventListener("touch", ScreenTouchListener)
timer.performWithDelay(500, function()
director:changeScene("mainPage") end, 1)
end
end
end
bird1:addEventListener("collision", gotShot)
Runtime:addEventListener("touch", ScreenTouchListener)
---------
-- MUST return a display.newGroup()
return localGroup
end
Any help is appreciated!
The error message is perfectly clear -- the variable sprite used at this line:
local bird1 = sprite.birdSheet( birdSet )
has a nil value, meaning it has not been initialized or was set to nil. You need to show the earlier code where you should have set it up.
(After OP updates)
I think this line
require "sprite"
should actually be
sprite = require "sprite"
You can read more in modules tutorial here:
http://lua-users.org/wiki/ModulesTutorial

Corona SDK: Inserting into tables

I've read the other topics related to this subject and cannot make sense of them in the sense of my code. In the code below, I cannot get the make other word buttons into the table. I can generate the words but they will not go into the table. The previous function with the correct word works fine. What am I doing wrong? Do I have problems elsewhere in the code?
--main text
local content = require "content"
--chooses a random number according to the maximum number available in the table
local defaultWidth = 1024
local defaultHeight = 768
local displayWidth = display.viewableContentWidth
local displayHeight = display.viewableContentHeight
local yMargin = 20
local centerX = defaultWidth/2;
local centerY = defaultHeight/2;
local xAdjust = (defaultWidth - display.viewableContentWidth)/2
local yAdjust = (defaultHeight - display.viewableContentHeight)/2
local rnd = math.random
local maxSightwords = 3
local currQuestion = 0
local playOrder
local letterButtons
local wrongGraphic
local correctButton
--local wordButtons
function getRandomOrder(amount)
local order ={}
local i
local temp
local temp1
for n = 1,amount do
order[n] = n
end
for i=0,9 do
for temp = 1,amount do
n = math.random(1, amount)
temp1 = order[temp]
order[temp] = order[n]
order[n] = temp1
end
end
return order
end
-- assign random order for words
playOrder = getRandomOrder(#content)
function nextQuestion()
-- update question number index
currQuestion = currQuestion+1
if currQuestion > #playOrder then
currQuestion = 1
end
local questionNumber = playOrder[currQuestion]
print("Question# "..currQuestion)
print("id "..content[questionNumber].id)
-- make word buttons
wordButtons = {}
-- make word button for correct word
local word = content[playOrder[currQuestion]].word
table.insert(wordButtons, newWordButton(word))
correctButton = wordButtons[1].graphics
local buttonWidth = 150
print ("correct: "..word)
print (#wordButtons)
---[[
-- ****make other word buttons***
local otherWords = getRandomWords(content.word)
--print (otherWords)
for i=1, maxSightwords-1 do
table.insert(wordButtons, otherWords)
end
--]]
print (#wordButtons)
-- position letter buttons and add touch event listener
local randomWordOrder = getRandomOrder(#wordButtons)
local buttonSpacing = buttonWidth * 1.5
local buttonsWidth = (#wordButtons * buttonWidth) + ((#wordButtons-1) * (buttonSpacing/4))
local buttonsX = centerX - (buttonWidth)
for i=1, #wordButtons do
local button = wordButtons[i].graphics
button.y = centerY
button.x = buttonsX + (buttonSpacing * (randomWordOrder[i]-1))
button:addEventListener("touch", onWordTouch)
--local randomDelay = transitionDuration + (math.random(1,10) * 10)
--transition.from(button, {time = 500, delay = randomDelay, y = defaultHeight + button.height})
end
end
function clearQuestion()
-- remove wrongGraphic if present
if wrongGraphic then
wrongGraphic:removeSelf()
wrongGraphic = nil
end
-- remove all word buttons
for i=1,#wordButtons do
wordButtons[i].graphics:removeSelf()
wordButtons[i].graphics = nil
end
end
function onWordTouch(event)
local t = event.target
if "ended" == event.phase then
if t == correctButton then
onCorrect()
else
onIncorrect(t)
end
end
end
function onIncorrect(incorrectButton)
media.playSound("sounds/splat.wav")
wrongGraphic = display.newImageRect("images/graphics/wrong.png", 137, 136)
wrongGraphic.x = incorrectButton.x + incorrectButton.width/2
wrongGraphic.y = incorrectButton.y + incorrectButton.height/2
transition.to(incorrectButton, {time=100, delay=500, alpha=0})
transition.to(wrongGraphic, {time=200, delay=500, alpha=0, onComplete=wrongCompleteListener})
local wrongCompleteListener = function(obj)
obj:removeSelf()
obj = nil
incorrectButton:removeSelf()
incorrectButton = nil
end
end
function onCorrect()
-- play correct sound then display word
media.playSound("sounds/correct.mp3", playWord)
-- remove the letter buttons
clearQuestion()
-- disable the home button until new screen is shown
homeEnabled = false
end
function newWordButton(word)
local wordGraphic = display.newImageRect("images/words/"..word..".png", 150, 75)
local wordButton = {}
wordButton.graphics = display.newGroup()
wordButton.graphics:insert(wordGraphic)
wordButton.word = word
return wordButton
end
function getRandomWords ()
local wordGraphic = display.newGroup ()
for i=1,maxSightwords-1 do
--remove a word from content using a random index #
--Since the index will be between 1 and the number of words in content
--and each time through the loop a word is removed, you can be sure
--You will get 3 different words without repeats.
local next_word = table.remove(content, math.random(#content))
--next_word is a table with 'word' and 'id' fields so you can make the text display object from next_word.word
local wordText = display.newImageRect("images/words/"..next_word.id..".png", 150, 75)
wordText.x = display.contentWidth/2
wordText.y = display.contentHeight/2 - 100
wordGraphic:insert(wordText)
print (next_word.id)
end
end
nextQuestion ()
I think your problem is that you are resetting the wordButton = {} again in function newWordButton. You already made the table in function nextQuestion(), so by calling it again in the newWordButton function is reseting the entire table.
Take a look at this links:
http://www.coronalabs.com/blog/2011/06/21/understanding-lua-tables-in-corona-sdk/
http://docs.coronalabs.com/api/library/table/insert.html
I'm pretty sure the function should look like this:
function newWordButton(word)
local wordGraphic = display.newImageRect("images/words/"..word..".png", 150, 75)
wordButton.graphics = display.newGroup()
wordButton.graphics:insert(wordGraphic)
wordButton.word = word
return wordButton
end

Cannot change value of object in lua

i have a table(array) where i keep the references of some images. Here is the code:
local rowcount = 8
local colcount = 4
local blockWidth = display.contentWidth / (colcount*4)
local blockHeight = display.contentWidth / (rowcount*2)
local row
local col
local pan = 3
local i=0
for row = 1, rowcount do
for col = 1, colcount do
local x = (col - 1) * blockWidth + pan + 30
local y = (row + 1) * blockHeight + pan
local random= math.random(1,6)
random = revisarTres(i, random)
local image = display.newImage(images[random], 0, 0)
image.x = x
image.y = y
print (x)
print (y)
image.value = random
image:addEventListener("touch", blockTouch)
block[i] = image
i=i+1
end
end
I keep the references in block of my 31 images.
Then i make a transition for one image to another, conversely. And i want to change the value, the coordenates and the reference of this two. I'm making this:
block[old].value, block[new].value = block[new].value, block[old].value
block[old].x, block[new].x = block[new].x, block[old].x
block[old].y, block[new].y = block[new].y, block[old].y
block[old], block[new] = block[new], block[old]
Old is the position of one of the images i want to change and new of the other one.
The reference is changing but the value doesn't.
Please can someone help me,
Thanks!
One small note (addition?):
if You ever find a table, where You can't directly change values - check if it's not readonly one. More about this kind of technique using Lua metatables: lua-users Wiki - Read Only Tables

Resources