简体   繁体   English

AS3,回收八哥物件

[英]AS3, recycling starling objects

We are a couple of guys making a game. 我们是几个做游戏的家伙。 Game entities' data are stored in nested arrays. 游戏实体的数据存储在嵌套数组中。 The top level array contains arrays, which correspond to one entity each. 顶层数组包含每个对应于一个实体的数组。 By entity I mean the game objects' parameters stored in the array and the starling object referred to in the array. 实体是指存储在数组中的游戏对象的参数以及数组中引用的八哥对象。

These sub-arrays have a reference to a starling movieclip or a starling sprite and around 15 other variables for that entity. 这些子数组引用了八哥电影剪辑或八哥精灵,以及该实体的大约15个其他变量。 The variables are therefore not stored in the movieclip/sprite itself for various reasons. 因此,由于各种原因,这些变量未存储在动画片段/子画面本身中。 The possibility of Blitting is one of them. 产生斑点的可能性就是其中之一。

The question is then how to organize this the best way and eventually implement recycling of the starling objects to get less problems with garbage collection. 然后的问题是如何以最好的方式组织这种方法,并最终实现八哥对象的回收,以减少垃圾回收的麻烦。 I have three suggestions, but I am aware, that something else could be better. 我有三个建议,但我知道,还有其他更好的方法。

1) have one 'graveyard' container for each class of object: one for asteroids, one for playershots, one for .... Whenever an entity is destroyed, corresponding object will go to the correct graveyard. 1)每个类别的物体都有一个“墓地”容器:一个用于小行星,一个用于玩家射击,一个用于...。每当一个实体被摧毁时,相应的物体都会进入正确的墓地。 Whenever an entity of same class should be created, then reuse one from corresponding container if it holds any. 每当应创建相同类的实体时,如果它包含任何实体,则从相应的容器中重用一个实体。

2) One big container for all destroyed movieclips and sprites. 2)一个用于存放所有被破坏的电影剪辑和子画面的大容器。 Whenever a sprite or movieclip would spawn, reuse the object from this container if it holds any. 只要会生成精灵或动画片段,就可以重用此容器中保存的对象。 Correct Animation should also be set. 还应该设置正确的动画。 I don't know if that takes a lot of cpu or is possible at all. 我不知道这是否需要大量的CPU或根本不可能。

3) Let garbage collection take care of destroyed movieclips and sprites. 3)让垃圾收集处理被破坏的影片剪辑和子画面。 Don't recycle them. 不要回收它们。

personally, when i want to do stuff like this i override the base Class i want to use and add some code to do that you want: 就个人而言,当我想做这样的事情时,我会覆盖我要使用的基本类,并添加一些代码来执行您想要的操作:

For example Asteroid class extending MovieClip : 例如,Asteroid类扩展了MovieClip:

package
{
    import starling.display.MovieClip;
    import starling.textures.Texture;

    public class Asteroid extends MovieClip
    {
        /** a object pool for the Asteroids **/
        protected static var _pool      :Vector.<Asteroid>;
        /** the number of objects in the pool **/
        protected static var _nbItems   :int;
        /** a static variable containing the textures **/
        protected static var _textures  :Vector.<Texture>;
        /** a static variable containing the textures **/
        protected static var _fps       :int;

        public function Asteroid()
        {
            super( _textures, 60 );
        }

        /** a static function to initialize the asteroids textures and fps and to create the pool **/
        public static function init(textures:Vector.<Texture>, fps:int):void
        {
            _textures   = textures;
            _fps        = fps;

            _pool       = new Vector.<Asteroid>();
            _nbItems    = 0;
        }

        /** the function to call to release the object and return it to the pool **/
        public function release():void
        {
            // make sure it don't have listeners
            this.removeEventListeners();
            // put it in the pool
            _pool[_nbItems++] = this;
        }

        /** a static function to get an asteroid from the pool **/
        public static function get():Asteroid
        {
            var a   :Asteroid;
            if( _nbItems > 0 )
            {
                a = _pool.pop();
                _nbItems--;
            }
            else
            {
                a = new Asteroid();
            }
            return a;
        }

        /** a static function to destroy asteroids and the pool **/
        public static function dispose():void
        {
            for( var i:int = 0; i<_nbItems; ++i )   _pool[i].removeFromParent(true);
            _pool.length = 0;
            _pool = null;
        }
    }
}

So with that you can have an asteroid with the Asteroid.get(); 这样一来,您可以通过Asteroid.get();获得一个小行星Asteroid.get(); method, this will get an asteroid in the pool or create one if the pool is empty. 方法,这将在池中获取一个小行星,如果池为空则创建一个小行星。

Before you have to init the class with the static function Asteroid.init(textures, fps) 在必须使用静态函数Asteroid.init(textures, fps)初始化类之前

When you don't need asteroid anymore you can call myAsteroid.release(); 当您不再需要小行星时,可以调用myAsteroid.release(); this will return the asteroid to the pool for a next use. 这将使小行星返回水池以备下次使用。

When you don't need asteroids anymore, you can call the static Asteroid.dispose(); 当您不再需要小行星时,可以调用静态Asteroid.dispose(); to clear the pool. 清理游泳池。

Hope this could help you. 希望这可以对您有所帮助。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM