2 Stimmen

Optimierung meiner dynamischen Hintergrund-Engine für ein 2d-Flash-Spiel in Actionscript-3

Edit 2: Nach dem Mangel an Antworten zu urteilen, frage ich mich, ob mein Problem klar genug ist. Bitte sagen Sie mir, wenn ich mehr ausführen muss.

Hinweis: siehe unten für ein Code-Update!

Kurze Einführung: Ich schreibe ein 2-dimensionales Flash-Raumspiel in Actionscript. Das Universum ist unendlich groß, deshalb muss der Hintergrund dynamisch gerendert werden und die Hintergrundobjekte (Gaswolken, Sterne, etc.) müssen zufällig positioniert werden.

Ich habe eine Klasse namens BackgroundEngine erstellt und sie funktioniert sehr gut, das Problem ist jedoch die Rendering-Leistung. Dies ist, wie es funktioniert:

Beim Start werden 4 Hintergrundcontainer (jeder so groß wie die Bühne) um den Spieler herum erstellt. Oben links, oben rechts, unten links und unten rechts. Alle Hintergrundquadrate werden zu einem Hauptcontainer hinzugefügt, damit der Hintergrund leicht verschoben werden kann. Jetzt gibt es 2 Abfragefunktionen:

1) "garbage poller": sucht nach Hintergrundcontainern, die 2 mal die Bühnenbreite oder -höhe von der X- bzw. Y-Koordinate des Spielers entfernt sind. Ist dies der Fall, wird das Hintergrundquadrat entfernt und für die Müllabfuhr freigegeben.

2) "Rendering Poller": prüft, ob an allen Seiten des Spielers (x - stageWidth, x + stageWidth, y - stageHeight, y + stageHeight) bereits ein Hintergrund vorhanden ist. Wenn nicht, wird ein neues Hintergrundquadrat an der entsprechenden Stelle gezeichnet.

Alle Hintergrundquadrate werden mit der folgenden Funktion erstellt (diejenigen, die dynamisch erstellt werden, und die vier beim Starten):

<<< alten Code entfernt, siehe unten für aktualisierten vollständigen Quelltext >>>

All die Randoms, die man dort sieht, sorgen dafür, dass die Umgebung auf jedem Platz ganz einzigartig aussieht. Das funktioniert wirklich großartig, das Universum sieht ziemlich fantastisch aus.

Die folgenden Assets werden als Hintergrundobjekte verwendet:

1) Einfache Sterne : http://www.feedpostal.com/client/assets/background/1.png (in einem Browser mit weißem Hintergrund werden Sie das wahrscheinlich nicht sehen können).

2) Helle Sterne : http://www.feedpostal.com/client/assets/background/2.png

3) Weiße Gaswolken : http://www.feedpostal.com/client/assets/background/3.png

4) Rote Gaswolken: http://www.feedpostal.com/client/assets/background/4.png

Wichtige Hinweise:

1) Alle Inhalte werden zwischengespeichert, so dass sie nicht immer wieder neu heruntergeladen werden müssen. Sie werden nur einmal heruntergeladen.

2) Die Bilder werden nicht gedreht oder skaliert, nachdem sie erstellt wurden, also habe ich cacheAsBitmap für alle Objekte, Container und den masterContainer aktiviert.

3) Ich musste in Photoshop PNG-Formate verwenden, da GIFs in Flash nicht sehr gut gerendert werden, wenn sie mit Transparenz verwendet werden.

Also, das Problem ist, dass wenn ich herumfliege das Rendering des Hintergrunds zu viel Leistung nimmt: der Client beginnt "lagging" (FPS-weise). Aus diesem Grund muss ich die Hintergrund-Engine optimieren, so dass es viel schneller gerendert wird. Könnt ihr mir hier helfen?

Aktualisierung 1: Dies ist der Stand der Dinge nach der einen Antwort, die ich erhalten habe.

BackgroundEngine.as

package com.tommedema.background
{
    import br.com.stimuli.loading.BulkLoader;

    import com.tommedema.utils.Settings;
    import com.tommedema.utils.UtilLib;

    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;

    public final class BackgroundEngine extends Sprite
    {
        private static var isLoaded:Boolean = false;
        private static var bulkLoader:BulkLoader = BulkLoader.getLoader("main");
        private static var masterContainer:Sprite;
        private static var containers:Array = [];
        private static var stageWidth:uint;
        private static var stageHeight:uint;
        private static var assets:Array;

        //moves the background's X coord
        public static function moveX(amount:Number):void
        {
            if (masterContainer)
            {
                masterContainer.x += amount;
                collectGarbage();
                drawNextContainer();
            }
        }

        //moves the background's Y coord
        public static function moveY(amount:Number):void
        {
            if (masterContainer)
            {
                masterContainer.y += amount;
                collectGarbage();
                drawNextContainer();
            }
        }

        //returns whether the background engine has been loaded already
        public static function loaded():Boolean
        {
            return isLoaded;
        }

        //loads the background engine
        public final function load():void
        {
            //set stage width and height
            stageWidth = stage.stageWidth;
            stageHeight = stage.stageHeight;

            //retreive all background assets
            bulkLoader.add(Settings.ASSETS_PRE_URL + "background/1.png", {id: "background/1.png"});
            bulkLoader.add(Settings.ASSETS_PRE_URL + "background/2.png", {id: "background/2.png"});
            bulkLoader.add(Settings.ASSETS_PRE_URL + "background/3.png", {id: "background/3.png"});
            bulkLoader.add(Settings.ASSETS_PRE_URL + "background/4.png", {id: "background/4.png"});
            bulkLoader.addEventListener(BulkLoader.COMPLETE, assetsComplete);
            bulkLoader.start();

            //set isLoaded to true
            isLoaded = true;
        }

        //poller function for drawing next background squares
        private static function drawNextContainer():void
        {
            var stageCenterX:Number = stageWidth / 2;
            var stageCenterY:Number = stageHeight / 2;
            var curContainer:Bitmap = hasBackground(stageCenterX, stageCenterY);
            if (curContainer)
            {
                //top left
                if (!hasBackground(stageCenterX - stageWidth, stageCenterY - stageHeight)) drawNewSquare(curContainer.x - stageWidth, curContainer.y - stageHeight);
                //top
                if (!hasBackground(stageCenterX, stageCenterY - stageHeight)) drawNewSquare(curContainer.x, curContainer.y - stageHeight);
                //top right
                if (!hasBackground(stageCenterX + stageWidth, stageCenterY - stageHeight)) drawNewSquare(curContainer.x + stageWidth, curContainer.y - stageHeight);
                //center left
                if (!hasBackground(stageCenterX - stageWidth, stageCenterY)) drawNewSquare(curContainer.x - stageWidth, curContainer.y);
                //center right
                if (!hasBackground(stageCenterX + stageWidth, stageCenterY)) drawNewSquare(curContainer.x + stageWidth, curContainer.y);
                //bottom left
                if (!hasBackground(stageCenterX - stageWidth, stageCenterY + stageHeight)) drawNewSquare(curContainer.x - stageWidth, curContainer.y + stageHeight);
                //bottom
                if (!hasBackground(stageCenterX, stageCenterY + stageHeight)) drawNewSquare(curContainer.x, curContainer.y + stageHeight);
                //bottom right
                if (!hasBackground(stageCenterX + stageWidth, stageCenterY + stageHeight)) drawNewSquare(curContainer.x + stageWidth, curContainer.y + stageHeight);
            }
        }

        //draws the next square and adds it to the master container
        private static function drawNewSquare(x:Number, y:Number):void
        {
            containers.push(genSquareBg());
            var cIndex:uint = containers.length - 1;
            containers[cIndex].x = x;
            containers[cIndex].y = y;
            masterContainer.addChild(containers[cIndex]);
        }

        //returns whether the given location has a background and if so returns the corresponding square
        private static function hasBackground(x:Number, y:Number):Bitmap
        {
            var stageX:Number;
            var stageY:Number;
            for(var i:uint = 0; i < containers.length; i++)
            {
                stageX = masterContainer.x + containers[i].x;
                stageY = masterContainer.y + containers[i].y;
                if ((containers[i]) && (stageX < x) && (stageX + stageWidth > x) && (stageY < y) && (stageY + stageHeight > y)) return containers[i];
            }
            return null;
        }

        //polling function for old background squares garbage collection
        private static function collectGarbage():void
        {
            var stageX:Number;
            var stageY:Number;

            for(var i:uint = 0; i < containers.length; i++)
            {
                if (containers[i])
                {
                    stageX = masterContainer.x + containers[i].x;
                    stageY = masterContainer.y + containers[i].y;
                    if ((stageX < -stageWidth * 1.5) || (stageX > stageWidth * 2.5) || (stageY < -stageHeight * 1.5) || (stageY > stageHeight * 2.5))
                    {
                        containers[i].parent.removeChild(containers[i]);
                        containers.splice(i, 1);
                    }
                }
            }
        }

        //dispatched when all assets have finished downloading
        private final function assetsComplete(event:Event):void
        {
            assets = [];
            assets.push(bulkLoader.getBitmap("background/1.png")); //star simple
            assets.push(bulkLoader.getBitmap("background/2.png")); //star bright
            assets.push(bulkLoader.getBitmap("background/3.png")); //cloud white
            assets.push(bulkLoader.getBitmap("background/4.png")); //cloud red
            init();
        }

        //initializes startup background containers
        private final function init():void
        {
            masterContainer = new Sprite(); //create master container

            //generate default background containers
            containers.push(genSquareBg()); //top left
            containers[0].x = 0;
            containers[0].y = 0;
            containers.push(genSquareBg()); //top
            containers[1].x = stageWidth;
            containers[1].y = 0;
            containers.push(genSquareBg()); //top right
            containers[2].x = stageWidth * 2;
            containers[2].y = 0;
            containers.push(genSquareBg()); //center left
            containers[3].x = 0;
            containers[3].y = stageHeight;
            containers.push(genSquareBg()); //center
            containers[4].x = stageWidth;
            containers[4].y = stageHeight;
            containers.push(genSquareBg()); //center right
            containers[5].x = stageWidth * 2;
            containers[5].y = stageHeight;
            containers.push(genSquareBg()); //bottom left
            containers[6].x = 0;
            containers[6].y = stageHeight * 2;
            containers.push(genSquareBg()); //bottom
            containers[7].x = stageWidth;
            containers[7].y = stageHeight * 2;
            containers.push(genSquareBg()); //bottom right
            containers[8].x = stageWidth * 2;
            containers[8].y = stageHeight * 2;

            //add the new containers to the master container
            for (var i:uint = 0; i <= containers.length - 1; i++)
            {
                masterContainer.addChild(containers[i]);    
            }

            //display the master container
            masterContainer.x = 0 - stageWidth;
            masterContainer.y = 0 - stageHeight;
            masterContainer.cacheAsBitmap = true;
            addChild(masterContainer);
        }

        //duplicates a bitmap display object
        private static function dupeBitmap(source:Bitmap):Bitmap {
            var data:BitmapData = source.bitmapData;
            var bitmap:Bitmap = new Bitmap(data);
            return bitmap;
        }

        //draws a simple star
    private static function drawStar(x:Number, y:Number, width:uint, height:uint):Sprite
    {
        var creation:Sprite = new Sprite();
        creation.graphics.lineStyle(1, 0xFFFFFF);
        creation.graphics.beginFill(0xFFFFFF);
        creation.graphics.drawRect(x, y, width, height);
        return creation;
    }

    //generates a background square
    private static function genSquareBg():Bitmap
    {
        //set 1% margin
        var width:Number = stageWidth * 0.99;
        var height:Number = stageHeight * 0.99;
        var startX:Number = 0 + stageWidth / 100;
        var startY:Number = 0 + stageHeight / 100;

        var scale:Number;
        var drawAmount:uint;
        var tmpBitmap:Bitmap;
        var tmpSprite:Sprite;
        var i:uint;

        //create container
        var container:Sprite = new Sprite();

        //draw simple stars
        drawAmount = UtilLib.getRandomInt(100, 250);
        for(i = 1; i <= drawAmount; i++)
        {
            tmpSprite = drawStar(0, 0, 1, 1);
            tmpSprite.x = UtilLib.getRandomInt(0, stageWidth);
            tmpSprite.y = UtilLib.getRandomInt(0, stageHeight);
            tmpSprite.alpha = UtilLib.getRandomInt(3, 10) / 10;
            scale = UtilLib.getRandomInt(2, 10) / 10;
            tmpSprite.scaleX = tmpSprite.scaleY = scale;
            container.addChild(tmpSprite);
        }

        //draw bright stars
        if (Math.random() >= 0.8) drawAmount = UtilLib.getRandomInt(1, 2);
        else drawAmount = 0;
        for(i = 1; i <= drawAmount; i++)
        {
            tmpBitmap = dupeBitmap(assets[1]);
            tmpBitmap.alpha = UtilLib.getRandomInt(3, 7) / 10;
            tmpBitmap.rotation = UtilLib.getRandomInt(0, 360);
            scale = UtilLib.getRandomInt(3, 10) / 10;
            tmpBitmap.scaleX = scale; tmpBitmap.scaleY = scale;
            tmpBitmap.x = UtilLib.getRandomInt(startX + tmpBitmap.width, width - tmpBitmap.width);
            tmpBitmap.y = UtilLib.getRandomInt(startY + tmpBitmap.height, height - tmpBitmap.height);
            container.addChild(tmpBitmap);
        }

        //draw white clouds
        drawAmount = UtilLib.getRandomInt(1, 4);
        for(i = 1; i <= drawAmount; i++)
        {
            tmpBitmap = dupeBitmap(assets[2]);
            tmpBitmap.alpha = UtilLib.getRandomInt(1, 10) / 10;
            scale = UtilLib.getRandomInt(15, 30);
            tmpBitmap.scaleX = scale / 10;
            tmpBitmap.scaleY = UtilLib.getRandomInt(scale / 2, scale) / 10;
            tmpBitmap.x = UtilLib.getRandomInt(startX, width - tmpBitmap.width);
            tmpBitmap.y = UtilLib.getRandomInt(startY, height - tmpBitmap.height);
            container.addChild(tmpBitmap);
        }

        //draw red clouds
        drawAmount = UtilLib.getRandomInt(0, 1);
        for(i = 1; i <= drawAmount; i++)
        {
            tmpBitmap = dupeBitmap(assets[3]);
            tmpBitmap.alpha = UtilLib.getRandomInt(2, 6) / 10;
            scale = UtilLib.getRandomInt(5, 30) / 10;
            tmpBitmap.scaleX = scale; tmpBitmap.scaleY = scale;
            tmpBitmap.x = UtilLib.getRandomInt(startX, width - tmpBitmap.width);
            tmpBitmap.y = UtilLib.getRandomInt(startY, height - tmpBitmap.height);
            container.addChild(tmpBitmap);
        }

        //convert all layers to a single bitmap layer and return
        var bitmapData:BitmapData = new BitmapData(stageWidth, stageHeight, true, 0x000000);
        bitmapData.draw(container);
        container = null;
        var bitmapContainer:Bitmap = new Bitmap(bitmapData);
        bitmapContainer.cacheAsBitmap = true;
        return bitmapContainer;
    }
    }
}

Wenn sich der Spieler bewegt, werden die Hintergrundmethoden moveX und moveY mit der umgekehrten Richtung des Spielers aufgerufen. Dies führt auch dazu, dass die Methoden collectGarbage und drawNextContainer aufgerufen werden.

Das Problem bei dieser Konfiguration ist, dass immer mindestens 9 Container aktiv sind. Oben links, oben, oben rechts, Mitte links, Mitte, Mitte rechts, unten links, unten und unten rechts. Das erfordert eine Menge Leistung.

Bearbeiten: Ich frage mich auch, sollte ich cacheAsBitmap verwenden? Wenn ja, auf welchen Images? Auf den Containern und dem Master-Container oder nur auf einem von ihnen? Wenn ich es für alle Bilder (auch die temporären Sprite-Objekte) aktivieren, ist es tatsächlich mehr verzögert.

Update 2:

Bei dieser Version werden Quadrate verwendet, die doppelt so groß sind wie die Bühne. Es sollten immer nur ein oder zwei Quadrate auf einmal geladen werden. Das ist besser, aber ich bemerke immer noch einen Leistungsabfall beim Bewegen. Dadurch friert der Client für einen kurzen Moment ein. Hat jemand eine Idee, wie man das optimieren kann?

BackgroundEngine2.as

package com.tommedema.background
{
    import br.com.stimuli.loading.BulkLoader;

    import com.tommedema.utils.Settings;
    import com.tommedema.utils.UtilLib;

    import flash.display.Bitmap;
    import flash.display.BitmapData;
    import flash.display.Sprite;
    import flash.events.Event;

    public final class BackgroundEngine2 extends Sprite
    {
        //general
        private static var isLoaded:Boolean = false;        
        private static var bulkLoader:BulkLoader = BulkLoader.getLoader("main");
        private static var assets:Array;

        //objects
        private static var masterContainer:Sprite;
        private static var containers:Array = [];

        //stage
        private static var stageWidth:uint;
        private static var stageHeight:uint;
        private static var stageCenterX:Number;
        private static var stageCenterY:Number;

        //moves the background's X coord
        public static function moveX(amount:Number):void
        {
            if (!masterContainer) return;
            masterContainer.x += amount;
            collectGarbage();
            drawNextContainer();
        }

        //moves the background's Y coord
        public static function moveY(amount:Number):void
        {
            if (!masterContainer) return;
            masterContainer.y += amount;
            collectGarbage();
            drawNextContainer();
        }

        //returns whether the background engine has been loaded already
        public static function loaded():Boolean
        {
            return isLoaded;
        }

        //loads the background engine
        public final function load():void
        {
            //set stage width, height and center
            stageWidth = stage.stageWidth;
            stageHeight = stage.stageHeight;
            stageCenterX = stageWidth / 2;
            stageCenterY = stageHeight / 2;

            //retreive background assets
            bulkLoader.add(Settings.ASSETS_PRE_URL + "background/1.png", {id: "background/1.png"});
            bulkLoader.add(Settings.ASSETS_PRE_URL + "background/2.png", {id: "background/2.png"});
            bulkLoader.add(Settings.ASSETS_PRE_URL + "background/3.png", {id: "background/3.png"});
            bulkLoader.add(Settings.ASSETS_PRE_URL + "background/4.png", {id: "background/4.png"});
            bulkLoader.addEventListener(BulkLoader.COMPLETE, assetsComplete);
            bulkLoader.start();

            //set isLoaded to true
            isLoaded = true;
        }

        //poller function for drawing next background squares
        private static function drawNextContainer():void
        {
            var curContainer:Bitmap = hasBackground(stageCenterX, stageCenterY);
            if (curContainer)
            {
                if (!hasBackground(stageCenterX - stageWidth * 0.75, stageCenterY - stageHeight * 0.75)) //top left
                    drawNewSquare(curContainer.x - curContainer.width, curContainer.y - curContainer.height);
                if (!hasBackground(stageCenterX, stageCenterY - stageHeight * 0.75)) //top
                    drawNewSquare(curContainer.x, curContainer.y - curContainer.height);
                if (!hasBackground(stageCenterX + stageWidth * 0.75, stageCenterY - stageHeight * 0.75)) //top right
                    drawNewSquare(curContainer.x + curContainer.width, curContainer.y - curContainer.height);
                if (!hasBackground(stageCenterX - stageWidth * 0.75, stageCenterY)) //center left
                    drawNewSquare(curContainer.x - curContainer.width, curContainer.y);
                if (!hasBackground(stageCenterX + stageWidth * 0.75, stageCenterY)) //center right
                    drawNewSquare(curContainer.x + curContainer.width, curContainer.y);
                if (!hasBackground(stageCenterX - stageWidth * 0.75, stageCenterY + stageHeight * 0.75)) //bottom left
                    drawNewSquare(curContainer.x - curContainer.width, curContainer.y + curContainer.height);
                if (!hasBackground(stageCenterX, stageCenterY + stageHeight * 0.75)) //bottom center
                    drawNewSquare(curContainer.x, curContainer.y + curContainer.height);
                if (!hasBackground(stageCenterX + stageWidth * 0.75, stageCenterY + stageHeight * 0.75)) //bottom right
                    drawNewSquare(curContainer.x + curContainer.width, curContainer.y + curContainer.height);
            }
        }

        //draws the next square and adds it to the master container
        private static function drawNewSquare(x:Number, y:Number):void
        {
            containers.push(genSquareBg());
            var cIndex:uint = containers.length - 1;
            containers[cIndex].x = x;
            containers[cIndex].y = y;
            masterContainer.addChild(containers[cIndex]);
        }

        //returns whether the given location has a background and if so returns the corresponding square
        private static function hasBackground(x:Number, y:Number):Bitmap
        {
            var stageX:Number;
            var stageY:Number;
            for(var i:uint = 0; i < containers.length; i++)
            {
                stageX = masterContainer.x + containers[i].x;
                stageY = masterContainer.y + containers[i].y;
                if ((containers[i]) && (stageX < x) && (stageX + containers[i].width > x) && (stageY < y) && (stageY + containers[i].height > y)) return containers[i];
            }
            return null;
        }

        //polling function for old background squares garbage collection
        private static function collectGarbage():void
        {
            var stageX:Number;
            var stageY:Number;
            for(var i:uint = 0; i < containers.length; i++)
            {
                if ((containers[i]) && (!isRequiredContainer(containers[i])))
                {
                    masterContainer.removeChild(containers[i]);
                    containers.splice(i, 1);
                }
            }
        }

        //returns whether the given container is required for display
        private static function isRequiredContainer(container:Bitmap):Boolean
        {
            if (hasBackground(stageCenterX, stageCenterY) == container) //center
                return true;
            if (hasBackground(stageCenterX - stageWidth * 0.75, stageCenterY - stageHeight * 0.75) == container) //top left
                return true;
            if (hasBackground(stageCenterX, stageCenterY - stageHeight * 0.75) == container) //top
                return true;
            if (hasBackground(stageCenterX + stageWidth * 0.75, stageCenterY - stageHeight * 0.75) == container) //top right
                return true;
            if (hasBackground(stageCenterX - stageWidth * 0.75, stageCenterY) == container) //center left
                return true;
            if (hasBackground(stageCenterX + stageWidth * 0.75, stageCenterY) == container) //center right
                return true;
            if (hasBackground(stageCenterX - stageWidth * 0.75, stageCenterY + stageHeight * 0.75) == container) //bottom left
                return true;
            if (hasBackground(stageCenterX, stageCenterY + stageHeight * 0.75) == container) //bottom center
                return true;
            if (hasBackground(stageCenterX + stageWidth * 0.75, stageCenterY + stageHeight * 0.75) == container) //bottom right
                return true;
            return false;
        }

        //dispatched when all assets have finished downloading
        private final function assetsComplete(event:Event):void
        {
            assets = [];
            assets.push(bulkLoader.getBitmap("background/1.png")); //star simple
            assets.push(bulkLoader.getBitmap("background/2.png")); //star bright
            assets.push(bulkLoader.getBitmap("background/3.png")); //cloud white
            assets.push(bulkLoader.getBitmap("background/4.png")); //cloud red
            init();
        }

        //initializes startup background containers
        private final function init():void
        {
            masterContainer = new Sprite(); //create master container

            //generate default background container
            containers.push(genSquareBg()); //top left
            containers[0].x = 0;
            containers[0].y = 0;
            masterContainer.addChild(containers[0]);

            //display the master container
            masterContainer.x = -(stageWidth / 2);
            masterContainer.y = -(stageHeight / 2);
            masterContainer.cacheAsBitmap = true;
            addChild(masterContainer);
        }

        //duplicates a bitmap display object
        private static function dupeBitmap(source:Bitmap):Bitmap {
            var data:BitmapData = source.bitmapData;
            var bitmap:Bitmap = new Bitmap(data);
            return bitmap;
        }

        //draws a simple star
        private static function drawStar(x:Number, y:Number, width:uint, height:uint):Sprite
        {
            var creation:Sprite = new Sprite();
            creation.graphics.lineStyle(1, 0xFFFFFF);
            creation.graphics.beginFill(0xFFFFFF);
            creation.graphics.drawRect(x, y, width, height);
            return creation;
        }

        //generates a background square
        private static function genSquareBg():Bitmap
        {
            var width:Number = stageWidth * 2;
            var height:Number = stageHeight * 2;
            var startX:Number = 0;
            var startY:Number = 0;

            var scale:Number;
            var drawAmount:uint;
            var tmpBitmap:Bitmap;
            var tmpSprite:Sprite;
            var i:uint;

            //create container
            var container:Sprite = new Sprite();

            //draw simple stars
            drawAmount = UtilLib.getRandomInt(100, 250);
            for(i = 1; i <= drawAmount; i++)
            {
                tmpSprite = drawStar(0, 0, 1, 1);
                tmpSprite.x = UtilLib.getRandomInt(startX, width);
                tmpSprite.y = UtilLib.getRandomInt(startY, height);
                tmpSprite.alpha = UtilLib.getRandomInt(3, 10) / 10;
                scale = UtilLib.getRandomInt(5, 15) / 10;
                tmpSprite.scaleX = tmpSprite.scaleY = scale;
                container.addChild(tmpSprite);
            }

            //draw bright stars
            drawAmount = UtilLib.getRandomInt(1, 2);
            for(i = 1; i <= drawAmount; i++)
            {
                tmpBitmap = dupeBitmap(assets[1]);
                tmpBitmap.alpha = UtilLib.getRandomInt(3, 7) / 10;
                tmpBitmap.rotation = UtilLib.getRandomInt(0, 360);
                scale = UtilLib.getRandomInt(3, 10) / 10;
                tmpBitmap.scaleX = scale; tmpBitmap.scaleY = scale;
                tmpBitmap.x = UtilLib.getRandomInt(startX + tmpBitmap.width, width - tmpBitmap.width);
                tmpBitmap.y = UtilLib.getRandomInt(startY + tmpBitmap.height, height - tmpBitmap.height);
                container.addChild(tmpBitmap);
            }

            //draw white clouds
            drawAmount = UtilLib.getRandomInt(2, 4);
            for(i = 1; i <= drawAmount; i++)
            {
                tmpBitmap = dupeBitmap(assets[2]);
                tmpBitmap.alpha = UtilLib.getRandomInt(1, 10) / 10;
                scale = UtilLib.getRandomInt(15, 40);
                tmpBitmap.scaleX = scale / 10;
                tmpBitmap.scaleY = UtilLib.getRandomInt(scale / 2, scale * 2) / 10;
                tmpBitmap.x = UtilLib.getRandomInt(startX, width - tmpBitmap.width);
                tmpBitmap.y = UtilLib.getRandomInt(startY, height - tmpBitmap.height);
                container.addChild(tmpBitmap);
            }

            //draw red clouds
            drawAmount = UtilLib.getRandomInt(0, 2);
            for(i = 1; i <= drawAmount; i++)
            {
                tmpBitmap = dupeBitmap(assets[3]);
                tmpBitmap.alpha = UtilLib.getRandomInt(2, 6) / 10;
                scale = UtilLib.getRandomInt(5, 40) / 10;
                tmpBitmap.scaleX = scale; tmpBitmap.scaleY = scale;
                tmpBitmap.x = UtilLib.getRandomInt(startX, width - tmpBitmap.width);
                tmpBitmap.y = UtilLib.getRandomInt(startY, height - tmpBitmap.height);
                container.addChild(tmpBitmap);
            }

            //convert all layers to a single bitmap layer and return
            var bitmapData:BitmapData = new BitmapData(width, height, true, 0x000000);
            bitmapData.draw(container);
            container = null;
            var bitmapContainer:Bitmap = new Bitmap(bitmapData);
            //bitmapContainer.cacheAsBitmap = true;
            return bitmapContainer;
        }
    }
}

0 Stimmen

Nebenbei bemerkt, würde ich gerne dein Weltraumspiel sehen, wenn es fertig ist...

0 Stimmen

Leider muss ich zuerst dieses Hintergrundproblem beheben. Back2Dos hat mir eine interessante Hilfe gegeben, die aber zu viele Fragen aufgeworfen hat, als dass ich ohne weitere Kommentare weitermachen könnte. Das Spiel selbst wird in den nächsten Jahren nicht fertig werden, da es ein Multiplayer-Spiel ist und ich gerade erst mit den Grundlagen begonnen habe.

0 Stimmen

Das heißt, auch wenn es mir gelingt, all die Probleme zu lösen, mit denen ich anfangs nicht gerechnet habe. Zum Beispiel das Problem, um das es in diesem Thread geht.

1voto

SmilyOrg Punkte 11

Versuchen Sie, ein einzelnes großes BitmapData mit einer eigenen Bitmap zu verwenden, die größer ist als die Bühne (obwohl Sie an die Grenzen von BitmapDatas stoßen könnten, wenn Sie eine wirklich große Bühne haben und/oder Flash 9 verwenden), und zeichnen Sie neue Hintergrundbilder mit der copyPixels-Methode (eine wirklich schnelle Methode zum Kopieren von Pixeln, schneller als draw(), zumindest soweit ich das gesehen habe).

Schwenken Sie die große Bitmap, wenn Sie wollen, und wenn Sie eine Kante erreichen, schwenken Sie die Bitmap auf die andere Seite, copyPixels das ganze Ding zurück, wo es vorher war (so sollte das Bild an der gleichen Stelle relativ zur Bühne bleiben, aber die Bitmap sollte sich bewegen) und copyPixels neue Bilder, wo sie fehlen.

Da Sie für die Bilder auch Alpha verwenden, sollten Sie vielleicht alle Parameter von copyPixels überprüfen, wenn es Alpha nicht so kopiert, wie Sie es wollten (wahrscheinlich mergeAlpha?).

Um es noch einmal zusammenzufassen: Verwenden Sie ein einziges großes Bitmap, das sich weit über die Grenzen der Bühne erstreckt, halten Sie die Bilder als BitmapDatas bereit, wenden Sie den Wrap-Trick an und füllen Sie die Leerstellen mit copyPixels aus den Bildern.

Ich weiß nicht, ob dieser Weg würde besser durchführen (die copyPixels über die gesamte Bitmap macht mir ein wenig Sorgen), aber es ist definitiv etwas zu versuchen. Viel Glück :)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X