From 861dd7ecefe200dd79a90b9a3fc4eb50f243def7 Mon Sep 17 00:00:00 2001 From: kercylan98 Date: Thu, 27 Apr 2023 10:49:30 +0800 Subject: [PATCH] =?UTF-8?q?=E6=B8=B8=E6=88=8F=E7=8E=A9=E6=B3=95=E6=B8=B8?= =?UTF-8?q?=E6=88=8F=E6=97=B6=E9=95=BF=E5=AE=9E=E7=8E=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game/builtin/gameplay_time.go | 67 ++++++++++++++++++++ game/builtin/gameplay_time_options.go | 30 +++++++++ game/examples/gameplay_time/gameplay_time.go | 49 ++++++++++++++ game/gameplay_time.go | 17 +++++ utils/{time => offset}/time.go | 6 +- 5 files changed, 168 insertions(+), 1 deletion(-) create mode 100644 game/builtin/gameplay_time.go create mode 100644 game/builtin/gameplay_time_options.go create mode 100644 game/examples/gameplay_time/gameplay_time.go create mode 100644 game/gameplay_time.go rename utils/{time => offset}/time.go (77%) diff --git a/game/builtin/gameplay_time.go b/game/builtin/gameplay_time.go new file mode 100644 index 0000000..5056edf --- /dev/null +++ b/game/builtin/gameplay_time.go @@ -0,0 +1,67 @@ +package builtin + +import ( + "minotaur/game" + "minotaur/utils/timer" + "time" +) + +const ( + gameplayTimeTickerEndTime = "GameplayTimeTickerEndTime" +) + +func NewGameplayTime(gameplay game.Gameplay, gameplayOver game.GameplayOver, options ...GameplayTimeOption) *GameplayTime { + gameplayTime := &GameplayTime{ + Gameplay: gameplay, + GameplayOver: gameplayOver, + } + for _, option := range options { + option(gameplayTime) + } + if gameplayTime.ticker == nil { + gameplayTime.afterName = gameplayTimeTickerEndTime + gameplayTime.ticker = timer.GetTicker(10) + } + return gameplayTime +} + +type GameplayTime struct { + game.Gameplay + game.GameplayOver + id int64 + afterName string + endTime time.Time + ticker *timer.Ticker +} + +func (slf *GameplayTime) GetEndTime() time.Time { + return slf.endTime +} + +func (slf *GameplayTime) SetEndTime(t time.Time) { + compare := t.Compare(slf.endTime) + if compare == 0 { + return + } + + slf.ticker.StopTimer(slf.afterName) + current := slf.GetCurrentTime() + if compare < 0 && t.Compare(current) < 0 { + slf.GameplayOver.GameOver() + return + } + + slf.endTime = t + slf.ticker.After(slf.afterName, slf.endTime.Sub(current), func() { + slf.GameplayOver.GameOver() + }) +} + +func (slf *GameplayTime) ChangeEndTime(d time.Duration) { + slf.SetEndTime(slf.endTime.Add(d)) +} + +func (slf *GameplayTime) Release() { + slf.ticker.Release() + slf.ticker = nil +} diff --git a/game/builtin/gameplay_time_options.go b/game/builtin/gameplay_time_options.go new file mode 100644 index 0000000..7c6f6a4 --- /dev/null +++ b/game/builtin/gameplay_time_options.go @@ -0,0 +1,30 @@ +package builtin + +import ( + "fmt" + "minotaur/utils/timer" +) + +type GameplayTimeOption func(time *GameplayTime) + +func WithGameplayTimeWheelSize(size int) GameplayTimeOption { + return func(time *GameplayTime) { + if time.ticker != nil { + time.ticker.Release() + time.id = 0 + } + time.ticker = timer.GetTicker(size) + time.afterName = gameplayTimeTickerEndTime + } +} + +func WithGameplayTimeTicker(id int64, ticker *timer.Ticker) GameplayTimeOption { + return func(time *GameplayTime) { + if time.ticker != nil { + time.ticker.Release() + } + time.id = id + time.ticker = ticker + time.afterName = fmt.Sprintf("%s_%d", gameplayTimeTickerEndTime, id) + } +} diff --git a/game/examples/gameplay_time/gameplay_time.go b/game/examples/gameplay_time/gameplay_time.go new file mode 100644 index 0000000..af61f2a --- /dev/null +++ b/game/examples/gameplay_time/gameplay_time.go @@ -0,0 +1,49 @@ +package main + +import ( + "log" + "minotaur/game" + "minotaur/game/builtin" + "sync" + "time" +) + +func NewGame() *Game { + gameplay := builtin.NewGameplay() + gameplayOver := builtin.NewGameplayOver() + return &Game{ + GameplayTime: builtin.NewGameplayTime(gameplay, gameplayOver), + } +} + +type Game struct { + game.GameplayTime + wait sync.WaitGroup +} + +func (slf *Game) init() error { + slf.wait.Add(1) + return nil +} + +func (slf *Game) onGameStart(startTime time.Time) { + log.Println("游戏开始") + slf.SetEndTime(startTime.Add(3 * time.Second)) +} + +func (slf *Game) onGameOver() { + log.Println("游戏结束") + slf.wait.Done() +} + +func main() { + g := NewGame() + g.RegGameplayStartEvent(g.onGameStart) + g.RegGameplayOverEvent(g.onGameOver) + + if err := g.GameStart(g.init); err != nil { + panic(err) + } + + g.wait.Wait() +} diff --git a/game/gameplay_time.go b/game/gameplay_time.go new file mode 100644 index 0000000..6ca8854 --- /dev/null +++ b/game/gameplay_time.go @@ -0,0 +1,17 @@ +package game + +import "time" + +// GameplayTime 为游戏玩法添加游戏时长的特性 +type GameplayTime interface { + Gameplay + GameplayOver + // GetEndTime 获取游戏结束时间 + GetEndTime() time.Time + // SetEndTime 设置游戏结束时间 + SetEndTime(t time.Time) + // ChangeEndTime 通过相对时间的方式改变游戏结束时间 + ChangeEndTime(d time.Duration) + // Release 释放资源 + Release() +} diff --git a/utils/time/time.go b/utils/offset/time.go similarity index 77% rename from utils/time/time.go rename to utils/offset/time.go index ab1671f..0967005 100644 --- a/utils/time/time.go +++ b/utils/offset/time.go @@ -1,7 +1,11 @@ -package time +package offset import "time" +func NewTime(offset time.Duration) *Time { + return &Time{offset: offset} +} + // Time 带有偏移量的时间 type Time struct { offset time.Duration