package main import ( "fmt" "math" ) func main() { // 实例化玩家对象,并设速度为0.5 p := NewPlayer(0.5) // 让玩家移动到3,1点 p.MoveTo(Vec2{3, 1}) // 如果没有到达就一直循环 for !p.IsArrived() { // 更新玩家位置 p.Update() // 打印每次移动后的玩家位置 fmt.Println(p.Pos()) } } type Vec2 struct { X, Y float32 } // 加 func (v Vec2) Add(other Vec2) Vec2 { return Vec2{ v.X + other.X, v.Y + other.Y, } } // 减 func (v Vec2) Sub(other Vec2) Vec2 { return Vec2{ v.X - other.X, v.Y - other.Y, } } // 乘 func (v Vec2) Scale(s float32) Vec2 { return Vec2{v.X * s, v.Y * s} } // 距离 func (v Vec2) DistanceTo(other Vec2) float32 { dx := v.X - other.X dy := v.Y - other.Y return float32(math.Sqrt(float64(dx*dx + dy*dy))) } // 插值 func (v Vec2) Normalize() Vec2 { mag := v.X*v.X + v.Y*v.Y if mag > 0 { oneOverMag := 1 / float32(math.Sqrt(float64(mag))) return Vec2{v.X * oneOverMag, v.Y * oneOverMag} } return Vec2{0, 0} } type Player struct { currPos Vec2 // 当前位置 targetPos Vec2 // 目标位置 speed float32 // 移动速度 } // 移动到某个点就是设置目标位置 func (p *Player) MoveTo(v Vec2) { p.targetPos = v } // 获取当前的位置 func (p *Player) Pos() Vec2 { return p.currPos } // 是否到达 func (p *Player) IsArrived() bool { // 通过计算当前玩家位置与目标位置的距离不超过移动的步长,判断已经到达目标点 return p.currPos.DistanceTo(p.targetPos) < p.speed } // 逻辑更新 func (p *Player) Update() { if !p.IsArrived() { // 计算出当前位置指向目标的朝向 dir := p.targetPos.Sub(p.currPos).Normalize() // 添加速度矢量生成新的位置 newPos := p.currPos.Add(dir.Scale(p.speed)) // 移动完成后,更新当前位置 p.currPos = newPos } } // 创建新玩家 func NewPlayer(speed float32) *Player { return &Player{ speed: speed, } }
有疑问加站长微信联系(非本文作者)