Правка 2: судя по отсутствию ответов, я начинаю задумываться, достаточно ли ясна моя проблема. Пожалуйста, скажите мне, если мне нужно уточнить подробнее.
Примечание: см. Внизу обновление кода!
Краткое введение: Я пишу двумерную флеш-игру в ActionScript. Вселенная бесконечно большая, из-за этой особенности фон должен отображаться динамически, а объекты фона (газовые облака, звезды и т. Д.) Должны располагаться случайным образом.
Я создал класс с именем BackgroundEngine, и он работает очень хорошо, однако проблема заключается в производительности рендеринга. Вот как это работает:
При запуске вокруг игрока создается 4 фоновых контейнера (каждый размером с размер сцены). Слева вверху, вверху справа, внизу слева и внизу справа. Все квадраты фона добавляются в мастер-контейнер для легкого перемещения фона. Теперь есть 2 функции опроса:
1) «мусорщик»: ищет фоновые контейнеры, которые в 2 раза превышают ширину или высоту сцены относительно координат X или Y игрока, соответственно. Если это так, он удалит этот фоновый квадрат и позволит собирать мусор.
2) «Поллер рендеринга»: проверяет, есть ли в настоящее время фон со всех сторон проигрывателя (x - stageWidth, x + stageWidth, y - stageHeight, y + stageHeight). Если нет, он нарисует новый квадрат фона в соответствующем месте.
Все фоновые квадраты создаются с помощью следующей функции (те, которые создаются динамически, и четыре при запуске):
<<< удален старый код, обновленный полный исходный код см. Внизу >>>
Все случайности, которые вы видите там, гарантируют, что окружение выглядит очень уникальным на каждом квадрате. Это на самом деле прекрасно работает, вселенная выглядит довольно круто.
В качестве фоновых объектов используются следующие активы:
1) Простые звезды: http://www.feedpostal.com/client/assets/background/1.png (вы, вероятно, не сможете увидеть их в браузере с белым фоном).
2) Яркие звезды: http://www.feedpostal.com/client/assets/background/2.png
3) Облака белого газа: http://www.feedpostal.com/client/assets/background/3.png
4) Красные газовые облака: http://www.feedpostal.com/client/assets/background/4.png
Важные примечания:
1) Все ресурсы кэшируются, поэтому их не нужно постоянно перезагружать. Они загружаются только один раз.
2) Изображения не вращаются и не масштабируются после их создания, поэтому я включил cacheAsBitmap для всех объектов, контейнеров и masterContainer.
3) Мне пришлось использовать форматы PNG в Photoshop, потому что GIF-файлы не очень хорошо отображались во флэш-памяти при использовании с прозрачностью.
Итак, проблема в том, что когда я летаю, рендеринг фона отнимает слишком много производительности: клиент начинает «отставать» (FPS). Из-за этого мне нужно оптимизировать фоновый движок, чтобы он рендерился намного быстрее. Не могли бы вы помочь мне здесь?
Обновление 1:
Это то, что я имею до сих пор после одного ответа, который я получил.
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;
}
}
}
Когда игрок движется, фоновые методы moveX и moveY вызываются в обратном направлении игрока. Это также приведет к вызову методов collectGarbage и drawNextContainer.
Проблема с этой настройкой заключается в том, что в активном режиме всегда минимум 9 контейнеров. Верхний левый, верхний, верхний правый, центральный левый, центр, правый центр, нижний левый, нижний и правый нижний. Это занимает много производительности.
Edit: мне также интересно, я должен использовать cacheAsBitmap? Если да, то на каких изображениях? На контейнерах и мастер-контейнерах или только на одном из них? Когда я включаю его для всех изображений (даже для временных спрайтовых объектов), оно на самом деле отстает.
Обновление 2:
В этой версии используются квадраты, которые в два раза больше, чем на сцене. Только один или два квадрата должны быть загружены за один раз. Это лучше, но я все еще замечаю снижение производительности во время движения. Это заставляет клиента замораживаться на очень короткий момент. Есть идеи как его оптимизировать?
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;
}
}
}