From 5a6abb199acf8cbbc089f15c38795ff1d73db866 Mon Sep 17 00:00:00 2001 From: kercylan98 Date: Sat, 3 Jun 2023 15:33:44 +0800 Subject: [PATCH] =?UTF-8?q?=E7=A7=BB=E5=8A=A8=E5=8A=9F=E8=83=BD=E4=BC=98?= =?UTF-8?q?=E5=8C=96=EF=BC=8C=E7=A7=BB=E5=8A=A8=E8=80=97=E6=97=B6bug?= =?UTF-8?q?=E9=97=AE=E9=A2=98=E5=A4=84=E7=90=86=EF=BC=8C=E6=B5=8B=E8=AF=95?= =?UTF-8?q?=E5=87=BD=E6=95=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- game/builtin/moving2d.go | 28 ++++++------- game/builtin/moving2d_options.go | 9 ++++- game/builtin/moving2d_test.go | 68 ++++++++++++++++++++++++++++++++ 3 files changed, 88 insertions(+), 17 deletions(-) create mode 100644 game/builtin/moving2d_test.go diff --git a/game/builtin/moving2d.go b/game/builtin/moving2d.go index a40ab63..fcd205a 100644 --- a/game/builtin/moving2d.go +++ b/game/builtin/moving2d.go @@ -12,17 +12,12 @@ func NewMoving2D(options ...Moving2DOption) *Moving2D { entities: map[int64]*moving2DTarget{}, timeUnit: float64(time.Millisecond), idle: time.Millisecond * 100, - event: make(chan func(), 1000), + interval: time.Millisecond * 100, } for _, option := range options { option(moving2D) } go moving2D.handle() - go func() { - for event := range moving2D.event { - event() - } - }() return moving2D } @@ -31,6 +26,7 @@ type Moving2D struct { entities map[int64]*moving2DTarget timeUnit float64 idle time.Duration + interval time.Duration event chan func() close bool @@ -114,25 +110,25 @@ func (slf *Moving2D) handle() { angle := g2d.CalcAngle(x, y, entity.x, entity.y) moveTime := time.Now().UnixMilli() interval := float64(moveTime - entity.lastMoveTime) + if interval == 0 { + continue + } distance := g2d.CalcDistance(x, y, entity.x, entity.y) - moveDistance := interval * entity.GetSpeed() / slf.timeUnit - if moveDistance > distance || (x == entity.x && y == entity.y) { + moveDistance := interval * (entity.GetSpeed() / (slf.timeUnit / 1000 / 1000)) + if moveDistance >= distance || (x == entity.x && y == entity.y) { entity.SetPosition(entity.x, entity.y) delete(slf.entities, guid) - slf.event <- func() { - slf.OnPosition2DDestinationEvent(entity) - } - return + slf.OnPosition2DDestinationEvent(entity) + continue } else { - nx, ny := g2d.CalculateNewCoordinate(x, y, angle, distance) + nx, ny := g2d.CalculateNewCoordinate(x, y, angle, moveDistance) entity.SetPosition(nx, ny) entity.lastMoveTime = moveTime - slf.event <- func() { - slf.OnPosition2DChangeEvent(entity, x, y) - } + slf.OnPosition2DChangeEvent(entity, x, y) } } + time.Sleep(slf.interval) if len(slf.entities) == 0 { slf.rw.Unlock() time.Sleep(slf.idle) diff --git a/game/builtin/moving2d_options.go b/game/builtin/moving2d_options.go index e4bf16d..85a99c4 100644 --- a/game/builtin/moving2d_options.go +++ b/game/builtin/moving2d_options.go @@ -19,9 +19,16 @@ func WithMoving2DTimeUnit(duration time.Duration) Moving2DOption { } // WithMoving2DIdleWaitTime 通过特定的空闲等待时间创建 -// - 默认情况下在没有新的移动计划时将限制 100 毫秒 +// - 默认情况下在没有新的移动计划时将限制 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/game/builtin/moving2d_test.go b/game/builtin/moving2d_test.go new file mode 100644 index 0000000..2f96608 --- /dev/null +++ b/game/builtin/moving2d_test.go @@ -0,0 +1,68 @@ +package builtin + +import ( + "fmt" + "github.com/kercylan98/minotaur/game" + "sync" + "testing" + "time" +) + +type MoveEntity struct { + guid int64 + x, y float64 + speed float64 +} + +func (slf *MoveEntity) SetGuid(guid int64) { +} + +func (slf *MoveEntity) GetGuid() int64 { + return slf.guid +} + +func (slf *MoveEntity) GetPosition() (x, y float64) { + return slf.x, slf.y +} + +func (slf *MoveEntity) SetPosition(x, y float64) { + slf.x, slf.y = x, y +} + +func (slf *MoveEntity) GetSpeed() float64 { + return slf.speed +} + +func NewEntity(guid int64, speed float64) *MoveEntity { + return &MoveEntity{ + guid: guid, + speed: speed, + } +} + +func TestMoving2D_MoveTo(t *testing.T) { + moving := NewMoving2D(WithMoving2DTimeUnit(time.Second)) + var wait sync.WaitGroup + moving.RegPosition2DDestinationEvent(func(moving game.Moving2D, entity game.Moving2DEntity) { + wait.Done() + }) + var res []string + moving.RegPosition2DChangeEvent(func(moving game.Moving2D, entity game.Moving2DEntity, oldX, oldY float64) { + x, y := entity.GetPosition() + res = append(res, fmt.Sprintf("%d : %d | %f, %f > %f, %f", entity.GetGuid(), time.Now().UnixMilli(), oldX, oldY, x, y)) + }) + //moving.RegPosition2DChangeEvent(func(moving game.Moving2D, entity game.Moving2DEntity, oldX, oldY float64) { + // x, y := entity.GetPosition() + // fmt.Println("Moving", entity.GetGuid(), oldX, oldY, x, y) + //}) + for i := 0; i < 1; i++ { + wait.Add(1) + entity := NewEntity(int64(i)+1, float64(10+i)) + moving.MoveTo(entity, 50, 30) + } + + wait.Wait() + for _, re := range res { + fmt.Println(re) + } +}