Go語言模擬玩家移動

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,
   }
}


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章