2dAOI添加进入离开视野事件
This commit is contained in:
parent
9b86108eb8
commit
8dfbcefb64
|
@ -16,4 +16,16 @@ type AOI2D interface {
|
||||||
// SetAreaSize 设置区域大小
|
// SetAreaSize 设置区域大小
|
||||||
// - 将会导致区域的重新划分
|
// - 将会导致区域的重新划分
|
||||||
SetAreaSize(width, height int)
|
SetAreaSize(width, height int)
|
||||||
|
|
||||||
|
// RegEntityJoinVisionEvent 在新对象进入视野时将会立刻执行被注册的事件处理函数
|
||||||
|
RegEntityJoinVisionEvent(handle EntityJoinVisionEventHandle)
|
||||||
|
OnEntityJoinVisionEvent(entity, target AOIEntity2D)
|
||||||
|
// RegEntityLeaveVisionEvent 在对象离开视野时将会立刻执行被注册的事件处理函数
|
||||||
|
RegEntityLeaveVisionEvent(handle EntityLeaveVisionEventHandle)
|
||||||
|
OnEntityLeaveVisionEvent(entity, target AOIEntity2D)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type (
|
||||||
|
EntityJoinVisionEventHandle func(entity, target AOIEntity2D)
|
||||||
|
EntityLeaveVisionEventHandle func(entity, target AOIEntity2D)
|
||||||
|
)
|
||||||
|
|
|
@ -29,6 +29,9 @@ type AOI2D struct {
|
||||||
areas [][]map[int64]game.AOIEntity2D
|
areas [][]map[int64]game.AOIEntity2D
|
||||||
focus map[int64]map[int64]game.AOIEntity2D
|
focus map[int64]map[int64]game.AOIEntity2D
|
||||||
repartitionQueue []func()
|
repartitionQueue []func()
|
||||||
|
|
||||||
|
entityJoinVisionEventHandles []game.EntityJoinVisionEventHandle
|
||||||
|
entityLeaveVisionEventHandles []game.EntityLeaveVisionEventHandle
|
||||||
}
|
}
|
||||||
|
|
||||||
func (slf *AOI2D) AddEntity(entity game.AOIEntity2D) {
|
func (slf *AOI2D) AddEntity(entity game.AOIEntity2D) {
|
||||||
|
@ -77,6 +80,26 @@ func (slf *AOI2D) SetAreaSize(width, height int) {
|
||||||
slf.setAreaSize(width, height)
|
slf.setAreaSize(width, height)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (slf *AOI2D) RegEntityJoinVisionEvent(handle game.EntityJoinVisionEventHandle) {
|
||||||
|
slf.entityJoinVisionEventHandles = append(slf.entityJoinVisionEventHandles, handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *AOI2D) OnEntityJoinVisionEvent(entity, target game.AOIEntity2D) {
|
||||||
|
for _, handle := range slf.entityJoinVisionEventHandles {
|
||||||
|
handle(entity, target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *AOI2D) RegEntityLeaveVisionEvent(handle game.EntityLeaveVisionEventHandle) {
|
||||||
|
slf.entityLeaveVisionEventHandles = append(slf.entityLeaveVisionEventHandles, handle)
|
||||||
|
}
|
||||||
|
|
||||||
|
func (slf *AOI2D) OnEntityLeaveVisionEvent(entity, target game.AOIEntity2D) {
|
||||||
|
for _, handle := range slf.entityLeaveVisionEventHandles {
|
||||||
|
handle(entity, target)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func (slf *AOI2D) setAreaSize(width, height int) {
|
func (slf *AOI2D) setAreaSize(width, height int) {
|
||||||
|
|
||||||
// 旧分区备份
|
// 旧分区备份
|
||||||
|
@ -143,6 +166,7 @@ func (slf *AOI2D) addEntity(entity game.AOIEntity2D) {
|
||||||
slf.focus[guid] = focus
|
slf.focus[guid] = focus
|
||||||
slf.rangeVisionAreaEntities(entity, func(eg int64, e game.AOIEntity2D) {
|
slf.rangeVisionAreaEntities(entity, func(eg int64, e game.AOIEntity2D) {
|
||||||
focus[eg] = e
|
focus[eg] = e
|
||||||
|
slf.OnEntityJoinVisionEvent(entity, e)
|
||||||
slf.refresh(e)
|
slf.refresh(e)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -160,9 +184,10 @@ func (slf *AOI2D) refresh(entity game.AOIEntity2D) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
slf.rangeVisionAreaEntities(entity, func(guid int64, entity game.AOIEntity2D) {
|
slf.rangeVisionAreaEntities(entity, func(guid int64, e game.AOIEntity2D) {
|
||||||
if _, exist := focus[guid]; !exist {
|
if _, exist := focus[guid]; !exist {
|
||||||
focus[guid] = entity
|
focus[guid] = e
|
||||||
|
slf.OnEntityJoinVisionEvent(entity, e)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -192,7 +217,6 @@ func (slf *AOI2D) rangeVisionAreaEntities(entity game.AOIEntity2D, handle func(g
|
||||||
for h := sh; h <= heightArea+heightSpan; h++ {
|
for h := sh; h <= heightArea+heightSpan; h++ {
|
||||||
var areaX, areaY float64
|
var areaX, areaY float64
|
||||||
if w < widthArea {
|
if w < widthArea {
|
||||||
// H同理,直接使用 float64((w + 1) * 100) 会导致 h 的值被加1(why?)
|
|
||||||
tempW := w + 1
|
tempW := w + 1
|
||||||
areaX = float64(tempW * int(slf.areaWidth))
|
areaX = float64(tempW * int(slf.areaWidth))
|
||||||
} else if w > widthArea {
|
} else if w > widthArea {
|
||||||
|
@ -229,10 +253,12 @@ func (slf *AOI2D) deleteEntity(entity game.AOIEntity2D) {
|
||||||
widthArea := int(x / slf.areaWidth)
|
widthArea := int(x / slf.areaWidth)
|
||||||
heightArea := int(y / slf.areaHeight)
|
heightArea := int(y / slf.areaHeight)
|
||||||
guid := entity.GetGuid()
|
guid := entity.GetGuid()
|
||||||
delete(slf.areas[widthArea][heightArea], guid)
|
|
||||||
focus := slf.focus[guid]
|
focus := slf.focus[guid]
|
||||||
for g := range focus {
|
for g, e := range focus {
|
||||||
|
slf.OnEntityLeaveVisionEvent(entity, e)
|
||||||
|
slf.OnEntityLeaveVisionEvent(e, entity)
|
||||||
delete(slf.focus[g], guid)
|
delete(slf.focus[g], guid)
|
||||||
}
|
}
|
||||||
delete(slf.focus, guid)
|
delete(slf.focus, guid)
|
||||||
|
delete(slf.areas[widthArea][heightArea], guid)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue