Repos / shark / 5b6a41ef55
commit 5b6a41ef55396832d58259c39b69072dd5f7b623
Author: Nhân <hi@imnhan.com>
Date: Sun Sep 17 12:37:32 2023 +0700
initial move to proper state machine: idle anim
diff --git a/main.go b/main.go
index 51dcdf5..aefab9e 100644
--- a/main.go
+++ b/main.go
@@ -285,7 +285,7 @@ func main() {
ebiten.SetWindowIcon([]image.Image{AppIcon})
must.Zero(ebiten.RunGameWithOptions(
- &game,
+ NewStateMachine(),
&ebiten.RunGameOptions{ScreenTransparent: true},
))
}
diff --git a/states.go b/states.go
new file mode 100644
index 0000000..3c333db
--- /dev/null
+++ b/states.go
@@ -0,0 +1,72 @@
+package main
+
+import (
+ "github.com/hajimehoshi/ebiten/v2"
+)
+
+type StateMachine struct {
+ state State
+ anim *Anim
+ animFrameCount int // number of frames in current anim
+ frameIdx int // frame index in current animation
+ ticks int // ticks since last animation frame change
+}
+
+func NewStateMachine() *StateMachine {
+ sm := StateMachine{state: StateIdle{}}
+ sm.state.Enter(&sm)
+ return &sm
+}
+
+func (sm *StateMachine) setAnim(anim *Anim) {
+ sm.anim = anim
+ sm.animFrameCount = len(anim.Frames)
+}
+func (sm *StateMachine) Frame() *ebiten.Image {
+ return sm.anim.Frames[sm.frameIdx]
+}
+
+func (sm *StateMachine) HandleInput() {
+ sm.state.HandleInput(sm)
+}
+func (sm *StateMachine) Update() error {
+ sm.state.Update(sm)
+
+ // Advance or reset animation frame
+ sm.ticks += 1
+ if sm.ticks < 10 {
+ return nil
+ }
+ sm.ticks = 0
+ if sm.frameIdx >= sm.animFrameCount-1 {
+ sm.frameIdx = 0
+ } else {
+ sm.frameIdx += 1
+ }
+ return nil
+}
+
+func (sm *StateMachine) Draw(screen *ebiten.Image) {
+ screen.DrawImage(sm.Frame(), nil)
+}
+func (sm *StateMachine) Layout(ow, oh int) (sw, sh int) {
+ return SPRITE_X, SPRITE_Y
+}
+
+type State interface {
+ Enter(sm *StateMachine)
+ HandleInput(sm *StateMachine)
+ Update(sm *StateMachine)
+}
+
+type StateIdle struct{}
+type StateDrag struct{}
+type StateRClick struct{}
+type StateHungry struct{}
+type StateFeed struct{}
+type StateWalkL struct{}
+type StateWalkR struct{}
+
+func (s StateIdle) Enter(sm *StateMachine) { sm.setAnim(Idle) }
+func (s StateIdle) HandleInput(sm *StateMachine) {}
+func (s StateIdle) Update(sm *StateMachine) {}