lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


John Belmonte wrote:
> 
> Hi,
> 
> As Dolfi kept his example simple there isn't much state in the characters (firing and
> firing_counter in enemy).  But in a real game there is a lot of state and complicated timing.
> Implementation and interaction of state machines is what I've always found frustrating about
> program design as opposed to hardware design, where everything is running in parallel.

Yeah, state machines: That's where my approach really kicks in:

State transitions are triggered by events or by logic decisions inside
"state code". State code is either executed when a state gets activated
(Moore automaton), or when a transition occurs (Mealy automaton). Mealy
automata are simpler for a given task, but the most practical are hybrid
automata where code is executed in all of the above occasions. In Lua,
state machines are a breeze, because you have anonymous functions and
beautiful table facilities:

my_fsm =
{ currentstate = "start",
  start  = { action = function ... end, mouseclick =  },
  state2 = { action = function ... end, crash = { cond = function() ...
end, action = function() ... end, to = "final" } }
  -- But one might as well use add_transition to add transitions; a
little 
  state3 = { }
  ...
  final = { action = shutdown } -- hypothetic shutdown function
}

function my_fsm:add_transition(from, _to, event, _cond, _action)
  -- state existence and multiplicity check omitted!!!
  self[from][event] = { action = _action, cond = _cond, to = _to }
end

-- just a sample: look up a transition with label event; do the
transition, but only when its condition 
-- is satisfied; execute state and transition actions
function my_fsm:send_event(event)
  local state = self[self.currentstate]
  local trans = state[event]

  if state==nil then print("FSM has no state " .. self.currentstate)

  -- decide yourself what arguments you pass to cond() and action()
  if trans==nil then 
    print("No transition for event " .. event)
  elseif trans.cond==nil or trans.cond( ) then
    if trans.action~=nil then trans.action( ) end
    self.currentstate = trans.to
    state = self[self.currentstate]
    if state.action~=nil then state.action( ) end
  end  
end

my_fsm:send_event("mouseclick")
my_fsm:send_event("crash")

OK, now you mix this stuff with the stuff I sent before, and there goes
your game engine, without coroutines and multithreading ;) (I know, I
know, it's not that simple...)

Dolfi