stateful.lua

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: stateful.lua

Post by kikito »

SiENcE wrote:Do I still need to define the following in game.lua ?
It's not required. But I do that from time to time. It depends on whether you need a "base" draw - if two or more of your states don't draw anything, for example, putting an empty function on Game:draw is simpler than having two empty functions on each state.
When I write def I mean function.
User avatar
SiENcE
Party member
Posts: 797
Joined: Thu Jul 24, 2008 2:25 pm
Location: Berlin/Germany
Contact:

Re: stateful.lua

Post by SiENcE »

Thanks for all the answers.

Last questions :).

First:

main.lua

Code: Select all

local Game = require ('game')
local game = nil -- the "game" var is local; only visible on this file
game.lua

Code: Select all

local class = require ( 'lib/middleclass' )
local Game = class('Game'):include(Stateful)
ingame.lua

Code: Select all

local Game = require 'game'
local InGame = Game:addState('InGame')
Is this right? I ask because why is the InGame state added to the new game class reference instead to the instance 'game' i made in main.lua?

Second question.

How can I get the current state? I need this because most ressources are loaded in 'ingame' state.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: stateful.lua

Post by kikito »

SiENcE wrote: Is this right? I ask because why is the InGame state added to the new game class reference instead to the instance 'game' i made in main.lua?
Yes, it is right. States are added to classes. But they are used by instances, just like methods.
SiENcE wrote: How can I get the current state? I need this because most ressources are loaded in 'ingame' state.
There is no default way to do that. You can create a :getCurrentState() function and override it on each state if you need to. But you shouldn't do that, you should not make "if state == xxx" on your code. That's the whole reason why you are using stateful in the first place. When you need to put an 'if state == xxx', create a new stateful function, make it do nothing by default, and make it do something on the xxx state.

Before you say "but this is a very basic functionality, the library should provide it": it's a bit more complex. Stateful does not have a "single current state", it has a "stack of states". You can "push" states one on top of the other; The ones at the top of the pile "override" the ones below them, but only in the methods they define. As a result, asking "what's the current state" is difficult. You can ask "what is in the pile" (and there is a function for that - getStateStackDebugInfo(). It's an ugly name on purpose - you should be using it for debugging, not for common game code.
When I write def I mean function.
User avatar
SiENcE
Party member
Posts: 797
Joined: Thu Jul 24, 2008 2:25 pm
Location: Berlin/Germany
Contact:

Re: stateful.lua

Post by SiENcE »

Okay, but how can I access my loaded ressources? The only way I can think of is a global.

I load my ressources (images,sounds,fonts) in my ingame.lua state, but I need to access them also in all classes used in ingame.lua state.

I mean, loading the ressources like sounds in every class is a bit contra productive :-/, because same sounds are used on different places.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: stateful.lua

Post by kikito »

Put them inside your game instance variable (it's 'self' on the state methods).
When I write def I mean function.
User avatar
SiENcE
Party member
Posts: 797
Joined: Thu Jul 24, 2008 2:25 pm
Location: Berlin/Germany
Contact:

Re: stateful.lua

Post by SiENcE »

Sorry I don't get it. Could you give me an example?

I use middleclass for other classes. For example, I want to play a sound in a gui class (uses middleclass). I use the gui class in my 'ingame' state. When I put the soundloading inside the 'game' instance (that one that include(Stateful)) ... how can i access this sounds?! Accessing self in my gui class, of couse don't work. It's the gui instance.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: stateful.lua

Post by kikito »

SiENcE wrote:Sorry I don't get it. Could you give me an example?

I use middleclass for other classes. For example, I want to play a sound in a gui class (uses middleclass). I use the gui class in my 'ingame' state. When I put the soundloading inside the 'game' instance (that one that include(Stateful)) ... how can i access this sounds?! Accessing self in my gui class, of couse don't work. It's the gui instance.
Depends on where you load the sound. If you had a LoadingState where the resources are loaded, you could put it in the Game instance like this:

Code: Select all

-- gamestates/loading.lua
local Game = require 'game'
local Loading = Game:addState('Loading')

function Loading:enterState()
  self.sfx = self.sfx or {}
end

function LoadingState:update()
  self.sfx.music = love.audio.newSource('sfx/music.mp3')
  self.sfx.shoot = love.audio.newSource('sfx/shoot.mp3')
  ...
  self:gotoState('MainMenu')
end

return Loading
And it would be available on the Main menu through self.sfx:

Code: Select all

-- gamestates/main_menu.lua
local Game = require 'game'
local MainMenu = Game:addState('MainMenu')

function MainMenu:enterState()
  love.sfx.music:play()
end

...

return MainMenu
The minimal main.lua capable of orchestating orchestates all this would look like this:

Code: Select all

local Game = require 'game'
require 'gamestates.loading'
require 'gamestates.main_menu'
... (other states)

local game

function love.load()
  local game = Game:new()
  game:gotoState('Loading') -- This could also be done in Game:initialize()
end

function love.update(dt)
  game:update(dt)
end
When I write def I mean function.
User avatar
SiENcE
Party member
Posts: 797
Joined: Thu Jul 24, 2008 2:25 pm
Location: Berlin/Germany
Contact:

Re: stateful.lua

Post by SiENcE »

Ok I undestand now. When I self something in a State, I can access it in other States with "self." .

I think you meant

Code: Select all

self.sfx.music:play()
instead of

Code: Select all

love.sfx.music:play()
But how can I access this sfx in a normal middleclass class? It's not a state.
User avatar
SiENcE
Party member
Posts: 797
Joined: Thu Jul 24, 2008 2:25 pm
Location: Berlin/Germany
Contact:

Re: stateful.lua

Post by SiENcE »

Sorry, i edited my former post a couple of times.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: stateful.lua

Post by kikito »

SiENcE wrote:
I think you meant

Code: Select all

self.sfx.music:play()
instead of

Code: Select all

love.sfx.music:play()
Yes, sorry.
SiENcE wrote:But how can I access this sfx in a normal middleclass class? It's not a state.
The same way you would handle any other dependency. There are many ways to do this - the usual thing to do when a class needs something to work, is passing whatever the class needs as a parameter on the class' initialize method, so it can be used by its instances. Or, if it's shared by all instances, it can be put on the class as a static attribute. Or even in a global variable, if it's important enough. It depends on the case.

I realize I am vague, but it's difficult to give you a concrete answer without knowing all the facts. I hope it helps anyway.
When I write def I mean function.
Post Reply

Who is online

Users browsing this forum: No registered users and 1 guest