2 votes

Comment améliorer les performances d'un swf lorsque plusieurs sprites statiques sont ajoutés à la scène ?

Je fais une application qui met des tonnes de sprites sur l'écran dans des positions aléatoires, comme jeter des cartes sur une table, mais après un certain temps, il commence à baisser les fps, parce que tous les sprites sont toujours consommer des ressources. Ce que je voudrais faire, c'est ajouter les sprites mais comme une image, sans qu'ils soient redessinés. Existe-t-il un moyen de le faire ?

le code ressemble à ceci :

var mySprite:MySprite = new MySprite();
mySprite.x = random;
mySprite.y = random;
mySprite.rotation = random;
addChild(mySprite);

Ps : je n'aurai pas à m'occuper d'eux une fois qu'ils seront sur l'écran.

1voto

JcFx Points 6266

Je pense cacheAsBitmap est ce que vous recherchez : http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObject.html#cacheAsBitmap

var mySprite:MySprite = new MySprite();
mySprite.x = random;
mySprite.y = random;
mySprite.rotation = random;
mySprite.cacheAsBitmap = true;
addChild(mySprite);

Il convient de lire attentivement la documentation et de consulter un peu Google : la mise en cache d'un Sprite en tant que Bitmap n'offre pas nécessairement de meilleures performances dans tous les cas.

1voto

Vesper Points 9507

Si vous n'avez pas à vous embrouiller, vous pourriez envisager d'avoir un objet Bitmap au lieu de plusieurs Sprites, et au lieu de les ajouter en tant qu'enfant, vous les dessinez() sur un bitmapData de ce Bitmap, et vous les jetez. Un exemple :

var mySprite:Sprite=new MySprite();
var myMat:Matrix=new Matrix();
for (i=100;i;i--) {
    myMat.identity();
    myMat.rotate(myRandom());
    myMat.translate(myRandom(),myRandom()); // set correct randoms here
    myBitmap.bitmapData.draw(mySprite,myMat);
}

Vous recevez ainsi un seul bitmap sur lequel sont dessinés 100 MySprites identiques. Si votre classe MySprite comporte une randomisation dans son constructeur, vous pouvez également ré-instancier la fonction mySprite variable à chaque fois.

1voto

Marcelo Assis Points 2438

Jetez un coup d'œil à cette impressionnante article .
J'ai fait quelques changements pour qu'il renvoie un sprite, au lieu d'en être un.

Vous pouvez en savoir plus dans l'article, mais cette classe récupère essentiellement les données bitmap de l'actif, et les met en cache dans un objet. Chaque fois que vous avez besoin d'une autre instance de cet actif, vous obtenez les données bitmap mises en cache. Vous pouvez améliorer beaucoup plus, en utilisant cette technique, en définissant les paramètres suivants qualité de la scène à faible .
Cette technique est meilleure que la simple utilisation de cacheAsBitmap car vous pouvez utiliser un Sprite, au lieu d'un bitmap plat, tout en ayant les données bitmap mises en cache.

    public class CachedSpriteFactory
    {
        //Declare a static data cache
        protected static var cachedData:Object = {};        
        public static var clip:Bitmap;

        public function cacheSprite(asset:Object, scale:int = 2):Sprite
        {
            //Check the cache to see if we've already cached this asset
            var data:BitmapData = cachedData[getQualifiedClassName(asset)];
            if (!data)
            {
                var instance:Sprite = new asset();
                var bounds:Rectangle = instance.getBounds(this);

                //Optionally, use a matrix to up-scale the vector asset, this way you can increase scale later and it still looks good.
                var m:Matrix = new Matrix();
                m.translate(-bounds.x, -bounds.y);
                m.scale(scale, scale);              
                data = new BitmapData(bounds.width * scale, bounds.height * scale, true, 0x0);              
                data.draw(instance, m, null, null, null, true);
                cachedData[getQualifiedClassName(asset)] = data;
            }

            clip = new Bitmap(data, "auto", true);
            //Use the bitmap class to inversely scale, so the asset still appear to be it's normal size
            clip.scaleX = clip.scaleY = 1/scale;
            var sprite:Sprite = new Sprite();
            sprite.addChild(clip);
            //Optimize mouse children
            sprite.mouseChildren = false;

            return sprite;
        }
    }

Utilisation :

stage.quality = StageQuality.HIGH
var cacheFactory:CachedSpriteFactory = new CachedSpriteFactory();
var coolSprite1:Sprite = cacheFactory.cacheSprite(SpriteLinkageNameInLibrary, 1);
var coolSprite2:Sprite = cacheFactory.cacheSprite(SpriteLinkageNameInLibrary, 1);
stage.quality = StageQuality.LOW

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X