Sprite和Group用作容器的异同

我们经常会用到容器的概念,在Phaser中,最常用作容器的就是Group和Sprite。Word就是游戏中最底层的一个容器。 在此,整理了一下以Sprite与Group用作容器的异同,纯属个人理解,供参考。


添加子对象的方法

Sprite用addChild(child); Group用add(child);

两者都继承了DisplayObjectContainer

Sprite和Group的容器功能都继承自DisplayObjectContainer,但DisplayObjectContainer的一些原有的属性方法在Sprite中被重写了,比如width、height、getBounds()等;而Group则完整的继承了DisplayObjectContainer的属性方法,如果单纯作为容器使用,Group应该更合适,更专业。

关于Texture和层级关系

Sprite有自己的texture,显示内容将会在它所有children的最底层,相当于背景(根据先画的垫底,后画的在上的渲染规则,以及先有父才有子的关系,所以不难理解) 而Group 没有自己的texture,他只是一个纯容器,如同空气没有显示的东西,所以他自身跟children没有显示上的层级关系,只有children们各自之间的层级关系

与children的坐标关系

Sprite 的children坐标位置是相对于父级Sprite的,即会随父级Sprite的移动而移动。(这是常用的而且合乎常理的逻辑) Group的坐标默认都是0的,因为创建时没有坐标的参数,(之前没做测试,以为没有用的,惭愧),其实跟sprite一样它的子对象坐标都是相对坐标,它的所有子对象都会跟随父级group移动的。 注意:一般很少改变group的坐标,可能大多情况下我们只关注它的子对象,而不是这个group本身,而且碰撞检测都是针对子对象分别进行的(group没有自身的物理属性);如果改变了group的坐标,读取子对象的坐标时,就要注意,你要的是xy还是world.x和world.y了。

关于包含children的总尺寸

有时,我们需要知道添加的children后这个Sprite总的尺寸,比如一些有多个显示对象组成的sprite组合体(里面可能有各种显示对象如sprite、text、image等)。 如果Sprite作为容器,你无法用width/height得到他包含了children的总尺寸; 但是group却可以!因为刚才说了,Group完整的继承了DisplayObjectContainer的属性方法,他的width、height就是干这个的(而在sprite中这些属性方法被覆盖重写了)。所以说作为容器,Group更专业!

问题来了

那么,我们想要一个组合的Sprite,需要子对象的坐标位置都随父级变化,有自己的物理属性,又想方便地知道这个Sprite包含所有子对象的总尺寸,怎么办? 也许你应该想到了,用这两者的组合!(OK,讲这么多,该上点代码了……) 具体实现是:

var sprite = game.add.sprite(x,y);
sprite.childrenGroup = sprite.addChild(game.make.group());  // 添加一个Group作为sprite唯一的下级子对象
sprite.childrenGroup.add(child);  // 所有子对象通过这种方式添加到这个Group中
var allWidth = sprite.childrenGroup.width;  // 获取这个Group的尺寸就是总尺寸了,如果子对象是动态的,可以根据总尺寸实时更新父级的body尺寸

OK, just enjoy it !