| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200 |
- package mapAOI
- import (
- aoiTower "f1-game/internal/algorithm/aoi_tower"
- "f1-game/internal/enum"
- nameRemote "f1-game/internal/name/remote"
- mapCall "f1-game/nodes/map/internal/call"
- mapTypes "f1-game/nodes/map/internal/types"
- "time"
- clog "github.com/cherry-game/cherry/logger"
- cactor "github.com/cherry-game/cherry/net/actor"
- )
- // TODO 待重构:不要绑定死 actorBase 与 objectType
- // actorBase 实现为通用方法集合,在每一层 AOI 中做定制化调用
- // 每一层 AOI 各自做实现,这样可以灵活地把多种不同的对象放在一起,比如:行军对象和军团对象
- type actorBase struct {
- cactor.Base
- aoi *aoiTower.AOI
- aoiUpdateTime time.Duration
- objectType enum.ObjectType
- printLog bool
- }
- func newActorAOIBase(objectType enum.ObjectType, aoi *aoiTower.AOI, aoiUpdateTime time.Duration) actorBase {
- return actorBase{
- aoi: aoi,
- aoiUpdateTime: aoiUpdateTime,
- objectType: objectType,
- }
- }
- func (p *actorBase) OnInit() {
- p.Remote().Register(nameRemote.MapAOI_Enter, p.enter)
- p.Remote().Register(nameRemote.MapAOI_Move, p.move)
- p.Remote().Register(nameRemote.MapAOI_Leave, p.leave)
- p.Remote().Register(nameRemote.MapAOI_Update, p.update)
- p.Timer().Add(p.aoiUpdateTime, p.aoiUpdate)
- p.initAOIFuncs()
- }
- func (p *actorBase) setPrintLog(printLog bool) {
- p.printLog = printLog
- }
- // enter 玩家登录进入地图
- func (p *actorBase) enter(req *mapTypes.AOIRequest) {
- if req.IsMarker() && req.ObjectType != p.objectType {
- return
- }
- object := aoiTower.NewObject(req.ObjectID, req.ObjectType, req.X, req.Y, req.IsWatcher(), req.IsMarker(), req.OwnerID())
- p.aoi.Enter(object)
- if p.printLog {
- clog.Debugf("[enter %s] object = {%s}", enum.GetObjectTypeName(p.objectType), object.Info())
- }
- }
- // move 玩家拖动屏幕
- func (p *actorBase) move(req *mapTypes.AOIRequest) {
- if req.ObjectType != enum.ObjectType_Player && req.ObjectType != p.objectType {
- return
- }
- p.aoi.Move(req.ObjectID, req.X, req.Y, time.Now().Unix())
- if p.printLog {
- clog.Debugf("[move %s] req = {%v}", enum.GetObjectTypeName(p.objectType), req)
- }
- }
- // leave 玩家下线离开
- func (p *actorBase) leave(objectID int64) {
- // TODO 需要判断,待改进
- if p.aoi.GetObject(objectID) == nil {
- return
- }
- p.aoi.Leave(objectID)
- if p.printLog {
- clog.Debugf("[leave %s] object = %d", enum.GetObjectTypeName(p.objectType), objectID)
- }
- }
- func (p *actorBase) update(req *mapTypes.AOIRequest) {
- if req.ObjectType == enum.ObjectType_Player || req.ObjectType != p.objectType {
- return
- }
- object := p.aoi.GetObject(req.ObjectID)
- if object == nil {
- return
- }
- p.aoi.UpdateID(*object, req.UpdateID(), req.FuncName())
- if p.printLog {
- clog.Debugf("[update %s] object = %d", enum.GetObjectTypeName(p.objectType), req.ObjectID)
- }
- }
- func (p *actorBase) initAOIFuncs() {
- p.aoi.OnMarkerEnter = p.onMarkerEnter
- p.aoi.OnMarkerMove = p.onMarkerMove
- p.aoi.OnMarkerLeave = p.onMarkerLeave
- p.aoi.OnMarkerUpdateID = p.onMarkerUpdateID
- p.aoi.OnWatcherEnter = p.onWatcherEnter
- p.aoi.OnWatcherMove = p.onWatcherMove
- p.aoi.OnTowerExpire = p.onTowerExpire
- }
- func (p *actorBase) aoiUpdate() {
- p.aoi.Tick(time.Now().Unix())
- }
- // marker进入的时候通知灯塔内所有watcher
- func (p *actorBase) onMarkerEnter(marker *aoiTower.Object, tower *aoiTower.Tower) {
- clog.Debugf("[onMarkerEnter] marker = (%v %s) towerId:%d", marker.ObjectID, enum.GetObjectTypeName(marker.ObjectType), tower.GetID())
- if tower.GetWatchers().IsEmpty() {
- return
- }
- mapCall.Logic.AOIMarkerEnterView(mapTypes.NewAOIMarkerEnterView(marker, tower.GetWatchers()))
- }
- // marker移动
- func (p *actorBase) onMarkerMove(marker *aoiTower.Object, newTower *aoiTower.Tower, oldTower *aoiTower.Tower) {
- clog.Debugf("[onMarkerMove] marker = (%v %s) newTowerId = %d oldTowerId = %d", marker.ObjectID, enum.GetObjectTypeName(marker.ObjectType),
- newTower.GetID(), oldTower.GetID())
- enterWatchers := aoiTower.Objects{}
- newTower.GetWatchers().Range(func(watcher *aoiTower.Object) {
- if !oldTower.GetWatchers().Contains(watcher.ObjectID) {
- // 不在watcher的视野内,视为新加入的对象
- enterWatchers.Add(watcher)
- }
- })
- if !enterWatchers.IsEmpty() {
- mapCall.Logic.AOIMarkerEnterView(mapTypes.NewAOIMarkerEnterView(marker, enterWatchers))
- }
- leaveWatchers := aoiTower.Objects{}
- oldTower.GetWatchers().Range(func(watcher *aoiTower.Object) {
- if !newTower.GetWatchers().Contains(watcher.ObjectID) {
- // 移出了视野
- leaveWatchers.Add(watcher)
- }
- })
- if !leaveWatchers.IsEmpty() {
- mapCall.Logic.AOIMarkerLeaveView(mapTypes.NewAOIMarkerLeaveView(marker, leaveWatchers))
- }
- }
- // marker退出的时候通知灯塔内所有watcher
- func (p *actorBase) onMarkerLeave(marker *aoiTower.Object, tower *aoiTower.Tower) {
- clog.Debugf("[onMarkerLeave] marker = (%v %s) towerId = %d", marker.ObjectID, enum.GetObjectTypeName(marker.ObjectType), tower.GetID())
- mapCall.Logic.AOIMarkerDespawn(mapTypes.NewAOIMarkerDespawn(marker, tower.GetWatchers()))
- }
- // marker更新通知
- func (p *actorBase) onMarkerUpdateID(marker *aoiTower.Object, tower *aoiTower.Tower, updateID uint32, funcName string) {
- clog.Debugf("[onMarkerUpdateID] marker = (%v %s) towerId = %d updateID = %d funcName = %s", marker.ObjectID, enum.GetObjectTypeName(marker.ObjectType),
- tower.GetID(), updateID, funcName)
- mapCall.Logic.AOIUpdate(funcName, mapTypes.NewAOIMarkerUpdate(marker, tower.GetWatchers(), updateID))
- }
- // watcher进入的时候推送范围内所有marker
- func (p *actorBase) onWatcherEnter(watcher *aoiTower.Object, towers aoiTower.Towers) {
- towers.Range(func(tower *aoiTower.Tower) {
- if !tower.GetMarkers().IsEmpty() {
- mapCall.Logic.AOIMarkerEnterView(mapTypes.NewBatchAOMarkerEnterView(tower.GetMarkers(), p.objectType, watcher.OwnerID()))
- }
- })
- }
- // watcher移动时的新灯塔内对象全视为新加入对象,因为延迟删除所以不需要处理oldTowers
- func (p *actorBase) onWatcherMove(watcher *aoiTower.Object, newTowers aoiTower.Towers, oldTowers aoiTower.Towers) {
- newTowers.Range(func(tower *aoiTower.Tower) {
- if !tower.GetMarkers().IsEmpty() {
- mapCall.Logic.AOIMarkerEnterView(mapTypes.NewBatchAOMarkerEnterView(tower.GetMarkers(), p.objectType, watcher.OwnerID()))
- }
- })
- }
- // 灯塔过期
- func (p *actorBase) onTowerExpire(watcher *aoiTower.Object, tower *aoiTower.Tower) {
- clog.Debugf("[onTowerExpire] watcher = %v towerId = %d", watcher.ObjectID, tower.GetID())
- if tower.GetMarkers().IsEmpty() {
- return
- }
- // 移出了视野
- mapCall.Logic.AOIMarkerLeaveView(mapTypes.NewBatchAOIMarkerLeaveView(tower.GetMarkers(), p.objectType, watcher.OwnerID()))
- }
|