I'm running into some confusion in trying to make a button that executes a function from another class I have.
Firstly, i have a "button" class that i made, in which one of the parameters is a function that can be done when the button is clicked.
The first button i made was simple, it would give you 1 coin when pressed by calling a function called addcoins:
function addcoins()
coins = coins + 1
end
super simple, but the function only worked when i put it in the parameters without the parentheses (the only thing that matters here is where i have addcoins, all other things are working fine)
bigButton = Button.new("circle", x_mid, y_mid, 100, 100, addcoins, nil, "button :D")
otherwise it would refuse to function. however, now I'm making a new button that calls a function from another class. This function a) increases the "level" of a "soul" and increases the price for the next level
function Soul:buy()
if self.lvl + 1 <= 100 then
self.lvl = self.lvl + 1
self.price = self.price * 1.01
end
end
so, i try to call the function the same way that I did the previous one with
wheat.button = Button.new("rectangle", 0, 15, 100, 30, wheat:buy, self, 100)
however, this doesn't work! It gives me an error saying that function parameters are expected. When i try to add the parentheses like so
wheat.button = Button.new("rectangle", 0, 15, 100, 30, wheat:buy(), self, 100)
I avoid the error message, but the function seems to get called exactly once when i start the program and the button still doesn't work, neither increasing the level or price.
I'm still quite new to Lua and very inexperienced in coding in general and especially classes, so I worry I may be missing something thats making this not work. What can I do to fix it and make the button work?
Here's all the relevant code. I'm sorry there's a lot, but I'm not sure where it's going wrong.
local love = require "love"
local constants = require "constants"
local Button = {}
Button.__index = Button
function Button.new(shape, x, y, width, height, func, func_param, text)
local self = setmetatable({}, Button)
self.shape = shape
self.x = x
self.y = y
self.width = width
self.height = height
self.func = func or function () end
self.func_param = func_param or nil
self.text = text or ''
if self.shape == "circle" then
self.x_min = self.x - self.width
self.x_max = self.x + self.width
self.y_min = self.y - self.width
self.y_max = self.y + self.width
else
self.x_min = self.x
self.x_max = self.x + self.width
self.y_min = self.y
self.y_max = self.y + self.height
end
return self
end
function Button:clicked(mouse_x, mouse_y)
if mouse_x > self.x_min and
mouse_x < self.x_max and
mouse_y > self.y_min and
mouse_y < self.y_max then
if self.func_param then
self.func(func_param)
else
self.func()
end
end
end
function Button:draw()
if self.func_con then
love.graphics.setColor(255,255,255)
else
love.graphics.setColor(200,200,200)
end
if self.shape == "circle" then
love.graphics.circle ("fill", self.x, self.y, self.height)
else
love.graphics.rectangle ("fill", self.x, self.y, self.width, self.height)
end
love.graphics.setColor(0,0,0)
if self.shape == "circle" then
love.graphics.printf (self.text, self.x_min, self.y-7.5, self.width*2, "center")
else
love.graphics.printf (self.text, self.x_min, (self.y_max + self.y_min)/2-7.5, self.width, "center")
end
end
local Soul = {}
Soul.__index = Soul
function Soul.new(Name, Price)
local self = setmetatable({}, Soul)
self.name = Name
self.lvl = 1
self.price = price
return self
end
function Soul:buy()
if self.lvl + 1 <= 100 then
self.lvl = self.lvl + 1
self.price = self.price * (1.01)
end
end
local x_size, y_size = love.graphics.getDimensions()
local x_mid = x_size/2
local y_mid = y_size/2
local coins = 0
function addcoins()
coins = coins + 1
end
function love.load()
bigButton = Button.new("circle", x_mid, y_mid, 100, 100, addcoins, "button :D")
wheat = Soul.new(wheat, 100, 100, 100)
wheat.button = Button.new("rectangle", 0, 15, 100, 30, wheat:buy, 100)
end
function love.update()
end
function love.mousepressed(x, y)
bigButton:clicked(x, y)
wheat.button:clicked(x,y)
end
function love.draw()
bigButton:draw()
wheat.button:draw()
love.graphics.setColor(255,255,255)
love.graphics.print(coins,0,0)
love.graphics.print(wheat.lvl,0,45)
end
Full code here -> https://pastebin.com/0qqYyM5u
The trouble is that wheat:buy
is actually a call due to the :
syntax, shorthand for wheat.buy(wheat)
, unlike a plain top-level function like addcoins
.
You can wrap wheat:buy
in an anonymous function to work around this, since the anonymous function won't be invoked instantly:
wheat.button = Button.new(
"rectangle", 0, 15, 100, 30, function() wheat:buy() end, 100
)
Also, function Soul.new(Name, Price)
should be function Soul.new(Name, price)
. Convention is to lowercase variable names (snake_case or camelCase), but the change suggested here at least gets the program running.