diff --git a/component/components/moving2d_example_test.go b/component/components/moving2d_example_test.go deleted file mode 100644 index 52f44c0..0000000 --- a/component/components/moving2d_example_test.go +++ /dev/null @@ -1,72 +0,0 @@ -package components_test - -import ( - "fmt" - "github.com/kercylan98/minotaur/component" - "github.com/kercylan98/minotaur/component/components" - "sync" - "time" -) - -func ExampleNewMoving2D() { - moving := components.NewMoving2D() - defer func() { - moving.Release() - }() - fmt.Println(moving != nil) - - // Output: - // true -} - -func ExampleMoving2D_MoveTo() { - moving := components.NewMoving2D(components.WithMoving2DTimeUnit(time.Second)) - defer func() { - moving.Release() - }() - - var wait sync.WaitGroup - moving.RegPosition2DDestinationEvent(func(moving component.Moving2D, entity component.Moving2DEntity) { - fmt.Println("done") - wait.Done() - }) - - wait.Add(1) - entity := NewEntity(1, 100) - moving.MoveTo(entity, 50, 30) - - wait.Wait() - - // Output: - // done -} - -func ExampleMoving2D_StopMove() { - moving := components.NewMoving2D(components.WithMoving2DTimeUnit(time.Second)) - defer func() { - moving.Release() - }() - - var wait sync.WaitGroup - moving.RegPosition2DChangeEvent(func(moving component.Moving2D, entity component.Moving2DEntity, oldX, oldY float64) { - fmt.Println("move") - }) - moving.RegPosition2DStopMoveEvent(func(moving component.Moving2D, entity component.Moving2DEntity) { - fmt.Println("stop") - wait.Done() - }) - moving.RegPosition2DDestinationEvent(func(moving component.Moving2D, entity component.Moving2DEntity) { - fmt.Println("done") - wait.Done() - }) - - wait.Add(1) - entity := NewEntity(1, 100) - moving.MoveTo(entity, 50, 300) - moving.StopMove(1) - - wait.Wait() - - // Output: - // stop -} diff --git a/component/components/moving2d_options.go b/component/components/moving2d_options.go deleted file mode 100644 index f7ac6d8..0000000 --- a/component/components/moving2d_options.go +++ /dev/null @@ -1,34 +0,0 @@ -package components - -import ( - "errors" - "time" -) - -type Moving2DOption func(moving *Moving2D) - -// WithMoving2DTimeUnit 通过特定时间单位创建 -// - 默认单位为1毫秒,最小单位也为1毫秒 -func WithMoving2DTimeUnit(duration time.Duration) Moving2DOption { - return func(moving *Moving2D) { - if duration < time.Millisecond { - panic(errors.New("time unit milliseconds minimum")) - } - moving.timeUnit = float64(duration) - } -} - -// WithMoving2DIdleWaitTime 通过特定的空闲等待时间创建 -// - 默认情况下在没有新的移动计划时将限制 100毫秒 + 移动间隔事件(默认100毫秒) -func WithMoving2DIdleWaitTime(duration time.Duration) Moving2DOption { - return func(moving *Moving2D) { - moving.idle = duration - } -} - -// WithMoving2DInterval 通过特定的移动间隔时间创建 -func WithMoving2DInterval(duration time.Duration) Moving2DOption { - return func(moving *Moving2D) { - moving.interval = duration - } -} diff --git a/component/moving2d.go b/component/moving2d.go deleted file mode 100644 index a06f52a..0000000 --- a/component/moving2d.go +++ /dev/null @@ -1,23 +0,0 @@ -package component - -// Moving2D 2D移动功能接口定义 -type Moving2D interface { - // MoveTo 设置对象移动至特定位置 - MoveTo(entity Moving2DEntity, x float64, y float64) - // StopMove 终止特定对象的移动 - StopMove(guid int64) - - // RegPosition2DChangeEvent 对象位置改变时将立即执行被注册的事件处理函数 - RegPosition2DChangeEvent(handle Position2DChangeEventHandle) - OnPosition2DChangeEvent(entity Moving2DEntity, oldX, oldY float64) - - // RegPosition2DDestinationEvent 对象抵达终点时将立即执行被注册的事件处理函数 - RegPosition2DDestinationEvent(handle Position2DDestinationEventHandle) - OnPosition2DDestinationEvent(entity Moving2DEntity) -} - -type ( - Position2DChangeEventHandle func(moving Moving2D, entity Moving2DEntity, oldX, oldY float64) - Position2DDestinationEventHandle func(moving Moving2D, entity Moving2DEntity) - Position2DStopMoveEventHandle func(moving Moving2D, entity Moving2DEntity) -) diff --git a/component/components/moving2d.go b/game/moving/2d.go similarity index 67% rename from component/components/moving2d.go rename to game/moving/2d.go index a1dcaff..83e7b8d 100644 --- a/component/components/moving2d.go +++ b/game/moving/2d.go @@ -1,15 +1,14 @@ -package components +package moving import ( - "github.com/kercylan98/minotaur/component" "github.com/kercylan98/minotaur/utils/geometry" "sync" "time" ) -// NewMoving2D 创建一个用于2D对象移动的实例(Moving2D) -func NewMoving2D(options ...Moving2DOption) *Moving2D { - moving2D := &Moving2D{ +// NewTwoDimensional 创建一个用于2D对象移动的实例(TwoDimensional) +func NewTwoDimensional(options ...TwoDimensionalOption) *TwoDimensional { + moving2D := &TwoDimensional{ entities: map[int64]*moving2DTarget{}, timeUnit: float64(time.Millisecond), idle: time.Millisecond * 100, @@ -22,11 +21,11 @@ func NewMoving2D(options ...Moving2DOption) *Moving2D { return moving2D } -// Moving2D 用于2D对象移动的数据结构 +// TwoDimensional 用于2D对象移动的数据结构 // - 通过对象调用 MoveTo 方法后将开始执行该对象的移动 -// - 移动将在根据设置的每次移动间隔时间(WithMoving2DInterval)进行移动,当无对象移动需要移动时将会进入短暂的休眠 +// - 移动将在根据设置的每次移动间隔时间(WithTwoDimensionalInterval)进行移动,当无对象移动需要移动时将会进入短暂的休眠 // - 当对象移动速度永久为0时,将会导致永久无法完成的移动 -type Moving2D struct { +type TwoDimensional struct { rw sync.RWMutex entities map[int64]*moving2DTarget timeUnit float64 @@ -34,13 +33,13 @@ type Moving2D struct { interval time.Duration close bool - position2DChangeEventHandles []component.Position2DChangeEventHandle - position2DDestinationEventHandles []component.Position2DDestinationEventHandle - position2DStopMoveEventHandles []component.Position2DStopMoveEventHandle + position2DChangeEventHandles []Position2DChangeEventHandle + position2DDestinationEventHandles []Position2DDestinationEventHandle + position2DStopMoveEventHandles []Position2DStopMoveEventHandle } // MoveTo 设置对象移动到特定位置 -func (slf *Moving2D) MoveTo(entity component.Moving2DEntity, x float64, y float64) { +func (slf *TwoDimensional) MoveTo(entity TwoDimensionalEntity, x float64, y float64) { guid := entity.GetGuid() current := time.Now().UnixMilli() slf.rw.Lock() @@ -51,10 +50,10 @@ func (slf *Moving2D) MoveTo(entity component.Moving2DEntity, x float64, y float6 entityTarget, exist := slf.entities[guid] if !exist { entityTarget = &moving2DTarget{ - Moving2DEntity: entity, - x: x, - y: y, - lastMoveTime: current, + TwoDimensionalEntity: entity, + x: x, + y: y, + lastMoveTime: current, } slf.entities[guid] = entityTarget return @@ -65,7 +64,7 @@ func (slf *Moving2D) MoveTo(entity component.Moving2DEntity, x float64, y float6 } // StopMove 停止特定对象的移动 -func (slf *Moving2D) StopMove(guid int64) { +func (slf *TwoDimensional) StopMove(guid int64) { slf.rw.Lock() defer slf.rw.Unlock() entity, exist := slf.entities[guid] @@ -76,52 +75,52 @@ func (slf *Moving2D) StopMove(guid int64) { } // RegPosition2DChangeEvent 在对象位置改变时将执行注册的事件处理函数 -func (slf *Moving2D) RegPosition2DChangeEvent(handle component.Position2DChangeEventHandle) { +func (slf *TwoDimensional) RegPosition2DChangeEvent(handle Position2DChangeEventHandle) { slf.position2DChangeEventHandles = append(slf.position2DChangeEventHandles, handle) } -func (slf *Moving2D) OnPosition2DChangeEvent(entity component.Moving2DEntity, oldX, oldY float64) { +func (slf *TwoDimensional) OnPosition2DChangeEvent(entity TwoDimensionalEntity, oldX, oldY float64) { for _, handle := range slf.position2DChangeEventHandles { handle(slf, entity, oldX, oldY) } } // RegPosition2DDestinationEvent 在对象到达终点时将执行被注册的事件处理函数 -func (slf *Moving2D) RegPosition2DDestinationEvent(handle component.Position2DDestinationEventHandle) { +func (slf *TwoDimensional) RegPosition2DDestinationEvent(handle Position2DDestinationEventHandle) { slf.position2DDestinationEventHandles = append(slf.position2DDestinationEventHandles, handle) } -func (slf *Moving2D) OnPosition2DDestinationEvent(entity component.Moving2DEntity) { +func (slf *TwoDimensional) OnPosition2DDestinationEvent(entity TwoDimensionalEntity) { for _, handle := range slf.position2DDestinationEventHandles { handle(slf, entity) } } // RegPosition2DStopMoveEvent 在对象停止移动时将执行被注册的事件处理函数 -func (slf *Moving2D) RegPosition2DStopMoveEvent(handle component.Position2DStopMoveEventHandle) { +func (slf *TwoDimensional) RegPosition2DStopMoveEvent(handle Position2DStopMoveEventHandle) { slf.position2DStopMoveEventHandles = append(slf.position2DStopMoveEventHandles, handle) } -func (slf *Moving2D) OnPosition2DStopMoveEvent(entity component.Moving2DEntity) { +func (slf *TwoDimensional) OnPosition2DStopMoveEvent(entity TwoDimensionalEntity) { for _, handle := range slf.position2DStopMoveEventHandles { handle(slf, entity) } } type moving2DTarget struct { - component.Moving2DEntity + TwoDimensionalEntity x, y float64 lastMoveTime int64 } // Release 释放对象移动对象所占用的资源 -func (slf *Moving2D) Release() { +func (slf *TwoDimensional) Release() { slf.rw.Lock() defer slf.rw.Unlock() slf.close = true } -func (slf *Moving2D) handle() { +func (slf *TwoDimensional) handle() { for { slf.rw.Lock() if slf.close { diff --git a/component/moving2d_entity.go b/game/moving/2d_entity.go similarity index 59% rename from component/moving2d_entity.go rename to game/moving/2d_entity.go index 9b761ef..aa7670c 100644 --- a/component/moving2d_entity.go +++ b/game/moving/2d_entity.go @@ -1,9 +1,9 @@ -package component +package moving import "github.com/kercylan98/minotaur/game" -// Moving2DEntity 2D移动对象接口定义 -type Moving2DEntity interface { +// TwoDimensionalEntity 2D移动对象接口定义 +type TwoDimensionalEntity interface { game.Actor game.Position2D game.Position2DSet diff --git a/game/moving/2d_events.go b/game/moving/2d_events.go new file mode 100644 index 0000000..63cb19c --- /dev/null +++ b/game/moving/2d_events.go @@ -0,0 +1,7 @@ +package moving + +type ( + Position2DChangeEventHandle func(moving *TwoDimensional, entity TwoDimensionalEntity, oldX, oldY float64) + Position2DDestinationEventHandle func(moving *TwoDimensional, entity TwoDimensionalEntity) + Position2DStopMoveEventHandle func(moving *TwoDimensional, entity TwoDimensionalEntity) +) diff --git a/game/moving/2d_example_test.go b/game/moving/2d_example_test.go new file mode 100644 index 0000000..df3840c --- /dev/null +++ b/game/moving/2d_example_test.go @@ -0,0 +1,71 @@ +package moving_test + +import ( + "fmt" + "github.com/kercylan98/minotaur/game/moving" + "sync" + "time" +) + +func ExampleNewTwoDimensional() { + m := moving.NewTwoDimensional() + defer func() { + m.Release() + }() + fmt.Println(m != nil) + + // Output: + // true +} + +func ExampleTwoDimensional_MoveTo() { + m := moving.NewTwoDimensional(moving.WithTwoDimensionalTimeUnit(time.Second)) + defer func() { + m.Release() + }() + + var wait sync.WaitGroup + m.RegPosition2DDestinationEvent(func(moving *moving.TwoDimensional, entity moving.TwoDimensionalEntity) { + fmt.Println("done") + wait.Done() + }) + + wait.Add(1) + entity := NewEntity(1, 100) + m.MoveTo(entity, 50, 30) + + wait.Wait() + + // Output: + // done +} + +func ExampleTwoDimensional_StopMove() { + m := moving.NewTwoDimensional(moving.WithTwoDimensionalTimeUnit(time.Second)) + defer func() { + m.Release() + }() + + var wait sync.WaitGroup + m.RegPosition2DChangeEvent(func(moving *moving.TwoDimensional, entity moving.TwoDimensionalEntity, oldX, oldY float64) { + fmt.Println("move") + }) + m.RegPosition2DStopMoveEvent(func(moving *moving.TwoDimensional, entity moving.TwoDimensionalEntity) { + fmt.Println("stop") + wait.Done() + }) + m.RegPosition2DDestinationEvent(func(moving *moving.TwoDimensional, entity moving.TwoDimensionalEntity) { + fmt.Println("done") + wait.Done() + }) + + wait.Add(1) + entity := NewEntity(1, 100) + m.MoveTo(entity, 50, 300) + m.StopMove(1) + + wait.Wait() + + // Output: + // stop +} diff --git a/game/moving/2d_options.go b/game/moving/2d_options.go new file mode 100644 index 0000000..9300d73 --- /dev/null +++ b/game/moving/2d_options.go @@ -0,0 +1,34 @@ +package moving + +import ( + "errors" + "time" +) + +type TwoDimensionalOption func(moving *TwoDimensional) + +// WithTwoDimensionalTimeUnit 通过特定时间单位创建 +// - 默认单位为1毫秒,最小单位也为1毫秒 +func WithTwoDimensionalTimeUnit(duration time.Duration) TwoDimensionalOption { + return func(moving *TwoDimensional) { + if duration < time.Millisecond { + panic(errors.New("time unit milliseconds minimum")) + } + moving.timeUnit = float64(duration) + } +} + +// WithTwoDimensionalIdleWaitTime 通过特定的空闲等待时间创建 +// - 默认情况下在没有新的移动计划时将限制 100毫秒 + 移动间隔事件(默认100毫秒) +func WithTwoDimensionalIdleWaitTime(duration time.Duration) TwoDimensionalOption { + return func(moving *TwoDimensional) { + moving.idle = duration + } +} + +// WithTwoDimensionalInterval 通过特定的移动间隔时间创建 +func WithTwoDimensionalInterval(duration time.Duration) TwoDimensionalOption { + return func(moving *TwoDimensional) { + moving.interval = duration + } +} diff --git a/component/components/moving2d_test.go b/game/moving/2d_test.go similarity index 61% rename from component/components/moving2d_test.go rename to game/moving/2d_test.go index c8eea13..9ad79c3 100644 --- a/component/components/moving2d_test.go +++ b/game/moving/2d_test.go @@ -1,9 +1,8 @@ -package components_test +package moving_test import ( "fmt" - "github.com/kercylan98/minotaur/component" - "github.com/kercylan98/minotaur/component/components" + "github.com/kercylan98/minotaur/game/moving" "sync" "testing" "time" @@ -41,30 +40,30 @@ func NewEntity(guid int64, speed float64) *MoveEntity { } } -func TestNewMoving2D(t *testing.T) { - moving := components.NewMoving2D() +func TestNewTwoDimensional(t *testing.T) { + m := moving.NewTwoDimensional() defer func() { - moving.Release() + m.Release() }() } -func TestMoving2D_StopMove(t *testing.T) { +func TestTwoDimensional_StopMove(t *testing.T) { var wait sync.WaitGroup - moving := components.NewMoving2D(components.WithMoving2DTimeUnit(time.Second)) + m := moving.NewTwoDimensional(moving.WithTwoDimensionalTimeUnit(time.Second)) defer func() { - moving.Release() + m.Release() }() - moving.RegPosition2DChangeEvent(func(moving component.Moving2D, entity component.Moving2DEntity, oldX, oldY float64) { + m.RegPosition2DChangeEvent(func(moving *moving.TwoDimensional, entity moving.TwoDimensionalEntity, oldX, oldY float64) { x, y := entity.GetPosition() fmt.Println(fmt.Sprintf("%d : %d | %f, %f > %f, %f", entity.GetGuid(), time.Now().UnixMilli(), oldX, oldY, x, y)) }) - moving.RegPosition2DDestinationEvent(func(moving component.Moving2D, entity component.Moving2DEntity) { + m.RegPosition2DDestinationEvent(func(moving *moving.TwoDimensional, entity moving.TwoDimensionalEntity) { fmt.Println(fmt.Sprintf("%d : %d | destination", entity.GetGuid(), time.Now().UnixMilli())) wait.Done() }) - moving.RegPosition2DStopMoveEvent(func(moving component.Moving2D, entity component.Moving2DEntity) { + m.RegPosition2DStopMoveEvent(func(moving *moving.TwoDimensional, entity moving.TwoDimensionalEntity) { fmt.Println(fmt.Sprintf("%d : %d | stop", entity.GetGuid(), time.Now().UnixMilli())) wait.Done() }) @@ -72,13 +71,13 @@ func TestMoving2D_StopMove(t *testing.T) { for i := 0; i < 10; i++ { wait.Add(1) entity := NewEntity(int64(i)+1, float64(10+i)) - moving.MoveTo(entity, 50, 30) + m.MoveTo(entity, 50, 30) } time.Sleep(time.Second * 1) for i := 0; i < 10; i++ { - moving.StopMove(int64(i) + 1) + m.StopMove(int64(i) + 1) } wait.Wait()