第二章:图像显示

本章内容源自于:Visualization

第一章中我们建立一个大致的游戏框架并在屏幕上显示了一艘飞船,但还没有使用实体系统。尽管我们写好了实体系统,但是还没有真正用到。这一章我们将真正地使用实体系统,我发誓。

敌人


没有入侵者的入侵者游戏的确不是一款入侵者游戏,因此你需要再次打开你的Blender给敌人制作一个模型。当然你也可以从google drive(译者:第一章中的网盘已经包含了所有资源,请国内读者找找看)获取我已经做好的模型。我把它称为:BasicInvader。(译者:我们目前做的这款游戏叫《太空入侵者》,玩法类似于红白机上的《小蜜蜂》。我们将操作“星际战舰”消灭这些“入侵者”)

现在我们使用实体系统来存储大量的入侵者实体和一个星际战舰实体。我们需要做什么才能让太空战舰和入侵者们显示到屏幕上?需要位置和模型,然后根据位置把模型设置到屏幕上。通常情况下,此时你会创建各种类对象,这些对象继承入侵者类或太空战舰类等等。或许你还会滥用Spatial类的userData存储一些游戏逻辑,然后把事情搞得一团糟,像意大利面一样。至少在我身上就发生过这种事情。为此,把图像显示这部分从游戏逻辑中分离出去就是一个非常聪明的主意。实体系统把这种想法发挥得淋漓尽致。使用实体系统,我们可以在任何时候扩展飞船的任何功能而无需触碰已经写好的那部分代码。甚至属性和方法也都是分离的——这完全违反了面向对象编程。因此如果你是个十足的面向对象编程人员,接下来的代码可能会使你感到困惑。但请耐心看完教程、耐心理解。

我的位置坐标是什么?


我们的飞船和敌人都需要位置,位置组件则是可以为他们提供位置信息的类:

位置组件类

你可以看到,组件类中只有纯粹的数据,并且不可更改。这种机制可以帮助我们在多线程情况下不必考虑线程同步的问题。我们将在教程进阶篇——局域网开发中用到这一特性。

我长什么样子?


为了告诉系统应该给对象加载哪个模型,我们应该给对象添加模型组件。如同创建位置组件类那样,模型组件也是只有属性并且不可修改:

模型组件类

为避免敲错名字,我在模型组件类中添加了两个静态常量字符串:SpaceShip和BasickInvader。现在,我们得瞧瞧它们该怎么用。

创建实体


最后我们用实体系统存储太空战舰与入侵者的数据。实体说白了就是ID。你得把组件和实体绑定到一起,这样实体才有意义。然后你就可以通过组件追查到实体,例如通过位置组件和模型组件查询太空战舰和入侵者实体。就像是使用数据库那样。现在我们需要一个运行游戏的AppState,它可以在游戏开始时创建敌人,敌人被消灭完后又会重新刷一波新敌人等等。我们先写个超级简单的,以后再慢慢地丰富它的功能:

游戏系统

当前我们只是显示太空战舰和入侵者,这就够了。这足以说明实体系统是怎么运行的了。

显示它们


本章重点来了。第一次用实体系统显示入侵者和我们的太空战舰。请用下列代码替换我们之前写的VisualAppState:

显示系统类

上述代码使用了一种实体系统中的设计模式,你将会经常使用这种设计模式,至少在客户端中是这样。

细节讲解


所以我们在显示系统类中究竟做了些什么?首先我们定义了一个我们要操作的实体集合:

代码段

我们要操作所有具有位置和模型的实体。这段代码就是把同时所有具有位置和模型的实体找出来,也就是入侵者与星际战舰这两种实体。

接下来是更新循环,所有游戏的核心所在。JME会给每个AppState提供一个update()方法:

代码段

我们在更新循环中检查实体集合中是否有实体的实体组件发生了改变、有了新的同时拥有位置和模型的实体、原实体集合中有实体不再拥有位置组件或模型组件了。

所有的Spatial都通过成员变量HashMap与实体相关联:

代码段

这样我们稍后就能移除掉已经添加到视图结点上的实体模型了。让我看一下移除实体方法:

代码段

Spatial被储存在HashMap中。当有实体被移除时,我们可以通过HashMap找到对应的Spatial并把它从视图结点中移除掉。当然,移除实体的前提是添加实体。添加实体的方法在addModels()方法中:

代码段

你可以看到,我们把所有的Spatial都储存在HashMap中。并且为了能看到,我们把Spatial关联到了rootNode上。

updateModels()方法十分简单:就是通过id找到Spatial,然后更新Spatial的位置。

最后,修改主类的构造方法,使它看起来像是这样:

修改主类构造方法

大功告成,你的第一个由实体系统驱动的软件。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,039评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,223评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 161,916评论 0 351
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,009评论 1 291
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,030评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,011评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,934评论 3 416
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,754评论 0 271
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,202评论 1 309
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,433评论 2 331
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,590评论 1 346
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,321评论 5 342
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,917评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,568评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,738评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,583评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,482评论 2 352

推荐阅读更多精彩内容