如何评价他改变了中国游戏改变者

游戏改变世界_百度文库
两大类热门资源免费畅读
续费一年阅读会员,立省24元!
游戏改变世界
&&游戏是分享和即时沟通的完美场景;也是互联时代人与人新的沟通协作方式
阅读已结束,下载文档到电脑
想免费下载更多文档?
定制HR最喜欢的简历
下载文档到电脑,方便使用
还剩7页未读,继续阅读
定制HR最喜欢的简历
你可能喜欢& 2005-, all rights reserved 北京豆网科技有限公司如何评价朴树? - 知乎4455被浏览3241419分享邀请回答4.1K381 条评论分享收藏感谢收起1.8K206 条评论分享收藏感谢收起查看更多回答如何评价守望先锋架构设计? - 知乎1789被浏览77614分享邀请回答class Player {
Model* model;
void move();
void attack();
类似这样完全没有或很少架构设计的代码,在项目规模增大后,很快变得臃肿、难以扩展和维护。OOP 设计模式的泛滥 案例:OGRE设计模式是语言表达能力不足的产物。 —— 某程序员
那么,作为他山之石,GoF 基于 Java 提出的设计模式,能否有效解决游戏开发领域的问题?大家还记得当年国内风靡一时的游戏引擎 OGRE 么? OGRE 总有那么些学院派的味道,试图通过设计模式的广泛使用,来提高代码的可维护性和可扩展性。然而,个人对游戏开发领域大规模使用 OOP 设计模式的看法:设计模式的六大原则大部分仍值得遵循。基于 Java 实现的设计模式,未必适合其它语言和领域。想想 C# 的 event、delegate、lambda 可以简化或者消除多少种 GoF 的模式,再想想 Golang 的隐式接口。C++ 是游戏开发领域最主要的语言,可以 OOP 但并不那么 OO,比如缺少语言层面纯粹的 interface,也缺少 GC、反射等特性。照抄 Java 的设计模式未免有些东施尿频,而且难以实现 C++ 所推崇的零代价抽象。(template 笑而不语)局部使用 OOP 设计模式来实现模块,并暴露简单接口,是可以起到提升代码质量和逼格的效果。然而在架构层面滥用,往往只是把逻辑中的复杂度转移到架构复杂度上。滥用设计模式导致的复杂架构,并不对可读性和可维护性有帮助。比如原本 c style 只要一个文件顺序读下来就能了解清楚的模块,滥用设计模式的 OOP 实现,阅读代码时有可能需要在十几个文件中来回跳转,还需要人脑去正确保证阅读代码的上下文...过多的抽象导致过多的中间层次,却只是把耦合一层一层传递。直到最后结合反射 + IoC框架 + 数据驱动,才算有了靠谱的解决方案。然而一提到反射,C++表示我的蛋蛋有点疼。那么,有没有办法简化和沉淀出游戏开发领域较通用的模式?未脱离 OO 思想的 Entity Component 模式 案例:Unity3DUnity3D 是个使用了 Entity Component 模式的成功的商业引擎。相信使用过 Unity3D 的童鞋,都知道 Unity3D 的 Entity Component 模式是怎么回事。(在Unity3D 中,Entity 叫 GameObject)。其优点:组件复用。体现了 ECS 的基本思想之一,Entity 由 Component 组成,而不是具体逻辑对象。设计得好的 Component 是可以高度复用的。数据驱动。场景创建、游戏实体创建,主要源于数据而不是硬编码。以此为基础,引擎实现了以编辑器为中心的开发模式。编辑器为中心。用户可在编辑器中可视化地编辑和配置 Entity 和 Component 的关系,修改属性和配置数据。在有成熟 Component 集合的情况下,新的关卡和玩法的开发,都可以完全不需要改动代码,由策划通过编辑器实现。看起来,Unity3D 已经在很大程度上解决了游戏设计领域通用模式的问题。然而,其 Entity Component 模式仍然存在一些问题:Component 仍然延续了一些 OOP 的思路。比如:Component 是数据和行为的封装。虽然此概念容易导致的问题可以通过其它方式避免,但以不加思考照着最自然的方式去做,往往会造成 Component 后期的膨胀。比如 Component 需要支持不同的行为就定义了不同的函数和相关变量;Component 之间有互相依赖的话逻辑该写在哪个 Component 中;多个 Component 逻辑上互相依赖之后,就难以实现单个 Component 级别的复用,最后的引用链有可能都涉及了代码库中大部分 Component 等等。Component 是支持多态的引用语义。这意味着单个 Component 需要单独在堆上分配,难以实现下文所提到的,对同类型多个 Component 进行数据局部性友好的存储方式。这样的存储方式好处在于,批量处理可以减少 cache miss 和内存换页的情况。当前主流的 Entity Component System 架构 案例:EntityX那么,综合以上所说的各种问题,一个基于 C++ 的现代 Entity Component System,应该是什么样子?具体案例,可以参考 [EntityX](),一个开源的 C++ ECS 框架。一一实现了前述现代 ECS 的各种概念:Entity 只是个 ID,Component 存储数据,System 实现关联多个 Component 的行为。代码味道:struct Position {
Position(float x = 0.0f, float y = 0.0f) : x(x), y(y) {}
float x, y;
struct Direction {
Direction(float x = 0.0f, float y = 0.0f) : x(x), y(y) {}
float x, y;
struct MovementSystem : public System&MovementSystem& {
void update(entityx::EntityManager &es, entityx::EventManager &events, TimeDelta dt) override {
es.each&Position, Direction&([dt](Entity entity, Position &position, Direction &direction) {
position.x += direction.x * dt;
position.y += direction.y * dt;
如上,实现了两类 Component:Position 和 Direction。MovementSystem 只关心同时具有两类 Component 的 Entity。一些值得说的特点:低抽象代价。C++ 的模板特性,便于把不少在其他语言中难以避免的运行时开销,转移到编译时。同类的多个 Component 实现了紧凑连续的内存布局。这个特性为什么重要?请参考[这个问题]()
的回答。同时这也是 Unity3D 的 Entity Component 模式难以做到的。当遍历同类 Component 时,数据存储于连续的内存空间中,可以大大提高缓存命中率。Component 只有数据,行为是 System 的事。这样的模式,避免了上一节提到的 Unity3D 中容易出现的问题。Component 没有逻辑上的互相引用,Component 的耦合和依赖由 System 处理。此外,由 System 进行统一的状态修改,也有利于定位和隔离问题。System 间的解耦,主要通过事件回调。System 之间不提倡互相引用,通过 Signal 来实现 publish / subscribe 进行处理。《守望先锋》也提到了关于 System 间发生了耦合的麻烦情况通常用 Singleton 模式和把共用代码放进 Utils 解决。 追加ECS 的进一步优化除了可以提高缓存命中率外,新世代的 ECS 还可以通过分析数据依赖和读写关系,来实现 System 间的并行。比如更新时, System A 需要读 组件1,System B 需要读 组件1、写组件2,System C 需要写 组件1,那么调度时可以把 System A 和 System B 分配到不同线程处理,之后再处理 System C。原贴中也一笔带过提到了这方面的优化。然而对于复杂的 C++ 游戏来说,这个目标在实践上的可行性具有比较大的障碍:难以确保团队中的熊孩子不小心写出非线程安全的代码。不过,Rust 给这个问题带来了解决方案。可以参考 Rust 实现的并行 ECS 框架:Rust 的语言特性在编译期保证了线程安全,只需声明一下 System 对 Component 的访问权限如:
type SystemData = (ReadStorage&'a, Velocity&,
WriteStorage&'a, Position&);
这样,即可安全地获得多线程带来的性能提升。15720 条评论分享收藏感谢收起20546 条评论分享收藏感谢收起查看更多回答如何评价张艺兴? - 知乎6277被浏览3474432分享邀请回答63224 条评论分享收藏感谢收起1.8K171 条评论分享收藏感谢收起查看更多回答

我要回帖

更多关于 淘宝网评价会改变吗 的文章

 

随机推荐