AOI十字链表python简单实现,仅用作学习,理解基本原理

AOI一般是C++去实现,本文章python写仅用来入门了解

场景内维护两个实体链表

list_x和list_y

所有实体根据x坐标大小排序,在list_x上
所有实体根据y坐标大小排序,在list_y上

实体位置改变时候,需要改变实体在list_x,list_x的位置

实体的AOI范围, 根据AOI半径 在list_x,list_x上遍历即可

十字链表发在计算AOI范围内对象时,计算量非常小,且跟空间大小无关,因此省去大量无效的遍历过程。十字链表法也有一些需要注意的地方,因为在两条链表中都必须按照大小顺序进行排列,因此对象在不停的移动,会带来比较大量的计算。

python版本:2.7

# coding: utf-8class Entity(object):def __init__(self, eid, x, y):self.id = eidself.x = xself.y = yself.radius = 5  # AOI半径def __str__(self):return "<{0},{1}-{2}>".format(self.id, self.x, self.y)def enter(self, pobj):print("{0} enter {1} view".format(pobj, self))def leave(self, pobj):print("{0} leave {1} view".format(pobj, self))def move(self, pobj):print("{0} move in {1} view".format(pobj, self))class Scene(object):def __init__(self):self.map_entity = {}self.list_x = []  # [实例ID] 实际应用链表 + 跳跃表self.list_y = []def __str__(self):return "<list_x: {0}, list_y: {1}, entities: {2}>".format(self.list_x, self.list_y, self.map_entity.keys())def add_by_entity(self, entity):# 添加一个新的对象self.map_entity[entity.id] = entitypos = len(self.list_x)for i, eid in enumerate(self.list_x):x = self.map_entity[eid].xif entity.x < x:pos = ibreakself.list_x.insert(pos, entity.id)pos = len(self.list_y)for j, eid in enumerate(self.list_y):y = self.map_entity[eid].yif entity.y < y:pos = jbreakself.list_y.insert(pos, entity.id)return entitydef remove(self, eid):entity = self.map_entity.pop(eid)for i, eid in enumerate(self.list_x):if eid == entity.id:del self.list_x[i]breakfor j, eid in enumerate(self.list_y):if eid == entity.id:del self.list_y[j]breakdef get_range_entities(self, entity):# 获取指定对象的AOI对象列表ret_set = set([])for ob_id in self.list_x:ob = self.map_entity[ob_id]if abs(ob.x - entity.x) <= entity.radius:if ob != entity:ret_set.add(ob)for ob_id in self.list_y:ob = self.map_entity[ob_id]if abs(ob.y - entity.y) <= entity.radius:if ob not in ret_set and entity != ob:ret_set.add(ob)else:breakreturn list(ret_set)def update_pos(self, eid, x, y):# 更新对象eid对象的坐标为(x, y)if eid not in self.map_entity:# 首次进入entity = Entity(eid, x, y)entity = self.add_by_entity(entity)entities = self.get_range_entities(entity)for ob in entities:ob.enter(entity)else:entity = self.map_entity[eid]if x < 0 or y < 0:# 坐标小于0时为离开场景obs = self.get_range_entities(entity)self.remove(eid)for ob in obs:ob.leave(entity)else:old_entities = self.get_range_entities(entity)self.remove(eid)entity.x = xentity.y = yself.add_by_entity(entity)new_entities = self.get_range_entities(entity)# enter处理enter_obs = [ob for ob in new_entities if ob not in old_entities]for ob in enter_obs:ob.enter(entity)# leave处理leave_obs = [ob for ob in old_entities if ob not in new_entities]for ob in leave_obs:ob.leave(entity)# move处理move_obs = [ob for ob in old_entities if ob in new_entities]for ob in move_obs:ob.move(entity)        def test():scene = Scene()scene.update_pos(1, 1, 2)scene.update_pos(2, 5, 9)scene.update_pos(3, 10, 10)pobj1 = scene.map_entity[1]pobj2 = scene.map_entity[2]pobj3 = scene.map_entity[3]print sceneprint("\nscene.update_pos(1, 7, 7), pobj1.range: ")scene.update_pos(1, 7, 7)for ob in scene.get_range_entities(pobj1):print(ob)print("\nscene.update_pos(2, 1, 2)), pobj2.range:")scene.update_pos(2, 1, 2)for ob in scene.get_range_entities(pobj2):print(ob)print("\nscene.update_pos(3, 5, 5), pobj3.range: ")scene.update_pos(3, 5, 5)for ob in scene.get_range_entities(pobj3):print(ob)test()
运行结果:
<2,5-9> enter <1,1-2> view
<3,10-10> enter <2,5-9> view
<list_x: [1, 2, 3], list_y: [1, 2, 3], entities: [1,2,3]>scene.update_pos(1, 7, 7), pobj1.range:
<1,7-7> enter <3,10-10> view
<1,7-7> move in <2,5-9> view
<3,10-10>
<2,5-9>scene.update_pos(2, 1, 2)), pobj2.range:
<2,1-2> leave <3,10-10> view
<2,1-2> move in <1,7-7> view
<1,7-7>scene.update_pos(3, 5, 5), pobj3.range:
<3,5-5> enter <2,1-2> view
<3,5-5> move in <1,7-7> view
<1,7-7>
<2,1-2>

规范版本应该双向列表维护,实体数量较多时候,应该用跳跃表去维护,类的设计如下

参考:https://www.cnblogs.com/rond/p/6114919.html

class Entity(object):def __init__(self):self.id = 0self.x = 0self.y = 0self.x_prev = None  # 双向列表self.x_next = Noneself.y_prev = Noneself.y_next = Noneclass Scene(object):def __init__(self):self.list_x_head = Noneself.list_x_tail = Noneself.list_y_head = Noneself.list_y_tail = None

游戏算法-AOI十字链表入门简单版python相关推荐

  1. 游戏算法-AOI基本介绍

    一.直接比较所有对象 最直观也是最效率最低的一种方法.当一个事件发生,我们需要获得AOI范围以内的物体时,直接遍历游戏中所有的对象,并且进行坐标判断,如果小于或者等于AOI的范围,则为需要的游戏对象. ...

  2. 游戏服务器设计(C#)简单版

    背景 充分利用c#中的task机制,设计高并发,无锁(针对业务逻辑)的服务器架构 gateserver 处理客户端连接.交互的服务器 永久性设计,与游戏项目无关,无需新代码维护 gameserver ...

  3. 稀疏矩阵的三元组表与十字链表存储

    三元组表:存储稀疏矩阵的非零元素,以及该元素所在的行.列信息,极大的节省了空间(如相比于一般的二维数组的存储),而且三元组表的某些算法的时间效率也要优于经典算法,如基于三元组表的一次快速转置算法等等 ...

  4. 算法:游戏内AOI视野算法(十字链表)

    为什么要有这个算法? 对于一个游戏场景内的实体来说,当战斗频繁的时候,可能存在上千实体的数据同步,例如上千实体移动时的坐标同步,大型战斗场景时全场景实体的属性的同步等等,这样就会造成一个问题,同步数据 ...

  5. 十字链表的AOI算法实现

    [game] 十字链表的AOI算法实现 转载:https://www.cnblogs.com/rond/p/6114919.html AOI主要有九宫格.灯塔和十字链表的算法实现.本文阐述十字链表的实 ...

  6. 阿里巴巴校园招聘 —— 灵犀游戏开发测试岗笔试题目总结(菜鸡版解析)涉及知识点——十字链表、线程与堆栈、FTP、Telnet、红黑树、哈夫曼树、平衡二叉树、乐观锁、悲观锁、HTTP、NIM游戏

    内容 感觉内容无非是那几个: 数据结构与算法 + 计算机网络 + 操作系统 + C++基础语法知识 简单的送分题我就不说了,我说几个还有点迷惑性的点来整理一下: 1. 十字链表 在Linux内核中应用 ...

  7. MMORPG游戏中AOI视野算法解析

    转载:https://blog.csdn.net/ybn6775/article/details/81701167 AOI(Area Of Interest),中文就是感兴趣区域.通俗一点说,感兴趣区 ...

  8. 游戏服务器AOI兴趣点算法原理--四叉树与九宫格 (golang)

    定义: 获取感兴趣的区域(Area Of Interest)的算法.主要用于常用的游戏服务器压力,降低网络风暴的可能. 常见的AOI算法有九宫格,四叉树,灯塔,十字链表等算法.本文主要举例九宫格和四叉 ...

  9. Java入门简单小游戏有哪些?

    适合新手练习的小游戏有超级玛丽.愤怒的小鸟.飞机大战.五子棋.彩虹雨.聊天室.华容道.坦克大战.扫雷等.还有贪吃蛇,由Java开发出来的一款经典小游戏,java小白入门可以用这款游戏开发练手锻炼自己的 ...

最新文章

  1. 存储mysql数据存在特殊字符时处理_转义 存储数据时特殊符号的处理
  2. mysql global index_CHECK GLOBAL INDEX
  3. 从零开始打造自己的PHP框架――第2章
  4. jsp文件上传_猿蜕变系列7——也说说springMVC上传姿势
  5. bzoj 1257: [CQOI2007]余数之和sum 数论
  6. 漫步最优化二十三——一维优化
  7. 蓝桥杯 ADV-87 算法提高 利息计算
  8. “叔叔,你来监考了!”
  9. 在线密码管理器LastPass遭入侵 官方建议修改主密码
  10. Excel表格文件,.xls和.xlsx格式的区别
  11. Pandas快乐学习之上海机动车牌照拍卖
  12. 什么?学了C语言还不会表白,下面的多彩小心心快去拿给那个她吧
  13. Adobe国际认证证书,深化设计师个人优势!
  14. 中国科学院计算机博士好考吗,中科院考博难不难?亲身经历告诉你答案…
  15. 临界资源的同步与互斥,区分临界资源与临界区,二义性分析
  16. Django 配置数据库相关
  17. 实验四-1:输入一个字符,请判断是字母、数字还是其它字符。
  18. LaTeX中文、英文字体属性设置
  19. Extjs 3.0.0 问题总结
  20. 数据结构 第一节 第一课

热门文章

  1. 数大电信巨头缺席北京通信展 折射电信业冬天
  2. UI设计理念-app的界面设计流程
  3. 如何写一份让大厂面试官,不服不行的简历
  4. Android使用移动智能终端补充设备标识获取OAID
  5. python 要点1
  6. Day03_Pandas
  7. 为什么很多程序员宁可打游戏也不追女生
  8. 三大运营商大数据运用
  9. Win8/Win7或XP 双系统安装图文教程
  10. Android安全[测试环境vuln-demopwn]