I need to pre render animation, which I am creating by code in as3. I would like to save every frame of _debugBmp to *.png or *.bmp file, or create sprite sheet.
Is that possible?
Thank you for answer.
public class PerlinNoise extends Sprite
{
// premenne pre perlin noise
private var _baseX:Number = 45;
private var _baseY:Number = 5;
private var _numOctaves:uint = 3;
private var _randomSeed:int = 50;
private var _stitch:Boolean = true;
private var _fractalNoise:Boolean = false;
private var _channelOptions:uint = 1;
private var _grayScale:Boolean = true;
private var _offsets:Array = [];
private var _perlinBitmapData : BitmapData;
private var _debugBmp : Bitmap;
public function PerlinNoise()
{
_perlinBitmapData = new BitmapData(275, 50, true);
// oktavy perlin noisu
for(var i:int = 0; i < _numOctaves;i++) _offsets[i] = new Point(0,0);
_debugBmp = new Bitmap(_perlinBitmapData);
addChild(_debugBmp);
stage.addEventListener(Event.ENTER_FRAME, onEnterFrame);
}
private function onEnterFrame(e:Event):void
{
// animacia perlin noisu
_offsets[1]['x'] += 1; // 2
_offsets[1]['y'] += 1/4;//1/4
// aplikacia perlin noisu
_perlinBitmapData.perlinNoise(_baseX, _baseY, _numOctaves, _randomSeed, _stitch, _fractalNoise, _channelOptions, _grayScale, _offsets);
}
}
I would recommend putting your code in an Adobe AIR application and then save the BitMapData out to files after each image is created in the onEnterFrame method. Once you have al your images than you could make a spritesheet out of them.
Related
i'm building a flash desktop App where the user clicks on a button and opens a SWF file (a game) in a new window, i used a NativeWindow to achieve it, i did the folowing:
var windowOptions:NativeWindowInitOptions = new NativeWindowInitOptions();
windowOptions.systemChrome = NativeWindowSystemChrome.STANDARD;
windowOptions.type = NativeWindowType.NORMAL;
var newWindow:NativeWindow = new NativeWindow(windowOptions);
newWindow.stage.scaleMode = StageScaleMode.NO_SCALE;
newWindow.stage.align = StageAlign.TOP_LEFT;
newWindow.bounds = new Rectangle(100, 100, 2000, 800);
newWindow.activate();
var aLoader:Loader = new Loader;
aLoader.load(new URLRequest(path));
newWindow.stage.addChild(aLoader);
the result is this:
the game doesn't take the whole space available. When i change the "NO_SCALE" to "EXACT_FIT":
newWindow.stage.scaleMode = StageScaleMode.EXACT_FIT;
i got this:
it only shows the top-left corner of the game. I also tried "SHOW_ALL" and "NO_BORDER". I got the same result as "EXACT_FIT".
When i open the SWF file of the game separatly it's displayed normally:
any idea how can i display the SWF game as the image above?
The best solution for that is to have the dimensions of your external game in pixel. you have to stretch the loader to fit it in your stage. if you are try to load different games with different sizes to your stage, save the swf dimensions with their URL addresses.
var extSWFW:Number = 550;
var extSWFH:Number = 400;
var extURL:String = "./Data/someSwf.swf";
var mainStageWidth:Number = 1024;
var mainStageHeight:Nubmer = 768;
var aLoader:Loader = new Loader;
aLoader.load(new URLRequest(extURL));
newWindow.stage.addChild(aLoader);
aLoader.scaleY = aLoader.scaleX = Math.min(mainStageWidth/extSWFW,mainStageHeight/extSWFH);
It is not very difficult to figure dimensions of a loaded SWF because it is engraved into it's header, you can read and parse it upon loading. Here's the working sample:
package assortie
{
import flash.display.Loader;
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.net.URLRequest;
import flash.utils.ByteArray;
public class Dimensions extends Sprite
{
private var loader:Loader;
public function Dimensions()
{
super();
loader = new Loader;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onLoaded);
loader.load(new URLRequest("outer.swf"));
}
private function onLoaded(e:Event):void
{
var aBytes:ByteArray = loader.contentLoaderInfo.bytes;
var aRect:Rectangle = new Rectangle;
var aRead:BitReader = new BitReader(aBytes, 8);
var perEntry:uint = aRead.readUnsigned(5);
aRect.left = aRead.readSigned(perEntry) / 20;
aRect.right = aRead.readSigned(perEntry) / 20;
aRect.top = aRead.readSigned(perEntry) / 20;
aRect.bottom = aRead.readSigned(perEntry) / 20;
aRead.dispose();
aRead = null;
trace(aRect);
}
}
}
import flash.utils.ByteArray;
internal class BitReader
{
private var bytes:ByteArray;
private var position:int;
private var bits:String;
public function BitReader(source:ByteArray, start:int)
{
bits = "";
bytes = source;
position = start;
}
public function readSigned(length:int):int
{
var aSign:int = (readBits(1) == "1")? -1: 1;
return aSign * int(readUnsigned(length - 1));
}
public function readUnsigned(length:int):uint
{
return parseInt(readBits(length), 2);
}
private function readBits(length:int):String
{
while (length > bits.length) readAhead();
var result:String = bits.substr(0, length);
bits = bits.substr(length);
return result;
}
static private const Z:String = "00000000";
private function readAhead():void
{
var wasBits:String = bits;
var aByte:String = bytes[position].toString(2);
bits += Z.substr(aByte.length) + aByte;
position++;
}
public function dispose():void
{
bits = null;
bytes = null;
}
}
My flash project has specific task to show the dynamic gallery items based on an XML list and there is a download option available for each gallery item.
For this I made a movieclip (imageTile) with a Thumbnail, Title, ProgressBar & ProgressText as shown below.
I have two classes named Main.as and FileRef.as
Main.as
var tileMap:Dictionary = new Dictionary();
public var tile:ImageTile;
addChild(wall);
wallWidth = wall.width;
wallHeight = wall.height;
var columns:Number;
var my_x:Number;
var my_y:Number;
var my_thumb_width:Number;
var my_thumb_height:Number;
var images:XMLList;
var total:Number;
var swipe:Number = 0;
var myXMLLoader:URLLoader = new URLLoader();
myXMLLoader.load(new URLRequest("gallery.xml"));
myXMLLoader.addEventListener(Event.COMPLETE, processXML);
function processXML(e:Event):void {
myXML = new XML(e.target.data);
images = myXML.IMAGE;
total = images.length();
myXMLLoader.removeEventListener(Event.COMPLETE, processXML);
myXMLLoader = null;
var loader:Loader;
for (var i:uint = 0; i < total; i++) {
tile = new ImageTile();
wall.addChild(tile);
tile.x = i % 3 * 400 + 180;
tile.y = Math.floor(i / 3) * 650 + 250;
var imageName:String = images[i].#FULL;
path = images[i].#Path;
var title:String = images[i].#Title;
**var caption:TextField = tile.getChildByName("caption_tf") as TextField;**
caption.text = title;
tile.addEventListener(MouseEvent.CLICK, onTileClick(path));
loader = new Loader();
loader.load(new URLRequest("images/" + imageName));
tileMap[loader] = tile;
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoad);
}
//trace(myXML);
}
var tileMap:Dictionary = new Dictionary();
function onImageLoad(e:Event):void {
var loader:Loader = e.target.loader;
var tile:ImageTile = tileMap[loader] as ImageTile;
var image:Bitmap = loader.content as Bitmap;
image.x = -100;
image.y = -100;
image.width=366;
image.height=418;
var textField:DisplayObject = tile.getChildByName("caption_tf");
var textFieldDepth:int = tile.getChildIndex(textField);
tile.addChildAt(image, textFieldDepth);
tileMap[loader] = null;
image.smoothing = true;
}
function onTileClick(url:String):Function {
return function(me:MouseEvent):void {
path = url;
var download:FileRef = new FileRef();
download.downloadFile(path);
}
FileRef.as code
public var mc_loaded : MovieClip = Main.gameInstance.tile.getChildByName("mc_loaded") as MovieClip,
mc_progress : MovieClip = Main.gameInstance.tile.getChildByName("mc_progress") as MovieClip,
txt_prog : TextField = Main.gameInstance.tile.getChildByName("txt_prog") as TextField;
public function downloadFile(url:String) : void
{
/// Download the gallery item codes using url
}
public function progressHandler( event : ProgressEvent ) : void
{
//mc_loaded.scaleX = (event.bytesLoaded / event.bytesTotal) ;
}
public function completeHandler( event : Event ) : void
{
//reset progress bar after download is finished
mc_loaded.scaleX = 0; // I want to use the imageTile element
txt_prog.text = "download finished";
}
public function OnZipComplete(evt:flash.events.Event):void
{
txt_prog.text = "download finished";
}
The download works fine, but I can not get the progress bar and progress text for every tile created.
I got the answer
Remove onTileClick(url:String) function from Main.as
Main.as
function processXML(e:Event):void {
//// Codes /////
//// Codes /////
var download:FileRefTut = new FileRefTut();
tile.addEventListener(MouseEvent.CLICK, download.downloadFile(path));
}
FileRef.as
public var txt_prog:TextField, mc_loaded:MovieClip;
public function downloadFile(url:String):Function {
return function(me:MouseEvent):void {
var tile:ImageTile = me.currentTarget as ImageTile;
txt_prog = tile.getChildByName("txt_prog") as TextField;
mc_loaded = tile.getChildByName("mc_loaded") as MovieClip;
}
public function progressHandler( event : ProgressEvent ) : void
{
mc_loaded.scaleX = (event.bytesLoaded / event.bytesTotal) ;
}
public function completeHandler( event : Event ) : void
{
//reset progress bar after download is finished
mc_loaded.scaleX = 0; // I want to use the imageTile element
txt_prog.text = "download finished";
}
public function OnZipComplete(evt:flash.events.Event):void
{
txt_prog.text = "download finished";
}
I'm making a game, and originally I placed the hero movieclip on the stage manually. Now I add the hero to a container and load the container in the Main.as constructor.
I get a 1009 error for this line:
bulletOffset = 5 / _root.accuracy;
Here is the relevant code of the hero class:
public class Hero extends MovieClip {
private var radius:Number;
//Bullet offset
private var bulletOffset:Number;
//Player variables
private var walkingSpeed:int = 3;
private var shootingRate:int = 120;
private var s:int;
//Making all of the items on the stage accessible by typing "_root.[ITEM]"
private var _root:MovieClip;
private var leftKeyDown:Boolean = false;
private var upKeyDown:Boolean = false;
private var rightKeyDown:Boolean = false;
private var downKeyDown:Boolean = false;
private var punchKeyDown:Boolean = false;
//Player states (shooting, attacking etc)
private var shooting:Boolean = false;
public function Hero()
{
addEventListener(Event.ADDED, beginClass);
}
private function beginClass(event:Event):void
{
//Determine the radius
radius = this.width - 8;
_root = MovieClip(root);
bulletOffset = 5 / _root.accuracy;
blablablabla
You are listening to the wrong event. Event.ADDED will be fired when it's added to any display list. But you need to wait for Event.ADDED_TO_STAGE before root will be available to you:
public function Hero()
{
addEventListener(Event.ADDED_TO_STAGE, beginClass);
}
I'm developing a mobile project with Flash Builder, and I'm having some issues with the Tween Class... It works just fine for some time, but then, all of the sudden, it just stops working.
The game emulates an "under the sea" scene, so, one of the things I have is a "bubbly" background, and it works just fine for some time, and then, all of the sudden, all the tweens stop at the same time (including some tweens that are in other classes). Any thoughts on why this could happen? I'm adding the code of the background bubbles to see if you get why this could be behaving so oddly.
Thanks in advance!
public class BurbujasBack extends Sprite
{
public var timer:Timer = new Timer(200,0);
public var burbujasMaximas:int = 25;
public static var burbujasActuales:int = 0;
public function BurbujasBack()
{
x=Diversion_bajo_el_agua.ancho_st/2;
y=Diversion_bajo_el_agua.alto_st;
timer.addEventListener(TimerEvent.TIMER,_nuevaBubble);
timer.start();
}
private function _nuevaBubble(e:TimerEvent):void {
var add:Boolean = (Math.random() > .5) ? true : false;
if (add==true) {
if(burbujasActuales < burbujasMaximas) {
trace("agrega una burbuja");
var burbuja:BurbujaChica = new BurbujaChica();
addChild(burbuja);
burbujasActuales++;
}
}
}
}
And
public class BurbujaChica extends Sprite
{
public var velocidad:Number = Math.random();
public var escala:Number = Math.random()*.5+.5;
public var tiempoMaximo:int = 3;
public var posX:Number = Math.random()*Diversion_bajo_el_agua.ancho_st;
public function BurbujaChica()
{
x = posX
var burbuja:Burbuja_ = new Burbuja_();
burbuja.scaleX = burbuja.scaleY = escala;
var desde:Number = burbuja.height/2;
var hasta:Number = -Diversion_bajo_el_agua.alto_st-burbuja.height/2;
trace("va desde "+desde+" hasta "+hasta);
var tw:Tween = new Tween(burbuja,"y",Regular.easeIn,desde,hasta,(velocidad*tiempoMaximo)+5,true);
tw.addEventListener(TweenEvent.MOTION_FINISH,_chauBurbuja);
addChild(burbuja);
}
private function _chauBurbuja(e:TweenEvent):void {
this.parent.removeChild(this);
BurbujasBack.burbujasActuales--;
}
}
I am new and having an issue with the use of classes in as3.
I have created an array of objects in my main timeline
function badPlayer()
{
var bads:Array = new Array();
for (var i=0; i<5; i++)
{
var mc = new bman();
mc.name=["mc"+i];
bads.push(mc);
_backGround.addChild(mc);
mc.x = 100;
mc.y = 100;
trace (bads);
Baddies(_backGround.mc); //here I am trying to export mc to my class
}
}
Here is a snip-it from my class. My trace statement wont even output.
public class Baddies extends MovieClip
{
private var pistolSound:pistolShot = new pistolShot();
//private var mc = new mc();
private var _rotateSpeedMax:Number = 2;
private var _gravity:Number = .68;
private var _bulletSpeed:Number = 2;
private var _maxDistance:Number = 200;
private var _reloadSpeed:Number = 500; //milliseconds
private var _barrelLength:Number = 20;
private var _bulletSpread:Number = 5;
private var _isLoaded:Boolean = true;
private var _isFiring:Boolean = true;
private var _endX:Number;
private var _endY:Number;
private var _startX:Number;
private var _startY:Number;
private var _reloadTimer:Timer;
private var _bullets:Array = [];
private var _gun:MovieClip;
private var _enemy:MovieClip;
private var _yx:Number;
private var _yy:Number;
private var _pcos:Number;
private var _psin:Number;
private var _trueRotation:Number;
public function Baddies()
{
trace("working");
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
Basically I am trying to create several bad guys (bman) and have the same code apply to each of them. I have also tried to change the linkage name of bman to Baddies with no success.
There are a few thing that are very wrong with this code.
Baddies(_backGround.mc); //here I am trying to export mc to my class
This is a typecast, as already stated in the comments. By the way Baddies isn't a good name, because it plural. You probably want to create a new bad guy, which would be done with this line:
var baddie = new Baddies();
Now your constructor uses the stage variable. This won't work because the object isn't on the stage, therefore stage is null (it may works if you drag and drop an instance to the stage in the editor). So before using the stage you actually need to add the object to the stage:
public function Baddies() {
trace("new baddie created");
}
public function init(mc:MovieClip) {
mc.addChild(this); // display this baddie
trace("working");
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
And in the badPlayer function:
var baddie = new Baddies();
baddie.init(_backGround);