Strict
Import mojo
Const PRESS_LEFT:=$01
Const PRESS_RIGHT:=$02
Const PRESS_JUMP:=$04
Const PRESS_DUCK:=$08
Const PRESS_FIRE:=$10
Const IMAGE_STAND:=0
Const IMAGE_DUCK:=1
Function Main:Int()
New CGame()
Return 0
End Function
' Class for controller input
Class Input
Field _inputState:Int
Method Update:Void()
_inputState = 0
If KeyDown(KEY_DOWN) _inputState |= PRESS_DUCK
If KeyDown(KEY_UP) _inputState |= PRESS_JUMP
If KeyDown(KEY_LEFT) _inputState |= PRESS_LEFT
If KeyDown(KEY_RIGHT) _inputState |= PRESS_RIGHT
If KeyDown(KEY_SPACE) _inputState |= PRESS_FIRE
End Method
' Get the state of the controller
Method GetInput:Bool(input:Int)
If _inputState & input Return True
Return False
End Method
Method Draw:Void()
Select _inputState
Case PRESS_DUCK
DrawText("DUCKING",0,0)
Case PRESS_JUMP
DrawText("JUMPING",0,0)
Case PRESS_LEFT
DrawText("LEFT",0,0)
Case PRESS_RIGHT
DrawText("RIGHT",0,0)
Case PRESS_FIRE
DrawText("FIRE",0,0)
Default
DrawText("Idle",0,0)
End Select
End Method
End Class
' Base class for the state.
' The 'Global' static variables are not being used here to allow more than one player to use the states.
' It's not a good idea to try to initialise the fields in the constructor. It will be forever creating it's self.
Class HeroineState
Field standing:StandingState
Field ducking:DuckingState
Method HandleInput:Void(heroine:Heroine, input:Input)
End
Method Update:Void(heroine:Heroine)
End
' Create a new set of states and return them
Function CreateStates:HeroineState()
Local state:= New HeroineState()
state.standing = New StandingState()
state.ducking = New DuckingState()
Return state
End Function
End Class
' The state for the down key being pressed
Class DuckingState Extends HeroineState
' Over ride the HandleInput of the base class
Method HandleInput:Void(heroine:Heroine, input:Input)
' Not ducking, so back to idle
If Not(input.GetInput(PRESS_DUCK))
heroine.SetGraphic(IMAGE_STAND)
' The player object holds it's own states, so that's where to look.
heroine.state = heroine.states.standing
Endif
' Do addtional checking. For example ducked but moving in a direction.
' Set craling state etc.
' e.g.
' If input.GetInput((PRESS_DUCK|PRESS_LEFT))
' heroine.SetGraphic(IMAGE_CRAWL_LEFT)
' heroine.state = heroine.states.clawleft
' Endif
End Method
' Over ride the Update of the base class
Method Update:Void(heroine:Heroine)
' Update anything related to ducking
Print "DuckingState Update"
End Method
End Class
' The state for when no key is being pressed
Class StandingState Extends HeroineState
' Over ride the HandleInput of the base class
Method HandleInput:Void(heroine:Heroine, input:Input)
If input.GetInput(PRESS_DUCK)
heroine.SetGraphic(IMAGE_DUCK)
' The player object holds it's own states, so that's where to look.
heroine.state = heroine.states.ducking
Endif
End Method
' Over ride the Update of the base class
Method Update:Void(heroine:Heroine)
' Update anything related to standing idle
Print "StandingState Update"
End Method
End Class
' The class to represent the player
Class Heroine
Field state:HeroineState ' holds the current state object
Field graphic:Int
Field states:HeroineState ' Look up for all states.
Method New()
states = HeroineState.CreateStates() ' Initialise all the states that the player can be in
state = states.standing ' Set the starting state
End
Method HandleInput:Void(input:Input)
' Pass the players object and the current input object to
' The current state object.
state.HandleInput(Self, input)
End
Method Update:Void()
' Call the current state's update methos
state.Update(Self)
End Method
Method SetGraphic:Void(image:Int)
graphic = image
End Method
Method Draw:Void()
Select graphic
Case IMAGE_STAND
DrawRect(DeviceWidth()/2-50,DeviceHeight()/2-25, 50,100)
Case IMAGE_DUCK
DrawRect(DeviceWidth()/2-50,DeviceHeight()/2+25, 50,50)
End Select
End Method
End Class
' Main game class
Class CGame Extends App
Field player:Heroine
Field controls:Input
Method OnCreate:Int()
player = New Heroine()
controls = New Input()
Return 0
End Method
Method OnUpdate:Int()
controls.Update()
player.HandleInput(controls)
player.Update()
Return 0
End Method
Method OnRender:Int()
Cls
controls.Draw()
player.Draw()
Return 0
End Method
End Class