Page 1 of 1

Stuck with functions

Posted: Sat May 10, 2014 1:04 am
by Blackhardd
I know it's more related question for LUA then for Love2D but i'm asking for help. I had just two simple lua scipts.
First is "buttons.lua"

Code: Select all

function createBtn( imgPath, btnName )
	btnName = love.graphics.newImage(imgPath)
end
and "main.lua"

Code: Select all

require("buttons")
function love.load()
	createBtn("Sprites/Menu/exit.png", exit_btn)
end

function love.update(dt)

end

function love.draw()
	love.graphics.draw(exit_btn, 200, 200)
end
I'm trying to create function that creates and draw buttons and i am totally don't understand why it doesn't works. I'll be glad if you tell me where is the problem. I am newbie at programming.
Regards Blackhardd.

Re: Stuck with functions

Posted: Sat May 10, 2014 2:27 am
by ejmr
The code is not saving the button anywhere, i.e. love.draw() never sees exit_btn. One would to address the issue would be to create a table of all the buttons and the change love.draw() to loop through that table, drawing each button. For example:

Code: Select all

-- This will be a global variable containing all of the buttons.
Buttons = {}

-- Takes the name of the button, the image to draw for the button, and
-- coordinates for where to draw it, which we store in the `Buttons`
-- table above.
function createButton(name, imagePath, x, y)
    Buttons[name] = { love.graphics.newImage(imagePath), x, y }
end

function love.load()
    createButton("Exit", "Sprites/Menu/Exit.png", 200, 200)
    createButton("Save", "Sprites/Menu/Save.png", 200, 400)
end

-- Now the `Buttons` table looks like this:
--
-- {
--     ["Exit"] = { Image, 200, 200 },
--     ["Save"] = { Image, 200, 400 }
-- }
--
-- The `Image` in each case is the object that
-- love.graphics.newImage() returns.
--
-- With this structure we can draw all of the buttons like so:
function love.draw()
    for name,data in pairs(Buttons) do
        -- This is the same as
        --
        --     love.graphics.draw(data[1], data[2], data[3])
        --
        -- but we can use unpack() to take advantage of the fact that
        -- the way we stored the data for buttons is in the order that
        -- love.graphics.draw() expects for its arguments.
        love.graphics.draw(unpack(data))
    end
end
This is only one way to do what you want, but I hope the code helps and makes sense.

Re: Stuck with functions

Posted: Sat May 10, 2014 2:43 am
by Suppercut
Blackhardd wrote:I know it's more related question for LUA then for Love2D but i'm asking for help. I had just two simple lua scipts.
First is "buttons.lua"

and "main.lua"

I'm trying to create function that creates and draw buttons and i am totally don't understand why it doesn't works. I'll be glad if you tell me where is the problem. I am newbie at programming.
Regards Blackhardd.
The problem you're having isn't with functions -- it's with how variables work.

First, let's look here.

Code: Select all

function createBtn( imgPath, btnName )
	btnName = love.graphics.newImage(imgPath)
end
In the top part, btnName is defined as a local variable representing what the second argument is, as a value. What you're doing here is instead overwriting that local variable, NOT the variable named in the second argument.

Code: Select all

function createBtn( imgPath, btnName ) -- Here, a local variable is created called btnName, and it has a value of whatever the second argument is when the function is called.
	btnName = love.graphics.newImage(imgPath) -- But here, the variable btnName's value changes from being the second argument to the ID of the image.
end -- The "end" statement marks the end of the code block, and all local variables in the code block it ends are forgotten by Lua.
It gets worse. Here, there's an even bigger problem with calling the function:

Code: Select all

require("buttons")
function love.load()
	createBtn("Sprites/Menu/exit.png", exit_btn) -- exit_btn is entered as a variable, not a string. And since exit_btn has nothing assigned to it, the second argument is passed as nil, or "nothing".
end
Finally, it would be ten times as efficient if you just assigned it directly, since all you're doing here is literally this:

Code: Select all

function love.load()
	exit_btn = love.graphics.newImage("Sprites/Menu/exit.png")
end

function love.update(dt)

end

function love.draw()
	love.graphics.draw(exit_btn, 200, 200)
end

Re: Stuck with functions

Posted: Sat May 10, 2014 8:10 am
by XxSolidJelloxX
Is it bad that this is how I would do this?

Code: Select all

function love.load()
   -- can store all of the buttons here for later use
   -- buttons[i] = {name, location, x, y}
   buttons = {}
   buttons[1] = {enter, "images/enter.png" 100, 100}
   buttons[2] = {exit, "images/exit.png" 200, 100}

   for i = 1,#buttons do
      buttons[i][1] = love.graphics.newImage(buttons[i][2])
   end
end

function love.update(dt)

end

function love.draw()
   for i = 1,#buttons do
      love.graphics.draw(buttons[i][1], buttons[i][3], buttons[i][4]
   end
end
I feel that I took a more "manual" approach, not the best for a button creator. Could be useful for something more static? (i.e a game menu)
Finally, it would be ten times as efficient if you just assigned it directly, since all you're doing here is literally this:

Code: Select all

function love.load()
	exit_btn = love.graphics.newImage("Sprites/Menu/exit.png")
end

function love.update(dt)

end

function love.draw()
	love.graphics.draw(exit_btn, 200, 200)
end
Looking back on it, I essentially just did this^, but added a table and some for loops, which just makes it more efficient for throwing in multiple buttons.

Re: Stuck with functions

Posted: Sat May 10, 2014 8:31 am
by Blackhardd
Thanks all for response. And i have one more question.
I have this code:

Code: Select all

function love.load()
	-- Setting window
	love.window.setMode(1280, 720, {fullscreen=false})
	love.window.setTitle("Blackhardd")
	
	-- Loading menu images
	logo = love.graphics.newImage("Sprites/Menu/logo.png")
	play_btn = love.graphics.newImage("Sprites/Menu/play.png")
	exit_btn = love.graphics.newImage("Sprites/Menu/exit.png")
	
	-- Loading particle sprites
	svastika = love.graphics.newImage("Sprites/Particles/svastika.png")
	
	-- Creating particles
	menu_bg_svast = love.graphics.newParticleSystem(svastika, 50)
end

function love.update(dt)
	-- Getting middle of the window
	scrnRes_w = (love.window.getWidth())*0.5
	scrnRes_h = (love.window.getHeight())*0.5
	
	-- Checking cursor overlaping
	onExitBtn = false
	
	mX = love.mouse.getX()
	mY = love.mouse.getY()
	
	if mX > (scrnRes_w - 150) and mX < (scrnRes_w + 150)
	and mY > scrnRes_h and mY < (scrnRes_h + 75)
	then
		onExitBtn = true
	end
	
	-- Exit function
	if love.keyboard.isDown("escape") then
		love.event.quit()
	end
	
	-- Particles
	menu_bg_svast:setPosition( scrnRes_w, scrnRes_h - 30)
	menu_bg_svast:setAreaSpread( normal, 300, 300)
	menu_bg_svast:setSizes( 0.5)
	menu_bg_svast:setColors( 255, 255, 255, 0, 255, 255, 255, 255, 255, 255, 255, 0)
	menu_bg_svast:setEmissionRate(4)
	menu_bg_svast:setParticleLifetime( 5, 7)
	menu_bg_svast:setRadialAcceleration( 5, 25)
	menu_bg_svast:setSpeed( 2, 5)
	menu_bg_svast:setSpin( 0, 15)
	menu_bg_svast:setSpinVariation(1)
	menu_bg_svast:setSpread(45)
	menu_bg_svast:update(dt)
	
	if love.mouse.isDown("l")
	and onExitBtn == true
	then
		love.event.quit()
	end
end

function love.draw()
	-- Drawing particles
	love.graphics.draw(menu_bg_svast)
	
	-- Draw buttons
	love.graphics.draw(logo, scrnRes_w - 150, scrnRes_h - 177)
	love.graphics.draw(play_btn, scrnRes_w - 150, scrnRes_h - 87)
	love.graphics.draw(exit_btn, scrnRes_w - 150, scrnRes_h)
	
	-- Draw background
	love.graphics.setBackgroundColor(200, 200, 200)
end
How to separate code which handle menu into other script and make it works? Is it possible?
Thank alot for quick responsing.

Re: Stuck with functions

Posted: Sat May 10, 2014 8:52 am
by XxSolidJelloxX
Blackhardd wrote:Thanks all for response. And i have one more question.

How to separate code which handle menu into other script and make it works? Is it possible?
Yes, it is possible to call functions from another file.

you could turn this code:

Code: Select all

function love.draw()
	-- Drawing particles
	love.graphics.draw(menu_bg_svast)
	
	-- Draw buttons
	love.graphics.draw(logo, scrnRes_w - 150, scrnRes_h - 177)
	love.graphics.draw(play_btn, scrnRes_w - 150, scrnRes_h - 87)
	love.graphics.draw(exit_btn, scrnRes_w - 150, scrnRes_h)
	
	-- Draw background
	love.graphics.setBackgroundColor(200, 200, 200)
end
into this:

Code: Select all

-- make sure to include this, as it references to the outside file(s) that you want to use
require "draws"

function love.draw()
   drawAll()
end
by doing this: *Separate file "draws.lua" (or whatever you would like to name it)

Code: Select all

function drawParticles()
   love.graphics.draw(menu_bg_svast)
end

function drawButtons()
   love.graphics.draw(logo, scrnRes_w - 150, scrnRes_h - 177)
   love.graphics.draw(play_btn, scrnRes_w - 150, scrnRes_h - 87)
   love.graphics.draw(exit_btn, scrnRes_w - 150, scrnRes_h)
end

function drawBackground()
   love.graphics.setBackgroundColor(200, 200, 200)
end

function drawAll()
   drawParticles()
   drawButtons()
   drawBackground()
end
This is how I would do it... not sure if it is the most efficient way, but it works :)