[SOLVED]HUMP Gamestate Issue: Passing Parameters Into New State

Questions about the LÖVE API, installing LÖVE and other support related questions go here.
Forum rules
Before you make a thread asking for help, read this.
Post Reply
User avatar
LudvickToba
Prole
Posts: 16
Joined: Wed Jan 11, 2017 9:51 pm

[SOLVED]HUMP Gamestate Issue: Passing Parameters Into New State

Post by LudvickToba »

Currently I'm writing a simple menu system using HUMP's Gamestate library. I've read the page, the readme, and that Gamestate.switch()/Gamestate.push() accepts extra parameters, but I just can't seem to figure out how to use those parameters onto a new gamestate.

I coded something simple to show what I want. There are two state files. StateOne.lua has the user pick one of three stats, each stat has a number to it(Ex.ATTACK stat is 10 and DEFENSE stat is 8). When you pick a stat, you go to StateTwo.lua, which you can make that stat's number bigger or smaller. The code for StateTwo can easily take some parameters from StateOne (like what stat was picked) and work from that.
However the only way I can make this work is if I make each stat have it's own unique StateTwo (like StateTwoAttack or StateTwoDefense) which is a lot of copy and pasting if there are more stats. OR I could put the code from StateTwo into StateOne using a variable state and if statements to switch between the two states, but that can get confusing and error prone. OR use the parameters I do want as a global variables but that doesn't seem efficient either.

Anyways, what do you guys think? Anyone know how to pass parameters into a new gamestate? Is there something I'm missing? The files that need to be looked at are at the root of the folder (main.lua, stateOne.lua, stateTwo.lua). I'll be posting the code for stateOne.lua and stateTwo.lua below too. Any advice or new ways to go about the problem are also welcomed!

stateOne.lua

Code: Select all

local Option_A = require 'objects.obj_option_a'
local TextBox = require 'objects.obj_textBox'

StateOne = {}

function StateOne:init()
end

function StateOne:enter()
	self.option = Option_A(10, 16, 20, 12, {"ATTACK", "DEFENSE", "LUCK"})

	self.howTo = "Z = Confirm, X = Back"
	self.selection = 1 -- WHAT OPTION ARE WE ON NOW? (1 = 'ATTACK', 2 = 'DEFENSE' etc...)
	self.explain = {
		[1] = "Base attack power",
		[2] = "Base defense power",
		[3] = "Chance of crit & item drop",
	}
	self.textBox = TextBox(1, 1, 29, 2)
	self.textBox2 = TextBox(1, 5, 29, 2)
end

function StateOne:update(dt)
end

function StateOne:draw()
	self.textBox:draw(self.howTo)
	self.textBox2:draw(self.explain[self.selection])
	self.option:draw()
	
	printStatOnly(hero, "ATTACK", 11, 18)
	printStatOnly(hero, "DEFENSE", 11, 20)
	printStatOnly(hero, "LUCK", 11, 22)
end

function StateOne:keypressed(key)
	if key == 'down' then
		if self.selection >= table.getn(self.option.options) then -- if we go out of bounds
			self.selection = 1 -- Go to top
		else
			self.selection = self.selection + 1
		end
		self.option:setSelect(self.selection)
	elseif key == 'up' then
		if self.selection <= 1 then -- if we go out of bounds
			self.selection = table.getn(self.option.options) -- Go to bottom
		else
			self.selection = self.selection - 1
		end
		self.option:setSelect(self.selection)
	elseif key == 'z' then
		return self:inputHandler(self.selection)
	elseif key == 'x' then
	end
end

local bindings = {
	--WHAT I WANT
	--[1] = function() Gamestate.push(StateTwo, "ATTACK", 11, 18) end,

	--WHAT WORKS
	[1] = function() Gamestate.push(StateTwo) end,
	--NOTHING HERE YET
	[2] = function() Gamestate.push() end,
	[3] = function() Gamestate.push() end,
}

function StateOne:inputHandler(input)
	local action = bindings[input]
	if action then return action() end
end

function printStatOnly(unit, id, x, y)
	local base = unit:GetBase(id)
	local full = unit:Get(id)
	local space = ""
	for i = 1, string.len(id) do
		space = space .. " "
	end
	local str = string.format("%s %d:%d", space, base, full)
	love.graphics.print(str, x*8, y*8)
end
stateTwo.lua

Code: Select all

local TextBox = require 'objects.obj_textBox'

StateTwo = {}

function StateTwo:init()
end
	--WHAT I WANT
--function StateTwo:enter(stat, x, y)
function StateTwo:enter()
	--WHAT I WANT
	--[[	
	self.stat = stat
	self.x = x
	self.y = y
	--]]
	self.howTo = "Arrow key to + & -.X to back"
	self.textBox = TextBox(1, 1, 29, 2)
end

function StateTwo:update(dt)
end

function StateTwo:draw()
	StateOne:draw()
	self.textBox:draw(self.howTo)

	love.graphics.setColor(255,201,14)
	--WHAT I WANT
	--printStatOnly(hero, self.stat, self.x, self.y)
	
	--WHAT WORKS (THE HARD CODING)
	printStatOnly(hero, "ATTACK", 11, 18)
	love.graphics.setColor(255,255,255)
end

-- THIS IS HARD CODED TOO, BUT EASILY CAN TAKE PARAMETERS 
function StateTwo:keypressed(key)
	local baseValue = hero:GetBase("ATTACK")
	if key == 'up' then
		if baseValue + 1 <= hero.statLimit then
			baseValue = baseValue + 1
			hero:EditBaseStat("ATTACK", baseValue)
		end
	elseif key == 'down' then
		if baseValue - 1 > 0 then
			baseValue = baseValue - 1
			hero:EditBaseStat("ATTACK", baseValue)
		end
	elseif key == 'x' then
		Gamestate.pop()
	end
end
Attachments
Menu.zip
(14.08 KiB) Downloaded 174 times
Last edited by LudvickToba on Wed Jun 20, 2018 3:39 pm, edited 1 time in total.
User avatar
Lirija
Prole
Posts: 28
Joined: Tue Mar 14, 2017 11:42 am
Contact:

Re: HUMP Gamestate Issue: Passing Parameters Into New State

Post by Lirija »

I think you can solve it this way:

let's say you call Gamestate.push(StateTwo, "ATTACK", 11, 18), then you should define StateTwo:enter() as such:

Code: Select all

function StateTwo:enter(prev, attack, defense, speed)
	local atk = attack
	local dfs = defense
	local spd = speed
	--and so on
	
end
or this one might be better (usually i stick with the verbose function definition of the first example for the sake of clarity)

Code: Select all

function StateTwo:enter(prev, ... )
	local atk, dfs, spd = ...

	-- and so on..


end
Let me know if this works!
User avatar
LudvickToba
Prole
Posts: 16
Joined: Wed Jan 11, 2017 9:51 pm

Re: HUMP Gamestate Issue: Passing Parameters Into New State

Post by LudvickToba »

@Lirija Sadly this isn't working for me. Using the same call as you did it appears that the extra parameters are not passing through. Here's the changes what I did with stateTwo following your instructions.

Code: Select all

StateTwo = {}

local stat, x, y = nil
function StateTwo:init()
end
	--WHAT I WANT
function StateTwo:enter(prev, stat, x, y)
--function StateTwo:enter()
	--WHAT I WANT
		
	stat = stat 
	x = x
	y = y
	--]]
	self.howTo = "Arrow key to + & -.X to back"
	self.textBox = TextBox(1, 1, 29, 2)
end
When calling a print function that uses variables stat(string), x(num), y(num) it only gets nil and produces an error. :(
Also as a side note, when declaring a local variable inside a function, that variable only exist in that function right? It can't be accessed by any other function even if it's in the same file?
User avatar
Lirija
Prole
Posts: 28
Joined: Tue Mar 14, 2017 11:42 am
Contact:

Re: HUMP Gamestate Issue: Passing Parameters Into New State

Post by Lirija »

Wait i don't think you can do things like

Code: Select all

	stat = stat 
	x = x
	y = y
outside of a table, like in

Code: Select all

	some_table = {	
		stat = stat, 
		x = x,
		y = y
		}
also if you want to store those value in the second state you might want to declare the variables as state fields (so you can use them in the other state functions):
Ok you actually declared them such that their scope is the whole module so i think the problem lies in the first thing i told you;

Let me know if this fix the problem!

p.s. i don't know if this will change something but in my project i don't call Gamestate.registerEvents() but Gamestate.update(dt) and Gamestate.draw() inside the love callbacks.

Code: Select all


StateTwo = {}

function StateTwo:init()
	self.stat = nil
	self.x = nil
	self.y = nil
end
	--WHAT I WANT
function StateTwo:enter(prev, stat, x, y)
--function StateTwo:enter()
	--WHAT I WANT
		
	self.stat = stat 
	self.x = x
	self.y = y
	--]]
	self.howTo = "Arrow key to + & -.X to back"
	self.textBox = TextBox(1, 1, 29, 2)
end
User avatar
LudvickToba
Prole
Posts: 16
Joined: Wed Jan 11, 2017 9:51 pm

Re: HUMP Gamestate Issue: Passing Parameters Into New State

Post by LudvickToba »

Nope, still nothing. Also if I read the readme correctly, Gamestate.registerEvents() is used to automatically call state callbacks corresponding with love's (ex. Gamestate.draw() is automatically called when love.draw() is called.)
User avatar
Lirija
Prole
Posts: 28
Joined: Tue Mar 14, 2017 11:42 am
Contact:

Re: HUMP Gamestate Issue: Passing Parameters Into New State

Post by Lirija »

Also if I read the readme correctly, Gamestate.registerEvents() is used to automatically call state callbacks corresponding with love's (ex. Gamestate.draw() is automatically called when love.draw() is called.)
Yes it might not be relevant, i don't call it as i need to do some things specifically before and after the update / draw call;

Anyway i did a few test just now and it works, here the relevant code:

play gamestate:

Code: Select all

function play:update(dt)

	if love.keyboard.wasPressed("p") then
		local img = love.graphics.newImage ( love.graphics.newScreenshot( ) ) -- take a screenshot

		Gamestate.push(gstates.pause, img, self.map.width, self.map.height, "something")
	end
	--stuff...
end

pause gamestate

Code: Select all


local pause = {}
pause.screen = nil
pause.width = 0
pause.height = 0
pause.string = nil

function pause:init()
end

function pause:enter(prev, img, width, height, string, ...)
--	Gamestate.push(gstates.play)
	self.screen = img
	self.width = width
	self.height = height
	self.string = string
end

function pause:draw()

	-- both of those print "something"
		print(self.string)
		love.graphics.print(self.string, g_WIDTH/2 - 32, g_HEIGHT/2)

end

return pause
I realized i have this bit of code in the main.lua:

Code: Select all


Gamestate = require "libs.gamestate"

-- global table of gamestates

gstates = {
			menu = require "gamestates.menu",
			play = require "gamestates.play",
			pause = require "gamestates.pause",
}


have you required all the gamestates somewhere, or at least you required StateTwo inside of StateOne?

Just for testing i found out that even if i change the call from play:update() like this it still works:

Code: Select all

function play:update(dt)

	if love.keyboard.wasPressed("p") then
		local img = love.graphics.newImage ( love.graphics.newScreenshot( ) ) -- take a screenshot

		Gamestate.push(require("gamestates.pause"), img, self.map.width, self.map.height)
	end
	--stuff...
end
User avatar
LudvickToba
Prole
Posts: 16
Joined: Wed Jan 11, 2017 9:51 pm

Re: HUMP Gamestate Issue: Passing Parameters Into New State

Post by LudvickToba »

Okay the code is working now! Thank you Lirija!
Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot], Bing [Bot], Google [Bot], Semrush [Bot] and 12 guests