Gia soy Aleko! (Hi Alekos)
Here is a more detailed approach (but still simple). I kept the code snippet as simple as possible.
Now you have the ability to execute code only once, when an entity enters into and exits from a state.
You can implement as much states as you want.
SetErrorMode(2)
SetWindowTitle("fsm")
SetWindowSize(1024, 768, 0)
SetWindowAllowResize(1)
SetVirtualResolution(1024, 768)
SetOrientationAllowed(1, 1, 1, 1)
SetScissor(0, 0, 0, 0)
UseNewDefaultFonts(1)
// the following constants are common to all entities
#constant PHASE_ENTER 0
#constant PHASE_RUN 1
#constant PHASE_EXIT 2
// the following constants are specific to entity
#constant ENTITYSTATE_NONE 0
#constant ENTITYSTATE_IDLE 1
#constant ENTITYSTATE_WALK 2
#constant ENTITYSTATE_PUSH 3
type _Entity
state as integer
state_prev as integer
phase as integer
endtype
function Entity_Update(ent ref as _Entity)
// here you can write code for the entity, that does not depends on any state
Print(ScreenFPS())
// execute the current state
select ent.state
case ENTITYSTATE_IDLE
Entity_StateIDLE(ent)
endcase
case ENTITYSTATE_WALK
Entity_StateWALK(ent)
endcase
case ENTITYSTATE_PUSH
Entity_StatePUSH(ent)
endcase
endselect
endfunction
function Entity_StateIDLE(ent ref as _Entity)
if ent.phase = PHASE_ENTER then Entity_OnEnterState(ent)
Print("Entity is in IDLE state")
Print("Press [W] to walk, [P] to push")
// check for W key
if GetRawKeyPressed(87) = 1
Entity_SetState(ent, ENTITYSTATE_WALK)
endif
if GetRawKeyPressed(80) = 1
Entity_SetState(ent, ENTITYSTATE_PUSH)
endif
endfunction
function Entity_StateWALK(ent ref as _Entity)
if ent.phase = PHASE_ENTER then Entity_OnEnterState(ent)
Print("Entity is WALKING")
// check for W key
if GetRawKeyState(87) = 0
Entity_SetState(ent, ENTITYSTATE_IDLE)
endif
endfunction
function Entity_StatePUSH(ent ref as _Entity)
if ent.phase = PHASE_ENTER then Entity_OnEnterState(ent)
Print("Entity is PUSHING")
// check for P key state
if GetRawKeyState(80) = 0
Entity_SetState(ent, ENTITYSTATE_IDLE)
endif
endfunction
function Entity_SetState(ent ref as _Entity, state_next as integer)
if ent.state <> state_next then Entity_OnExitState(ent)
ent.state_prev = ent.state
ent.state = state_next
ent.phase = PHASE_ENTER
endfunction
function Entity_OnEnterState(ent ref as _Entity)
select ent.state
case ENTITYSTATE_IDLE
print("Entering IDLE state...")
endcase
case ENTITYSTATE_WALK
print("Entering WALK state...")
endcase
case ENTITYSTATE_PUSH
print("Entering PUSH state...")
endcase
endselect
ent.phase = PHASE_RUN
endfunction
function Entity_OnExitState(ent ref as _Entity)
select ent.state
case ENTITYSTATE_IDLE
print("Exiting IDLE state...")
endcase
case ENTITYSTATE_WALK
print("Exiting WALK state...")
endcase
case ENTITYSTATE_PUSH
print("Exiting PUSH state...")
endcase
endselect
endfunction
myEntity as _Entity
myEntity.state = ENTITYSTATE_IDLE
do
Entity_Update(myEntity)
Sync()
`Sleep(500)
loop
In order to check how it works simply remove the rem symbol from the Sleep(500) command
I hope it will be useful to you and other newcomer members