• 3.4 求出九宫格
    • A)根据格子ID求出九宫格
    • B)根据坐标求出九宫格

    3.4 求出九宫格

    A)根据格子ID求出九宫格

    现在我们根据格子IDgid求出周边的格子有哪些?

    我们可能要考虑一些情况,比如格子的四周都有,如下图:

     3.4 求出九宫格  - 图1或者,格子所在AOI区域的四个顶角,如下图:

     3.4 求出九宫格  - 图2或者给所在AOI边界,周边的格子缺少一列,或者缺少一行。

    思考一下,我们是否可以想一个统一的方法,将所有的条件都满足。

    如果求出一个gid的周边九宫格,那么可以先算出该gid所处一行左边和右边是否有,然后在分别计算这一行的上边和下边的格子是否有,就可以了。

    思路如下:

     3.4 求出九宫格  - 图3 3.4 求出九宫格  - 图4 3.4 求出九宫格  - 图5参考代码如下:

    mmo_game/core/aoi.go

    1. //根据格子的gID得到当前周边的九宫格信息
    2. func (m *AOIManager) GetSurroundGridsByGid(gID int) (grids []*Grid) {
    3. //判断gID是否存在
    4. if _, ok := m.grids[gID]; !ok {
    5. return
    6. }
    7. //将当前gid添加到九宫格中
    8. grids = append(grids, m.grids[gID])
    9. //根据gid得到当前格子所在的X轴编号
    10. idx := gID % m.CntsX
    11. //判断当前idx左边是否还有格子
    12. if idx > 0 {
    13. grids = append(grids, m.grids[gID-1])
    14. }
    15. //判断当前的idx右边是否还有格子
    16. if idx < m.CntsX - 1 {
    17. grids = append(grids, m.grids[gID+1])
    18. }
    19. //将x轴当前的格子都取出,进行遍历,再分别得到每个格子的上下是否有格子
    20. //得到当前x轴的格子id集合
    21. gidsX := make([]int, 0, len(grids))
    22. for _, v := range grids {
    23. gidsX = append(gidsX, v.GID)
    24. }
    25. //遍历x轴格子
    26. for _, v := range gidsX {
    27. //计算该格子处于第几列
    28. idy := v / m.CntsX
    29. //判断当前的idy上边是否还有格子
    30. if idy > 0 {
    31. grids = append(grids, m.grids[v-m.CntsX])
    32. }
    33. //判断当前的idy下边是否还有格子
    34. if idy < m.CntsY - 1 {
    35. grids = append(grids, m.grids[v+m.CntsX])
    36. }
    37. }
    38. return
    39. }
    B)根据坐标求出九宫格

    还有一种情况是玩家只知道自己的坐标,那么如何确定玩家AOI九宫格的区域都有哪些玩家呢,那就需要设计一个根据坐标求出周边九宫格中玩家的接口。

     3.4 求出九宫格  - 图6我们首先应该根据坐标得到所属的格子ID,然后再走根据格子ID获取九宫格信息就可以了。

    mmo_game/core/aoi.go

    1. //通过横纵坐标获取对应的格子ID
    2. func (m *AOIManager) GetGIDByPos(x, y float32) int {
    3. gx := (int(x) - m.MinX) / m.gridWidth()
    4. gy := (int(x) - m.MinY) / m.gridLength()
    5. return gy * m.CntsX + gx
    6. }
    7. //通过横纵坐标得到周边九宫格内的全部PlayerIDs
    8. func (m *AOIManager) GetPIDsByPos(x, y float32) (playerIDs []int) {
    9. //根据横纵坐标得到当前坐标属于哪个格子ID
    10. gID := m.GetGIDByPos(x, y)
    11. //根据格子ID得到周边九宫格的信息
    12. grids := m.GetSurroundGridsByGid(gID)
    13. for _, v := range grids {
    14. playerIDs = append(playerIDs, v.GetPlyerIDs()...)
    15. fmt.Printf("===> grid ID : %d, pids : %v ====", v.GID, v.GetPlyerIDs())
    16. }
    17. return
    18. }