diff --git a/_examples/stop/main.go b/_examples/stop/main.go new file mode 100644 index 0000000..f6167f1 --- /dev/null +++ b/_examples/stop/main.go @@ -0,0 +1,16 @@ +package main + +import ( + "github.com/elgopher/pi/piebiten" + "github.com/elgopher/pi/pikey" + "github.com/elgopher/pi/piloop" +) + +func main() { + // stops the game loop when user pressed Escape key + pikey.RegisterShortcut(piloop.Stop, pikey.Esc) + + piebiten.Run() // this function ends without panic once game loop is stopped + + // Code in here is executed after loop is stopped +} diff --git a/piebiten/internal/ebitengame.go b/piebiten/internal/ebitengame.go index d77b3dc..5a7bced 100644 --- a/piebiten/internal/ebitengame.go +++ b/piebiten/internal/ebitengame.go @@ -4,12 +4,13 @@ package internal import ( + "math" + "time" + "github.com/elgopher/pi/piaudio" "github.com/elgopher/pi/piebiten/internal/audio" "github.com/elgopher/pi/piebiten/internal/input" ebitenaudio "github.com/hajimehoshi/ebiten/v2/audio" - "math" - "time" "github.com/hajimehoshi/ebiten/v2" @@ -40,6 +41,7 @@ func RunEbitenGame() *EbitenGame { } pidebug.Target().SubscribeAll(game.onPidebugEvent) + piloop.Target().Subscribe(piloop.EventStop, game.onPiloopStopEvent) return game } @@ -87,9 +89,14 @@ type EbitenGame struct { inputBackend *input.Backend ebitenFrame int // frame incremented on each Ebiten tick + + stopped bool } func (g *EbitenGame) Update() error { + if g.stopped { + return ebiten.Termination + } if ebiten.IsWindowBeingClosed() { piloop.Target().Publish(piloop.EventWindowClose) return ebiten.Termination @@ -217,3 +224,7 @@ func (g *EbitenGame) onPidebugEvent(event pidebug.Event, _ pievent.Handler) { g.paused = false } } + +func (g *EbitenGame) onPiloopStopEvent(piloop.Event, pievent.Handler) { + g.stopped = true +} diff --git a/piloop/event.go b/piloop/event.go index ab6187f..98ef3bc 100644 --- a/piloop/event.go +++ b/piloop/event.go @@ -13,4 +13,5 @@ const ( EventDraw Event = "draw" // after pi.Draw EventLateDraw Event = "late_draw" // after EventDraw EventWindowClose Event = "window_close" // when a user closes the window (desktop only) + EventStop Event = "stop" // when game loop is stopped by calling piloop.Stop() ) diff --git a/piloop/piloop.go b/piloop/piloop.go index ae746e6..8e37df4 100644 --- a/piloop/piloop.go +++ b/piloop/piloop.go @@ -17,6 +17,10 @@ func DebugTarget() pievent.Target[Event] { return debugTarget } +func Stop() { + Target().Publish(EventStop) +} + var ( target = pievent.NewTarget[Event]() debugTarget = pievent.NewTarget[Event]()