Sunday, November 30, 2008

Bitmapdata .disose()

This is just some venting...I am working a fraction game..i've tentatively called "Fraction Wars"..basically you blast up equivalent fractions. Anyway, I'm using a fair amount of blitting ala 8 bit rocket style. I decide to create and cache some text animations that use this blitting technique. The logic is that I would cache all the text animations that were likely to occur during the more intense parts of the game and then just blit them to the main canvas, a single bitmapdata object that spans most of the screen. (for in between levels when not much action was occuring, I used regular old text fields and transitionmanagers).

The morale of my wasted time is that bitmapdata's dispose() method is DESTRUCTIVE. Only use it if you don't need ANY reference that given bitmapdata. I knew this before today , just didn't see how it



I wasted more time than I care to share over the following embarrising fact that I had a timer loop that

1) created new bitmapdata by drawing from a text field
2) store bitmapdata in a slot in an array
3) before moving on to the next iteration of the timer, I called .dispose() on the new bitmapdata

I know it seems obviuos now

Friday, November 28, 2008

Randomize Elements in an Array

I had to rewrite some code that randomized elements in the new Vector class (had written the code below to randomize array elements)and thought I'd post both the old array randomizer() here. nothing fancy at all...just thought might be useful to someone.


var myArray:Array =[1,2,3,4,5,6];

function randomize(arr:Array):Array{
var originalA:Array = arr;
var newA:Array=[];

while(originalA.length > 0){
var index:int = int(Math.random() * originalA.length);
var element = originalA.splice(index,1);
//splice returns an array.
newA.push(element[0]);

}

return newA;

}

trace(randomize(myArray));


Note: the splice() method of the array class actually returns an Array made up of the elements you've spliced out of the original array. This is why we need to push element[0] into the new randomized array.

Saturday, November 22, 2008

Loading External BitmapData into Vector of Type BitmapData

I'm working on a math game that requires many external images to be loaded into Actionscript 3's new Vector class (typed array) . It took me a bit of experimenting to determine how to properly load external images into a Vector of type BitmapData. Before the new the typed arrays of our new Vector class, I didn't have to worry about the type of the data that I was storing (arrays can handle any type)...now, it's a whole new ball game

. In the end, you just cast the content of the loader object to a Bitmap then access that Bitmap's ".bitmapData" property...see a simplified version of my code below.




//Here's my BitmapData Vector
var explosionVec:Vector. = new Vector.();

//load external png
var _loader = new Loader();
_loader.contentLoaderInfo.addEventListener(Event.COMPLETE, loaded,false,0, true);
_loader.load( new URLRequest("bath/To/Image/explosion.png"));

//
function loaded(e:Event):void{
//cast content to bitmap
var bmp:Bitmap = Bitmap(_loader.content);
//store the bitmapData from the Bitmap!
explosionVec[0] = bmp.bitmapData;

}

Wednesday, November 19, 2008

Vectors! Typed arrays come to Actionscript 3

Finally got my hands on CS4... one of the main new new perks of the Actionscript is the new Vector class (nothing to do with physics or vector graphics)...these are good old typed arrays in the style of C++ or Java.

Basics of the Syntax

//create a Vector and call it vec

var vec:Vector. <int> = new Vector.<int>();

now "vec" can only store ints! This allows for Type-safety in your code, and potentially performance gains.

to add an object to a vector just call .push()
//the next line adds the int '3' to the vector
vec.push(3);



Much more info over at Senocular

Sunday, November 16, 2008

Bitmapdata Image Effects in Actionscript 3 demo with code

Well, I started this Blog for a few reasons, one of which is to share code that others might find useful.. Toda I had to create some classes that I assumed would be easy to find on the internet...well, now they are (at least if you can find my blog) Aside from teaching, I work on several websites and am currently doing some work on site for a Dentist's website...anyway, I needed an image slideshow that would provide some neat transition effects.

I expected to be able to find something on the web that I could just copy paste and pawn off as my own, but there was nothing out there that was perfect. There's something close at Flep Studio. However, after downloading their code I realized, I'd just have to write my own to acheive what I wanted.


In the end, my code is pretty far from Flep Studio. I ended up writing 2 distinct Actionscript 3 classes that manipulate Bitmapdata. It was easier to create a separate object for each square that would flash bright white then fade away. The codes' much sloppier than it could be, but if you like the code you can download the source (.fla and classes). If you're going to just copy and paste this code, you will need some images in your library. The ImageTrans class which is the document class assumes that there are five images (jpg, png or whathave you) with the following linkage identifiers

  • Picture1
  • Picture2
  • Picture3
  • Picture4
  • Picture5
You can see the final product below.









package{
import flash.display.MovieClip;
import flash.display.BitmapData;
import flash.display.Bitmap;
import flash.geom.Point;
import flash.events.TimerEvent;
import flash.geom.*;
import flash.display.*;
import flash.net.*;
import flash.events.*;
import flash.geom.*;
import flash.utils.*;


public class ImageTrans extends MovieClip{



private var timer:Timer;
private var updateInterval:int = 10;
const NUMBER_ROWS: Number = 13;
const NUMBER_COLS:Number = 13;
var currentRow:int=0;
var currentCol:int =0;
private var index:int =1;


private var currentBD:BitmapData;
private var nextBD:BitmapData;
private var canavsBD:BitmapData;
private var arrayofImg:Array;
private var bmp:Bitmap;

//delay betwen pics
var delayTimerTimer:int =1000;

private static var delayTimer:Timer;




private function initOnce():void{
FadingBD.setRoot(stage);
delayTimer = new Timer(delayTimerTimer,1);
arrayofImg = new Array();
canavsBD = new BitmapData(stage.stageWidth*2,stage.stageHeight*2,false);
arrayofImg.push(new Picture1(0,0) );
arrayofImg.push(new Picture2(0,0));
arrayofImg.push(new Picture5(0,0));
arrayofImg.push(new Picture4(0,0));
arrayofImg.push(new Picture3(0,0));


canavsBD.copyPixels(arrayofImg[0],arrayofImg[0].rect,new Point());

currentBD = arrayofImg[1];
nextBD = arrayofImg[2];

bmp = new Bitmap(canavsBD)//canavsBD);

addChild(bmp);
timer = new Timer(updateInterval);
timer.start();
timer.addEventListener(TimerEvent.TIMER,go,false,0,true);





}


public function ImageTrans():void{
initOnce();
}


function nextOne(e:TimerEvent):void{
var nextIndex:int;
index++;

if(index == arrayofImg.length-1)
nextIndex=0;

else
nextIndex = index+1;

if( index == arrayofImg.length)
{
index = 0;
nextIndex = 1;
}
currentRow=0;
currentCol=0;

currentBD= new BitmapData(nextBD.width,nextBD.height);
currentBD.draw(arrayofImg[index] );

nextBD= new BitmapData(nextBD.width,nextBD.height);
nextBD.draw(arrayofImg[nextIndex]);


}


public function go(e:TimerEvent):void{



var w:Number =currentBD.width/ NUMBER_COLS;
var h:Number = currentBD.height/NUMBER_ROWS;

var rect:Rectangle=new Rectangle(w*currentCol-1, h* currentRow-1,w+2,h+2);
var _point:Point =new Point( currentCol*w, currentRow*h);

//add one point toeither isde to make up for any small gaps in bitmapdata size
var tmpBd:BitmapData = new BitmapData(rect.width,rect.height,false);
tmpBd.draw(currentBD);
canavsBD.copyPixels(currentBD,rect, _point);

var f:FadingBD = new FadingBD(rect,_point,tmpBd);
stage. addChild(f);

if(currentCol != NUMBER_COLS)
currentCol ++;
else if(currentCol == NUMBER_COLS )
{
currentRow++;
currentCol=0;
}


if(currentCol == NUMBER_COLS && currentRow == NUMBER_ROWS )
delayNext();
}

private function delayNext():void{
delayTimer.start();
delayTimer.addEventListener(TimerEvent.TIMER_COMPLETE,nextOne,false,0,true);


}




}


}//end of imageTrans class

package{
import flash.display.*;
import flash.filters.*;
import flash.geom.*;

import flash.events.*

public class FadingBD extends Sprite{

private static var rootRef:DisplayObjectContainer;
private var mc:MovieClip;
private var rect:Rectangle;
private var _point:Point;
private var myBd:BitmapData;
private var bmp:Bitmap;


public static function setRoot(t:DisplayObjectContainer):void{
rootRef = t;
}

public function FadingBD(r:Rectangle,p:Point,bd:BitmapData){

rect=r;
_point =p;
myBd = new BitmapData(r.width,r.height,false,0xffffff);
bmp = new Bitmap(myBd);
mc = new MovieClip();
mc.addChild(bmp);
var b:BlurFilter =new BlurFilter(4,4,1);

mc.filters =[b];

rootRef.addChild(mc);
mc.x =p.x;
mc.y=p.y;

addEventListener(Event.ENTER_FRAME,go,false,0,true);
}

private function go(e:Event):void{
mc.alpha -= .1;
if(mc.alpha <= 0) end(); } private function end():void{ removeEventListener(Event.ENTER_FRAME,go); mc.removeChild(mc.getChildAt(0)); rootRef.removeChild(mc); bmp=null myBd.dispose(); mc.filters=[]; mc = null; myBd.dispose(); myBd = null; } } }