﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-cloud-随笔分类-游戏</title><link>http://www.cppblog.com/cloud/category/4241.html</link><description /><language>zh-cn</language><lastBuildDate>Fri, 11 Dec 2009 14:13:38 GMT</lastBuildDate><pubDate>Fri, 11 Dec 2009 14:13:38 GMT</pubDate><ttl>60</ttl><item><title>把D3D画面渲染到桌面！不用创建任何窗口 </title><link>http://www.cppblog.com/cloud/archive/2008/03/21/45032.html</link><dc:creator>cloud</dc:creator><author>cloud</author><pubDate>Fri, 21 Mar 2008 02:53:00 GMT</pubDate><guid>http://www.cppblog.com/cloud/archive/2008/03/21/45032.html</guid><wfw:comment>http://www.cppblog.com/cloud/comments/45032.html</wfw:comment><comments>http://www.cppblog.com/cloud/archive/2008/03/21/45032.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cloud/comments/commentRss/45032.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cloud/services/trackbacks/45032.html</trackback:ping><description><![CDATA[<p>HWND&nbsp;hWnd&nbsp; <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">&nbsp;FindWindowEx(GetDesktopWindow()&nbsp;,&nbsp;</span> <span style="COLOR: #000000">0</span> <span style="COLOR: #000000">&nbsp;,&nbsp;</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">Progman</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">&nbsp;,&nbsp;</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">Program&nbsp;Manager</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">);<br>hWnd&nbsp;</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">&nbsp;FindWindowEx(hWnd&nbsp;,&nbsp;</span> <span style="COLOR: #000000">0</span> <span style="COLOR: #000000">&nbsp;,&nbsp;</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">SHELLDLL_DefView</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">&nbsp;,&nbsp;</span> <span style="COLOR: #000000">0</span> <span style="COLOR: #000000">);<br>hWnd&nbsp;</span> <span style="COLOR: #000000">=</span> <span style="COLOR: #000000">&nbsp;FindWindowEx(hWnd&nbsp;,&nbsp;</span> <span style="COLOR: #000000">0</span> <span style="COLOR: #000000">&nbsp;,&nbsp;</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">SysListView32</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">&nbsp;,&nbsp;</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">FolderView</span> <span style="COLOR: #000000">"</span> <span style="COLOR: #000000">);<br></span><span style="COLOR: #008000">//</span> <span style="COLOR: #008000">&nbsp;初始化&nbsp;D3D&nbsp;设备</span>&nbsp;<span style="COLOR: #008000"><br></span><span style="COLOR: #000000">InitD3D(hWnd);<br><br>显示的时候，如果想渲染在桌面的一角，则可以这样写：<br><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;显示在左上角，128&#215;128宽</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">RECT&nbsp;rect;<br>rect.left&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>rect.right&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">128</span><span style="COLOR: #000000">;<br>rect.top&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">;<br>rect.bottom&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">128</span><span style="COLOR: #000000">;<br></span><span style="COLOR: #008000">//</span><span style="COLOR: #008000">&nbsp;显示</span><span style="COLOR: #008000"><br></span><span style="COLOR: #000000">g_pd3dDevice</span><span style="COLOR: #000000">-&gt;</span><span style="COLOR: #000000">Present(</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">&nbsp;,&nbsp;</span><span style="COLOR: #000000">&amp;</span><span style="COLOR: #000000">rect&nbsp;,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">&nbsp;,&nbsp;</span><span style="COLOR: #000000">0</span><span style="COLOR: #000000">);<br></span></span></p>
<img src ="http://www.cppblog.com/cloud/aggbug/45032.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cloud/" target="_blank">cloud</a> 2008-03-21 10:53 <a href="http://www.cppblog.com/cloud/archive/2008/03/21/45032.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>[转]游戏Entity设计不完全整理</title><link>http://www.cppblog.com/cloud/archive/2008/01/09/40796.html</link><dc:creator>cloud</dc:creator><author>cloud</author><pubDate>Wed, 09 Jan 2008 07:14:00 GMT</pubDate><guid>http://www.cppblog.com/cloud/archive/2008/01/09/40796.html</guid><wfw:comment>http://www.cppblog.com/cloud/comments/40796.html</wfw:comment><comments>http://www.cppblog.com/cloud/archive/2008/01/09/40796.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cloud/comments/commentRss/40796.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cloud/services/trackbacks/40796.html</trackback:ping><description><![CDATA[<div class=postText>
<p class=MsoNormal style="TEXT-ALIGN: center"><span style="FONT-FAMILY: 宋体"><span style="FONT-FAMILY: 宋体"><span style="FONT-FAMILY: 宋体">在游戏引擎中，</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">通常被翻译成实体，也常用诸如</span><span lang=EN-US>GameObject</span><span style="FONT-FAMILY: 宋体">、</span><span lang=EN-US>Actor</span><span style="FONT-FAMILY: 宋体">、</span><span lang=EN-US>SimulationObject</span><span style="FONT-FAMILY: 宋体">、</span><span lang=EN-US>Unit</span><span style="FONT-FAMILY: 宋体">、</span><span lang=EN-US>Character</span><span style="FONT-FAMILY: 宋体">等名字。相比于对图像声音引擎的热情，</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">层多年来一直备受冷遇，但最近几年随着大型游戏的发展，</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">层设计的重要性已经达到和图像声音的同等水平，而且已经出现了多种通用型</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">架构。当然，这里伴随着争议和分歧。</span></p>
<h3><span style="FONT-FAMILY: 宋体">直接模式（</span><span lang=EN-US>The C Approach</span><span style="FONT-FAMILY: 宋体">）</span></h3>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">这是最早、最简单、也是任何人都能直接想到的模式。这种方式下一个</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">就是一个简单的</span><span lang=EN-US>struct:</span></p>
<p class=MsoNormal><span lang=EN-US>struct Mob<br>{<br>int level, hp, mp, attack, &#8230;;<br>};</span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">这种情况下往往需要对不同类型的</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">定义不同的</span><span lang=EN-US>struct</span><span style="FONT-FAMILY: 宋体">，比如</span><span lang=EN-US>Player</span><span style="FONT-FAMILY: 宋体">、</span><span lang=EN-US>Mob</span><span style="FONT-FAMILY: 宋体">、</span><span lang=EN-US>Item</span><span style="FONT-FAMILY: 宋体">、</span><span lang=EN-US>Doodad</span><span style="FONT-FAMILY: 宋体">等。</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">的数据库可以直接使用现成的数据库系统或者从数据文件读取，比如</span><span lang=EN-US>csv</span><span style="FONT-FAMILY: 宋体">文件。一般会选择</span><span lang=EN-US>Excel</span><span style="FONT-FAMILY: 宋体">编辑数据库，然后导出</span><span lang=EN-US>csv</span><span style="FONT-FAMILY: 宋体">。</span><span lang=EN-US>Excel</span><span style="FONT-FAMILY: 宋体">的强大表格和统计计算功能是调节游戏数据平衡的得力工具。以致这种最古老而简单的</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">模式以强大的生命力一直活到现在。</span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">那么为什么</span><span lang=EN-US>Developers</span><span style="FONT-FAMILY: 宋体">会要去探索其他方式呢？最大的问题是这种方式下各种</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">完全不同质。比如</span><span lang=EN-US>Player</span><span style="FONT-FAMILY: 宋体">、</span><span lang=EN-US>Mob</span><span style="FONT-FAMILY: 宋体">、</span><span lang=EN-US>Doodad</span><span style="FONT-FAMILY: 宋体">都有位置，都要做碰撞检测，但他们却是不同的类型，不能使用同一份代码；</span><span lang=EN-US>Player</span><span style="FONT-FAMILY: 宋体">和</span><span lang=EN-US>Mob</span><span style="FONT-FAMILY: 宋体">都有</span><span lang=EN-US>hp</span><span style="FONT-FAMILY: 宋体">和</span><span lang=EN-US>mp</span><span style="FONT-FAMILY: 宋体">，也有基本相同的处理逻辑&#8230;&#8230;当然，这个可以用</span><span lang=EN-US>hack</span><span style="FONT-FAMILY: 宋体">的方法解决：只要各个</span><span lang=EN-US>struct</span><span style="FONT-FAMILY: 宋体">前若干个成员类型和顺序完全相同，就可以将指针</span><span lang=EN-US>cast</span><span style="FONT-FAMILY: 宋体">成统一的一个</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">类型来处理。不过，任何人都能想到更好的办法，用类！</span></p>
<h3><span style="FONT-FAMILY: 宋体">继承模式（</span><span lang=EN-US>Inheritage</span><span style="FONT-FAMILY: 宋体">）</span></h3>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">这也是</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">、</span><span lang=EN-US>GameObject</span><span style="FONT-FAMILY: 宋体">等这些名字的由来，他们就是基类。于是我们可以得到一颗继承关系树，例如：</span></p>
<p class=MsoNormal><span lang=EN-US>Entity</span></p>
<p class=MsoNormal><span lang=EN-US><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Character</span></p>
<p class=MsoNormal><span lang=EN-US><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Player</span></p>
<p class=MsoNormal><span lang=EN-US><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Mob</span></p>
<p class=MsoNormal><span lang=EN-US><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Missile</span></p>
<p class=MsoNormal><span lang=EN-US><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Laser</span></p>
<p class=MsoNormal><span lang=EN-US><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>GuidedMissile</span></p>
<p class=MsoNormal><span lang=EN-US><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>Item</span></p>
<p class=MsoNormal><span lang=EN-US><span>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span>&#8230;</span></p>
<p class=MsoNormal><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">对象的逻辑大多也是直接包含在类里的。但也有人采用了数据对象和逻辑对象的分离，其好处是对相同的数据可以替换不同的逻辑。不过，个人比较怀疑这种分离是否值得，因为类的派生本身就是可以拥有不同的逻辑。</span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">另外，</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">间的交互除了用标准的直接访问方式外，经常使用消息模式。消息模式和</span><span lang=EN-US>Windows</span><span style="FONT-FAMILY: 宋体">的消息模式类似，</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">间通过消息交互。虽说窗口编程画了多年时间才摆脱了当年肥大的</span><span lang=EN-US>switch</span><span style="FONT-FAMILY: 宋体">的消息处理模式，在</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">层使用消息模式还是有意义的，因为消息很容易广播且可以直接在网络上发送。执着于</span><span lang=EN-US>OO</span><span style="FONT-FAMILY: 宋体">的人会将消息写成</span><span lang=EN-US>Command</span><span style="FONT-FAMILY: 宋体">对象，但原理仍然是一样的。</span><span lang=EN-US><o:p></o:p></span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">同时，联网游戏出现，指针不能在不同的机器上标识对象，我们必须用稳定的</span><span lang=EN-US>ID</span><span style="FONT-FAMILY: 宋体">来标识对象，于是我们有了</span><span lang=EN-US>EntityManager</span><span style="FONT-FAMILY: 宋体">来分配</span><span lang=EN-US>ID</span><span style="FONT-FAMILY: 宋体">和管理对象集合，或者叫</span><span lang=EN-US>GameObjectManager</span><span style="FONT-FAMILY: 宋体">、</span><span lang=EN-US>ObjectManager</span><span style="FONT-FAMILY: 宋体">等。这在一段时期内几乎成了完美的方案。</span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">随着游戏内容的丰富性的迅速膨胀，传统的由程序员来实现游戏逻辑功能的模式也越来越力不从心。脚本语言的集成将大部分创意性工作从程序员的担子上拿了下来，交还给游戏设计人员。为了给脚本提供足够的控制权，</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">结构上必须有充分的灵活性。</span></p>
<h3><span style="FONT-FAMILY: 宋体">数据驱动（</span><span lang=EN-US>Data-Driven</span><span style="FONT-FAMILY: 宋体">）</span></h3>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">现在有句很流行的话，&#8220;唯一不变的是变化。（</span><span lang=EN-US>The only constant is change.</span><span style="FONT-FAMILY: 宋体">）&#8221;数据驱动使得变化对引擎的影响最小化。数据驱动不能算是一种独立的</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">模式，不如说它是一种设计思想，其目的就是将内容制作和游戏引擎的制作分离开来。与上面所说的填充</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">属性数据库的不同之处在于，它还要能通过数据来设计游戏逻辑。</span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">游戏设计人员需要的一项最基本功能就是自定义人物属性，所以与其在类里写死属性成员，不如使用属性表（</span><span lang=EN-US>Attributes/Properties</span><span style="FONT-FAMILY: 宋体">）。通常使用一个哈希表（</span><span lang=EN-US>Hashtable</span><span style="FONT-FAMILY: 宋体">），或者</span><span lang=EN-US>std::map</span><span style="FONT-FAMILY: 宋体">，或者</span><span lang=EN-US>Dictionary</span><span style="FONT-FAMILY: 宋体">，或者就是个数组，随个人喜好，其实就是要一个</span><span lang=EN-US>key-value</span><span style="FONT-FAMILY: 宋体">的映射表。然后为脚本和编辑器提供对属性表的操作。</span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">动态的逻辑主要就靠脚本了，必须为脚本提供足够的事件和方法。个人推荐用</span><span lang=EN-US>Lua</span><span style="FONT-FAMILY: 宋体">脚本，因为它是在游戏领域内用得最多的通用脚本语言，其引擎很小、速度很快、易于集成，尽管语法过于松散。不要迷信宣传去用庞大、极慢、难于集成的</span><span lang=EN-US>Python</span><span style="FONT-FAMILY: 宋体">。为脚本提供事件，其实也就是调用脚本里的函数，这里如果使用了前面所述的消息模式，那么就只要调用一个脚本方法，传递不同的消息参数就行了。当然也有人觉得这样很丑陋而更愿意为不同的事件注册不同的函数。</span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">当有了数据驱动后，</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">的继承树就基本失去意义了，因为一个</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">是什么已经不是程序里决定的了，而是通过数据和脚本设计出来的。但数据和脚本又不是全部，一个</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">的核心内容和需要高效处理的部分，如碰撞检测，还是要程序来完成。于是我们需要重新设计</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">类，困难的局面也就由此开始。</span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">一个直观的想法是一个统一且唯一的</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">类，它包含了所有的基本功能，如显示、碰撞检测、运动、背包等，然后由数据决定哪些组件被启用。比如一个玩家角色可能会启用绝大部分组件，而一颗树只启用显示和碰撞检测组件。但也伴随着缺点：一、这个类太大了；二、对于树木等一些简单的</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">也要浪费其他组件的私有数据所占的内存。那么一个简单的折中是部分使用继承、部分使用数据定制。例如</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">只提供最基本的组件，再派生出</span><span lang=EN-US>CharactorEntity</span><span style="FONT-FAMILY: 宋体">提供足够人物角色使用的组件。</span></p>
<h3><span style="FONT-FAMILY: 宋体">组件模式（</span><span lang=EN-US>Component-Based Entity</span><span style="FONT-FAMILY: 宋体">）</span></h3>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">提到组件，那么很自然的就过渡到组件模式，就是把显示、运动、攻击、背包、队伍、声音等基本功能都做成独立的组件，由数据来决定向</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">里添加哪些组件。由此可以得到另外一个扩展，就是既然可以有引擎内置的组件，那就也可以有脚本制作的组件，实现脚本模块的复用。这种模式在</span><span lang=EN-US>GDC2002</span><span style="FONT-FAMILY: 宋体">正式提出，到现在主流的引擎都有这种设计。</span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">这种模式在理论上很完美，但实践上还是有不少疑问。最常见的问题就是组件间的依赖关系。理想情况下，各个组件是完全独立的，但实践中必然有所依赖。比如运动速度、攻击强度等和角色的基本属性有关，运动组件需要角色的包围盒来测试是否碰撞，</span><span lang=EN-US>AI</span><span style="FONT-FAMILY: 宋体">组件需要分析角色当前状态和发出运动、攻击命令，角色动作状态变化时改变显示组件属性，攻击组件需要访问队伍信息组件以禁止攻击队友等等。处理这种依赖关系主要要解决两个问题：</span></p>
<p class=MsoNormal style="MARGIN-LEFT: 19.5pt; TEXT-INDENT: -19.5pt">&lt;!--[if !supportLists]--&gt;<span lang=EN-US><span>一、<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>&lt;!--[endif]--&gt;<span style="FONT-FAMILY: 宋体">谁依赖谁。比如是敏捷属性改变而去修改移动速度，还是运动组件读取敏捷属性来计算移动速度。如果要游戏设计人员自由定义基本属性的话，就要选择前者，因为基本属性组件会是脚本组件。</span></p>
<p class=MsoNormal style="MARGIN-LEFT: 19.5pt; TEXT-INDENT: -19.5pt">&lt;!--[if !supportLists]--&gt;<span lang=EN-US><span>二、<span style="FONT: 7pt 'Times New Roman'; font-size-adjust: none; font-stretch: normal">&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; </span></span></span>&lt;!--[endif]--&gt;<span style="FONT-FAMILY: 宋体">如何取得另一组件的指针</span><span lang=EN-US>/</span><span style="FONT-FAMILY: 宋体">引用。常见的方法是给每个组件类型一个唯一</span><span lang=EN-US>ID</span><span style="FONT-FAMILY: 宋体">，然后用该</span><span lang=EN-US>ID</span><span style="FONT-FAMILY: 宋体">在</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">上查询注册了的组件，如果找到返回其指针</span><span lang=EN-US>/</span><span style="FONT-FAMILY: 宋体">引用，否则返回</span><span lang=EN-US>null</span><span style="FONT-FAMILY: 宋体">。当然，每次访问都做这个查询会很浪费</span><span lang=EN-US>CPU</span><span style="FONT-FAMILY: 宋体">，如果</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">的组件不会在运行时动态添加删除的话（除非在编辑器里，否则很少有人会这么做），可以在</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">初始化后让每个组件缓存它所要用的其他组件指针。那么当所依赖的组件不存在怎么办，一般情况下都是无声地忽略。</span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">当</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">由很多组件组成后，交互的消息需要发给每一个组件。这里又一次体现出消息机制的优势，你不需要在</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">里为每一个事件函数写一个</span><span lang=EN-US>loop</span><span style="FONT-FAMILY: 宋体">来调用组件的相应事件函数。但这里也出现了一个问题，消息到达各个组件的顺序。很多时候这个顺序不会有什么影响，但个别时候不同的顺序会导致完全不同的逻辑发展方向。</span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">此外，</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">的序列化存储也变得比较复杂，经典的</span><span lang=EN-US>Excel</span><span style="FONT-FAMILY: 宋体">导出</span><span lang=EN-US>csv</span><span style="FONT-FAMILY: 宋体">的模式难以奏效，因为这里需要结构化的存储，所以需要结构化的数据文件如</span><span lang=EN-US>XML</span><span style="FONT-FAMILY: 宋体">来存储，或者完全用脚本来包含所有数据和构造</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">。</span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">据个人经验，使用数据驱动的继承模式时很是向往组件模式，感觉上它一个非常自然的扩展方向，但顾忌其引入的额外的复杂性，尤其是需要游戏设计人员具有一定的编程能力，所以一直不敢全盘接过使用。但退一步，在引擎里仍然使用组件思想，但</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">的组件构成在编译时固定，可以达到某种妥协，这和采用继承与数据驱动的折中类似。</span></p>
<h3><span style="FONT-FAMILY: 宋体">混入模式（</span><span lang=EN-US>Mix-in</span><span style="FONT-FAMILY: 宋体">）</span></h3>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">这是又一种常见的折中模式，即使用</span><span lang=EN-US>C++</span><span style="FONT-FAMILY: 宋体">的多重继承，将各个组件类混入一个</span><span lang=EN-US>Entity</span><span style="FONT-FAMILY: 宋体">类。如：</span></p>
<p class=MsoNormal><span lang=EN-US>class Mob: public GameObject, public Renderable, public Movable, public Attackable<br>{<br>&#8230;<br>}</span></p>
<p class=MsoNormal><span lang=EN-US><o:p></o:p></span><span style="FONT-FAMILY: 宋体">这种方法因其简单而且非常符合多重继承设计思想而被很多引擎采用。当然缺点也是只能在支持多重继承的语言里使用，而且当组件很丰富时，</span><span lang=EN-US>dynamic_cast</span><span style="FONT-FAMILY: 宋体">就变成一个代价高昂的操作。</span><span lang=EN-US><o:p> <br></o:p></span></p>
<h3><span style="FONT-FAMILY: 宋体">功能性与复杂性（</span><span lang=EN-US>Functionality vs Complexity</span><span style="FONT-FAMILY: 宋体">）</span></h3>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">编程领域最古老的原则之一就是要&#8220;简单快速&#8221;。但随着问题的复杂化，程序也随之变得越来越复杂。好的方法应该能有效的降低或隐藏复杂性。但是，没有不带副作用的药（</span><span lang=EN-US>No silver bullet.</span><span style="FONT-FAMILY: 宋体">），在取得更强大的功能的同时总会带来额外的复杂性。我们需要做出权衡，在必要时牺牲一些功能，也就是要估算性价比。</span><br><span lang=EN-US><o:p></o:p></span></p>
<p class=MsoNormal><span style="FONT-FAMILY: 宋体">一般游戏内容制作人员不会或不太会编程，编程人员也不善于游戏的内容创造和数值平衡，过于复杂的系统会导致需要两面兼顾的人才，会大大增加做出一款游戏的难度。</span></p>
</span></span></div>
<img src ="http://www.cppblog.com/cloud/aggbug/40796.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cloud/" target="_blank">cloud</a> 2008-01-09 15:14 <a href="http://www.cppblog.com/cloud/archive/2008/01/09/40796.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>关于串号的问题</title><link>http://www.cppblog.com/cloud/archive/2007/06/18/26573.html</link><dc:creator>cloud</dc:creator><author>cloud</author><pubDate>Mon, 18 Jun 2007 09:37:00 GMT</pubDate><guid>http://www.cppblog.com/cloud/archive/2007/06/18/26573.html</guid><wfw:comment>http://www.cppblog.com/cloud/comments/26573.html</wfw:comment><comments>http://www.cppblog.com/cloud/archive/2007/06/18/26573.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cloud/comments/commentRss/26573.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cloud/services/trackbacks/26573.html</trackback:ping><description><![CDATA[这几天服务器突发一个bug, 登陆的人员会发生串号, 就是A玩家登陆后, 得到B玩家的角色.<br>&nbsp; 这个bug触发的主要原因是网络底层在得到一个客户端的连接请求时, 会分配一个id,而这个id是用栈在保存的,当有新的连接, id就出栈, 当连接断开时,id入栈, 这样就导致了id被重复利用的次数非常高,尤其是某些id. 当这些id生成后,会进入登陆队列,等待登陆结果, 如果这个时候登陆认证模块的速度很慢, 或者说这个时候客户端退出了, 这个时候的id就是一个无效id了, 可是这个只有网络底层知道, 这就造成引用层编写的难度.&nbsp; 所以最好的解决方案就是每次的连接id都是不一样的,类似操作系统的HANDLE
<img src ="http://www.cppblog.com/cloud/aggbug/26573.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cloud/" target="_blank">cloud</a> 2007-06-18 17:37 <a href="http://www.cppblog.com/cloud/archive/2007/06/18/26573.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>快速 double 转整型</title><link>http://www.cppblog.com/cloud/archive/2007/05/11/23890.html</link><dc:creator>cloud</dc:creator><author>cloud</author><pubDate>Fri, 11 May 2007 04:01:00 GMT</pubDate><guid>http://www.cppblog.com/cloud/archive/2007/05/11/23890.html</guid><wfw:comment>http://www.cppblog.com/cloud/comments/23890.html</wfw:comment><comments>http://www.cppblog.com/cloud/archive/2007/05/11/23890.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cloud/comments/commentRss/23890.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cloud/services/trackbacks/23890.html</trackback:ping><description><![CDATA[<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id=Codehighlighter1_16_40_Open_Image onclick="this.style.display='none'; Codehighlighter1_16_40_Open_Text.style.display='none'; Codehighlighter1_16_40_Closed_Image.style.display='inline'; Codehighlighter1_16_40_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_16_40_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_16_40_Closed_Text.style.display='none'; Codehighlighter1_16_40_Open_Image.style.display='inline'; Codehighlighter1_16_40_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top><span style="COLOR: #000000">union&nbsp;luai_Cast&nbsp;</span><span id=Codehighlighter1_16_40_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_16_40_Open_Text><span style="COLOR: #000000">{&nbsp;</span><span style="COLOR: #0000ff">double</span><span style="COLOR: #000000">&nbsp;l_d;&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;l_l;&nbsp;}</span></span><span style="COLOR: #000000">;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/None.gif" align=top></span><span style="COLOR: #0000ff">#define</span><span style="COLOR: #000000">&nbsp;lua_number2int(i,d)&nbsp;\</span><span style="COLOR: #000000"><br><img id=Codehighlighter1_75_152_Open_Image onclick="this.style.display='none'; Codehighlighter1_75_152_Open_Text.style.display='none'; Codehighlighter1_75_152_Closed_Image.style.display='inline'; Codehighlighter1_75_152_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_75_152_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_75_152_Closed_Text.style.display='none'; Codehighlighter1_75_152_Open_Image.style.display='inline'; Codehighlighter1_75_152_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_75_152_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_75_152_Open_Text><span style="COLOR: #000000">{&nbsp;</span><span style="COLOR: #0000ff">volatile</span><span style="COLOR: #000000">&nbsp;union&nbsp;luai_Cast&nbsp;u;&nbsp;u.l_d&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(d)&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">6755399441055744.0</span><span style="COLOR: #000000">;&nbsp;(i)&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;u.l_l;&nbsp;}</span></span></div>
<img src ="http://www.cppblog.com/cloud/aggbug/23890.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cloud/" target="_blank">cloud</a> 2007-05-11 12:01 <a href="http://www.cppblog.com/cloud/archive/2007/05/11/23890.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个不错的字符串 hash 函数</title><link>http://www.cppblog.com/cloud/archive/2007/05/11/23891.html</link><dc:creator>cloud</dc:creator><author>cloud</author><pubDate>Fri, 11 May 2007 04:01:00 GMT</pubDate><guid>http://www.cppblog.com/cloud/archive/2007/05/11/23891.html</guid><wfw:comment>http://www.cppblog.com/cloud/comments/23891.html</wfw:comment><comments>http://www.cppblog.com/cloud/archive/2007/05/11/23891.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cloud/comments/commentRss/23891.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cloud/services/trackbacks/23891.html</trackback:ping><description><![CDATA[<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><span style="COLOR: #000000">unsigned&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;hash(</span><span style="COLOR: #0000ff">const</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #0000ff">char</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">name,size_t&nbsp;len)<br>{<br>&nbsp;&nbsp;&nbsp;&nbsp;unsigned&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">&nbsp;h</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">(unsigned&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">)len;<br>&nbsp;&nbsp;&nbsp;&nbsp;size_t&nbsp;step&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;(len</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">;<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">for</span><span style="COLOR: #000000">&nbsp;(size_t&nbsp;i</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">len;&nbsp;i</span><span style="COLOR: #000000">&gt;=</span><span style="COLOR: #000000">step;&nbsp;i</span><span style="COLOR: #000000">-=</span><span style="COLOR: #000000">step)<br>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;h&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;h&nbsp;</span><span style="COLOR: #000000">^</span><span style="COLOR: #000000">&nbsp;((h</span><span style="COLOR: #000000">&lt;&lt;</span><span style="COLOR: #000000">5</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">(h</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">2</span><span style="COLOR: #000000">)</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">(unsigned&nbsp;</span><span style="COLOR: #0000ff">long</span><span style="COLOR: #000000">)name[i</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">]);<br>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;h;<br>}</span></div>
<img src ="http://www.cppblog.com/cloud/aggbug/23891.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cloud/" target="_blank">cloud</a> 2007-05-11 12:01 <a href="http://www.cppblog.com/cloud/archive/2007/05/11/23891.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>一个快速开方的函数</title><link>http://www.cppblog.com/cloud/archive/2007/05/11/23889.html</link><dc:creator>cloud</dc:creator><author>cloud</author><pubDate>Fri, 11 May 2007 04:00:00 GMT</pubDate><guid>http://www.cppblog.com/cloud/archive/2007/05/11/23889.html</guid><wfw:comment>http://www.cppblog.com/cloud/comments/23889.html</wfw:comment><comments>http://www.cppblog.com/cloud/archive/2007/05/11/23889.html#Feedback</comments><slash:comments>4</slash:comments><wfw:commentRss>http://www.cppblog.com/cloud/comments/commentRss/23889.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cloud/services/trackbacks/23889.html</trackback:ping><description><![CDATA[<p><span class=br0><font color=#66cc66></font></span>&nbsp;</p>
<div style="BORDER-RIGHT: #cccccc 1px solid; PADDING-RIGHT: 5px; BORDER-TOP: #cccccc 1px solid; PADDING-LEFT: 4px; FONT-SIZE: 13px; PADDING-BOTTOM: 4px; BORDER-LEFT: #cccccc 1px solid; WIDTH: 98%; WORD-BREAK: break-all; PADDING-TOP: 4px; BORDER-BOTTOM: #cccccc 1px solid; BACKGROUND-COLOR: #eeeeee"><img id=Codehighlighter1_0_19_Open_Image onclick="this.style.display='none'; Codehighlighter1_0_19_Open_Text.style.display='none'; Codehighlighter1_0_19_Closed_Image.style.display='inline'; Codehighlighter1_0_19_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_0_19_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_0_19_Closed_Text.style.display='none'; Codehighlighter1_0_19_Open_Image.style.display='inline'; Codehighlighter1_0_19_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top><span id=Codehighlighter1_0_19_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff">/**/</span><span id=Codehighlighter1_0_19_Open_Text><span style="COLOR: #008000">/*</span><span style="COLOR: #008000">&nbsp;来至&nbsp;Quake&nbsp;3&nbsp;的源码&nbsp;</span><span style="COLOR: #008000">*/</span></span><span style="COLOR: #000000"><br><img id=Codehighlighter1_44_403_Open_Image onclick="this.style.display='none'; Codehighlighter1_44_403_Open_Text.style.display='none'; Codehighlighter1_44_403_Closed_Image.style.display='inline'; Codehighlighter1_44_403_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif" align=top><img id=Codehighlighter1_44_403_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_44_403_Closed_Text.style.display='none'; Codehighlighter1_44_403_Open_Image.style.display='inline'; Codehighlighter1_44_403_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif" align=top></span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;CarmSqrt(</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;x)</span><span id=Codehighlighter1_44_403_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_44_403_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;union<br><img id=Codehighlighter1_54_91_Open_Image onclick="this.style.display='none'; Codehighlighter1_54_91_Open_Text.style.display='none'; Codehighlighter1_54_91_Closed_Image.style.display='inline'; Codehighlighter1_54_91_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_54_91_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_54_91_Closed_Text.style.display='none'; Codehighlighter1_54_91_Open_Image.style.display='inline'; Codehighlighter1_54_91_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_54_91_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_54_91_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;intPart;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;floatPart;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">&nbsp;convertor;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;union<br><img id=Codehighlighter1_112_149_Open_Image onclick="this.style.display='none'; Codehighlighter1_112_149_Open_Text.style.display='none'; Codehighlighter1_112_149_Closed_Image.style.display='inline'; Codehighlighter1_112_149_Closed_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif" align=top><img id=Codehighlighter1_112_149_Closed_Image style="DISPLAY: none" onclick="this.style.display='none'; Codehighlighter1_112_149_Closed_Text.style.display='none'; Codehighlighter1_112_149_Open_Image.style.display='inline'; Codehighlighter1_112_149_Open_Text.style.display='inline';" src="http://www.cppblog.com/Images/OutliningIndicators/ContractedSubBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span id=Codehighlighter1_112_149_Closed_Text style="BORDER-RIGHT: #808080 1px solid; BORDER-TOP: #808080 1px solid; DISPLAY: none; BORDER-LEFT: #808080 1px solid; BORDER-BOTTOM: #808080 1px solid; BACKGROUND-COLOR: #ffffff"><img src="http://www.cppblog.com/Images/dot.gif"></span><span id=Codehighlighter1_112_149_Open_Text><span style="COLOR: #000000">{<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">int</span><span style="COLOR: #000000">&nbsp;intPart;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">float</span><span style="COLOR: #000000">&nbsp;floatPart;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockEnd.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;}</span></span><span style="COLOR: #000000">&nbsp;convertor2;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;convertor.floatPart&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;x;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;convertor2.floatPart&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;x;<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;convertor.intPart&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0x1FBCF800</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;(convertor.intPart&nbsp;</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;convertor2.intPart&nbsp;</span><span style="COLOR: #000000">=</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0x5f3759df</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">-</span><span style="COLOR: #000000">&nbsp;(convertor2.intPart&nbsp;</span><span style="COLOR: #000000">&gt;&gt;</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">1</span><span style="COLOR: #000000">);<br><img src="http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif" align=top>&nbsp;&nbsp;&nbsp;&nbsp;</span><span style="COLOR: #0000ff">return</span><span style="COLOR: #000000">&nbsp;</span><span style="COLOR: #000000">0.5f</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">(convertor.floatPart&nbsp;</span><span style="COLOR: #000000">+</span><span style="COLOR: #000000">&nbsp;(x&nbsp;</span><span style="COLOR: #000000">*</span><span style="COLOR: #000000">&nbsp;convertor2.floatPart));<br><img src="http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockEnd.gif" align=top>}</span></span></div>
<img src ="http://www.cppblog.com/cloud/aggbug/23889.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cloud/" target="_blank">cloud</a> 2007-05-11 12:00 <a href="http://www.cppblog.com/cloud/archive/2007/05/11/23889.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>快速查找指定对象周边的对象</title><link>http://www.cppblog.com/cloud/archive/2007/05/10/23816.html</link><dc:creator>cloud</dc:creator><author>cloud</author><pubDate>Thu, 10 May 2007 09:33:00 GMT</pubDate><guid>http://www.cppblog.com/cloud/archive/2007/05/10/23816.html</guid><wfw:comment>http://www.cppblog.com/cloud/comments/23816.html</wfw:comment><comments>http://www.cppblog.com/cloud/archive/2007/05/10/23816.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/cloud/comments/commentRss/23816.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/cloud/services/trackbacks/23816.html</trackback:ping><description><![CDATA[快速查找一个对象周边的对象,一个可行的方案是用网格. <br>做法:<br>&nbsp;&nbsp;&nbsp;&nbsp; 1.把一个地图划分成N*N个网格,每一个网格拥有一个list<br>&nbsp;&nbsp;&nbsp;&nbsp; 2.确定每个对象在网格中的位置(假定对象的位置[x, y]):&nbsp;x%N, y%N,找到指定的格子之后,加入到list中即可<br>&nbsp;&nbsp;&nbsp;&nbsp; 3.还有就是一个网格需要按情况决定要多大,这样才能确定处N的大小&nbsp; <br><br>优点:<br>&nbsp;&nbsp;&nbsp;&nbsp; 速度快<br>缺点:<br>&nbsp;&nbsp;&nbsp;&nbsp; 占用内存,尤其是地图过大的时候.
<img src ="http://www.cppblog.com/cloud/aggbug/23816.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/cloud/" target="_blank">cloud</a> 2007-05-10 17:33 <a href="http://www.cppblog.com/cloud/archive/2007/05/10/23816.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>