Dynamically creating movieclip instances - actionscript-3

I use the code below to create 3 movie clips.
var A:Array = new Array();
for (var i:uint = 0; i < 3 ; i++) {
A[i] = new hayvanSec();
A[i].x = 240+i*160;
A[i].y=300;
addChild(A[i]);
}
I have 10 image files in the library. I want to show one of these images inside those dynamically created movie clips randomly.

In the flash IDE make those image a MovieClip and name your clip with something like that XXX_0, XXX_1,...,XXX_9.
Then you can in your function you can get the random reference to your clip with :
var myImageName:String="XXX_"+Math.floor(Math.random()*10);
// and then get the movie from the library
var clazz:Class=ApplicationDomain.currentDomain.getDefinition(myImageName) as Class;
if (clazz !== null) {
var mc:MovieClip=MovieClip(new clazz());
(...).addChild(mc);
}

Related

Adding Multiple Children of the Same Object As3

I have been working on a flash project and I am making an achievements display with each achievement progress complete and reward for completing. I would like to add multiple textFields to the stage and add text to each one individually. I have 30 text boxes and I think there is a better way of adding them than making different classes for each.
public var progress1:textField = new textField();
public var progress2:textField = new textField();
public var progress3:textField = new textField();
public var progress4:textField = new textField();
...And so on until 30
Is there a way of adding them and changing their text with a for loop because this does not seem like an efficient way to do it.
I also have to add a movie clip to the stage 30 times and change its y each time is there a way of making that in a for loop.
You can keep the textfields in a vector like this.
var texts:Vector.<TextField> = new Vector.<TextField>();
var num:int = 30;
for (var i:int = 0; i < num; i++)
{
texts.push(new TextField());
}
//change the text in a loop;
var content:Array = ["text1", "text2" ...];//the contents for the texts to show
var max:int = Math.max(content.length, texts.length);
for (var j:int = 0; j < max; j++)
{
texts[j].text = content[j];
}

How to add a keyboard navigation to a Flash AS3 based app?

I would like to make my Flash AS3 based app more accessible with a keyboard navigation.
What's the best way to add to every MovieClip with a MouseEvent.CLICK the ability to get selected through the TAB and clicked/fired through ENTER?
Some basic example of my code:
nav.btna.addEventListener(MouseEvent.CLICK, openSection);
dialog.btnx.addEventListener(MouseEvent.CLICK, closeDialog);
function openSection(event:Event=null):void
{
trace("nav.btna")
}
function closeDialog(event:Event=null):void
{
trace("dialog.btnx")
}
I remember that there was a AS3 function that enabled that every MovieClip with a MouseEvent could be fire through ENTER if the MovieClip was selected with TAB. I can't remeber the function though.
I think the problem may be that you are attempting this with a MovieClip instead of a button (Button or SimpleButton).
I made a simple test by creating buttons instead of MovieClips in my library and this worked as expected:
// I have 4 buttons (button1, button2, etc) on the stage
for(var i:int = 1; i <= 4; i++)
{
var mc = getChildByName("button" + (i+1));
mc.tabIndex = i;
mc.addEventListener(MouseEvent.CLICK, onClicked);
}
function onClicked(e:MouseEvent):void
{
trace(e.currentTarget + " clicked");
}
stage.focus = stage;
I initially ran this test with MovieClip instances, and while they would show that the tab was working (a yellow border shows up), the MouseEvent.CLICK was never firing. Once I switched to actual buttons (SimpleButton in this case), it worked with both the Enter and Space keys.
EDIT:
To answer the question posed in the comments, this is a quick-and-dirty way to "convert" MovieClips to SimpleButtons at runtime:
// I have 4 MovieClips (button1, button2, etc) on the stage
for(var i:int = 1; i <= 4; i++)
{
var mc:MovieClip = getChildByName("button" + i) as MovieClip;
var button:SimpleButton = convertMovieClipToButton(mc);
button.tabIndex = i;
button.addEventListener(MouseEvent.CLICK, onClicked);
}
function convertMovieClipToButton(mc:MovieClip):SimpleButton
{
var className:Class = getDefinitionByName(getQualifiedClassName(mc)) as Class;
var button:SimpleButton = new SimpleButton(new className(), new className(), new className(), new className());
button.name = mc.name;
button.x = mc.x;
button.y = mc.y;
mc.parent.addChildAt(button, getChildIndex(mc));
mc.parent.removeChild(mc);
return button;
}

Accessing pieces of bitmaps inside a movieclip

I have a movieclip with 10 bitmaps in it. I wanna access each of them.
myMovieClip is the movieclip containing those 10 bitmaps. I wanna access those bitmaps one by one. All 10 bitmaps are imported separately.
I tried this :
for ( var i =0 ; i< myMovieClip.numChildren ; i++)
{
trace ( myMovieClip.getChildAt(i) );
}
Problem is numChildren comes "1" only, as if it doesnot consider those 10 pieces of bitmap. Any other way, to access those bitmaps ?
thanks
V.
what do you mean by pieces of bitmaps?? Do you mean 10 different bitmap objects are children of the movieClip??
In addition, your code does have a syntax error.
var newMc:MovieClip = MovieClip();
should be:
var newMc:MovieClip = new MovieClip();
second off all, in your loop, numChildren will be always changing since you are taking the reference of a child from the myMoiveClip and moving it to the newMc object. there are two way to fix this.
either set a local variable to the value of myMovieClip.numChildren and use that value in your loop
example:
var numOfChildren:int = myMovieClip.numChildren;
for(var i:int = 0; i < numOfChildren; i++){
var newMc:MovieClip = new MovieClip();
newMc.addChild(myMovieClip.getChildAt(i));
}
this will move the bitmaps out of myMovieClip and into newMc, if you want to keep them there you can create a new bitmap inside the loop and then add the new bitmap to the newMc.
example:
for(var i:int = 0; i < myMovieClip.numChildren; i++){
var newMc:MovieClip = new MovieClip();
var b:Bitmap = new Bitmap(Bitmap(myMovieClip.getChildAt(i)).bitmapData);
newMc.addChild(b);
}

Actionscript 3: Slice a Bitmap into tiles

I have the Bitmap data from a Loader object and I would like to slice it up into 32x32 squares to use as tiles. What is the most efficient way to do so?
I have done the work for you. The basic idea is to use the BitmapData function copyPixels, see Adobe Reference for the same . It lets you copy pixels from one region(specified by a Rectangle) in the source BitmapData, to a specific Point in the destination BitmapData. I have created a new BitmapData for each 32x32 square and looped through the loaded object to populate the squares with copyPixels.
var imageLoader:Loader;
function loadImage(url:String):void
{
// Set properties on my Loader object
imageLoader = new Loader();
imageLoader.load(new URLRequest(url));
imageLoader.contentLoaderInfo.addEventListener(ProgressEvent.PROGRESS, imageLoading);
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, imageLoaded);
}
loadImage("Cow Boy.jpg");//--------->Replace this by your image. I hope you know to specify path.
function imageLoaded(e:Event):void
{
// Load Image
imageArea.addChild(imageLoader);
var mainImage:BitmapData = new BitmapData(imageArea.width,imageArea.height);
var tileX:Number = 36;
var tileY:Number = 36;
var bitmapArray:Array;
var tilesH:uint = Math.ceil(mainImage.width / tileX); // Number of Columns
var tilesV:uint = Math.ceil(mainImage.height / tileY);// Number of Rows
mainImage.draw(imageArea);
imageArea.x += 500;
bitmapArray = new Array();
for (var i:Number = 0; i < tilesH; i++)
{
bitmapArray[i] = new Array();
for (var n:Number = 0; n < tilesV; n++)
{
var tempData:BitmapData=new BitmapData(tileX,tileY);
var tempRect = new Rectangle((tileX * i),(tileY * n),tileX,tileY);
tempData.copyPixels(mainImage,tempRect,new Point(0,0));
bitmapArray[i][n]=tempData;
}
}
for (var j:uint =0; j<bitmapArray.length; j++)
{
for (var k:uint=0; k<bitmapArray[j].length; k++)
{
var bitmap:Bitmap=new Bitmap(bitmapArray[j][k]);
this.addChild(bitmap);
bitmap.x = (j+1)* bitmap.width + j*10;
bitmap.y = (k+1)* bitmap.height + k*10;
}
}
}
function imageLoading(e:ProgressEvent):void
{
// Use it to get current download progress
// Hint: You could tie the values to a preloader :)
}
You can use the BitmapData function copyPixels, see this link. It lets you copy pixels from one region(specified by a Rectangle) in the source BitmapData, to a specific Point in the destination BitmapData. Basically you could just create a new BitmapData for each 32x32 square and loop through the loaded object to populate the squares with copyPixels.

Multiple movieclips all go to the same spot; What am i doing wrong?

So I'm trying to shoot multiple bullets out of my body and it all works except I have an odd problem of just one bullet showing up and updating to set position for the new ones.
I have a move able player thats supposed to shoot and I test this code by moving the player and shooting. Im taking it step by step in creating this.
The result of tracing the bulletContainer counts correctly in that its telling me that movieclips ARE being added to the stage; I Just know it comes down to some kind of logic that im forgetting.
Here's My Code (The Bullet it self is a class)
UPDATE*
Everything in this code works fine except for I stated earlier some code seems reduntned because I've resorted to a different approaches.
BulletGod Class:
public class bulletGod extends MovieClip{
//Register Variables
//~Global
var globalPath = "http://127.0.0.1/fleshvirusv3/serverside/"
//~MovieCLips
var newBullet:bulletClass = new bulletClass();
//~Boolean
var loadingBulletInProgress:Number = 0;
var shootingWeapon:Number = 0;
//~Timers
var fireBulletsInterval = setInterval(fireBullets, 1);
var bulletFireEvent;
//~Arrays
var bulletArray:Array = new Array();
var bulletType:Array = new Array();
var bulletContainer:Array = new Array();
//~Networking
var netBulletRequest:URLRequest = new URLRequest(globalPath+"bullets.php");
var netBulletVariables:URLVariables = new URLVariables();
var netBulletLoader:URLLoader = new URLLoader();
//~Bullet Image Loader
var mLoader:Loader = new Loader();
var mRequest:URLRequest = new URLRequest();
public function bulletGod() {
//Load every bullet for every gun
//Compile data to be requested
netBulletVariables.act = "loadBullets"
netBulletRequest.method = URLRequestMethod.POST
netBulletRequest.data = netBulletVariables;
netBulletLoader.dataFormat = URLLoaderDataFormat.VARIABLES;
netBulletLoader.addEventListener(Event.COMPLETE, getBulletImages);
netBulletLoader.load(netBulletRequest);
}
private function getBulletImages(bulletImageData:Event){
//Request every bullet URL image
//Set vars
var bulletData = bulletImageData.target.data;
//Load images
for(var i:Number = 0; i < bulletData.numBullets; i++){
bulletArray.push(bulletData["id"+i.toString()]);
bulletType.push(bulletData["bullet"+i.toString()]);
//trace(bulletData["id"+i]+"-"+bulletData["bullet"+i]);
}
//All the arrays have been set start firing the image loader/replacer
var imageLoaderInterval = setInterval(imageReplacer, 10);
}
private function imageReplacer(){
//Check to see which image needs replacing
if(!loadingBulletInProgress){
//Begin loading the next image
//Search for the next "String" in the bulletType:Array, and replace it with an image
for(var i:Number = 0; i < bulletType.length; i++){
if(getQualifiedClassName(bulletType[i]) == "String"){
//Load this image
mRequest = new URLRequest(globalPath+"ammo/"+bulletType[i]);
mLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, loadImage);
mLoader.load(mRequest);
//Stop imageReplacer() while we load image
loadingBulletInProgress = 1;
//Stop this for() loop while we load image
i = 999;
}
}
}
}
private function loadImage(BlackHole:Event){
//Image has loaded; find which array slot it needs to go into
for(var i:Number = 0; i <= bulletType.length; i++){
if(getQualifiedClassName(bulletType[i]) == "String"){
//We found which array type it belongs to; now replace the text/url location with the actual image data
var tmpNewBullet:MovieClip = new MovieClip;
tmpNewBullet.addChild(mLoader);
//Add image to array
bulletType[i] = tmpNewBullet;
//Restart loadingBullets if there are more left
loadingBulletInProgress = 0;
//Stop for() loop
i = 999;
}
}
}
//###############################################################################################################################################
private function fireBullets(){
//If player is holding down mouse; Fire weapon at rate of fire.
if(shootingWeapon >= 1){
if(bulletFireEvent == null){
//Start shooting bullets
bulletFireEvent = setInterval(allowShooting, 500);
}
}
if(shootingWeapon == 0){
//The user is not shooting so stop all bullets from firing
if(bulletFireEvent != null){
//Strop firing bullets
clearInterval(bulletFireEvent);
bulletFireEvent = null
}
}
}
private function allowShooting(){
//This function actually adds the bullets on screen
//Search for correct bullet/ammo image to attach
var bulletId:Number = 0;
for(var i:Number = 0; i < bulletArray.length; i++){
if(bulletArray[i] == shootingWeapon){
//Bullet found
bulletId = i;
//End For() loop
i = 999;
}
}
//Create new bullet
//Create Tmp Bullet
var tmpBulletId:MovieClip = new MovieClip
tmpBulletId.addChild(newBullet);
tmpBulletId.addChild(bulletType[bulletId]);
//Add To Stage
addChild(tmpBulletId)
bulletContainer.push(tmpBulletId); //Add to array of bullets
//Orientate this bullet from players body
var bulletTmpId:Number = bulletContainer.length
bulletTmpId--;
bulletContainer[bulletTmpId].x = Object(root).localSurvivor.x
bulletContainer[bulletTmpId].y = Object(root).localSurvivor.y
//addChild(bulletContainer[bulletTmpId]);
}
//_______________EXTERNAL EVENTS_______________________
public function fireBullet(weaponId:Number){
shootingWeapon = weaponId;
}
public function stopFireBullets(){
shootingWeapon = 0;
}
}
}
BulletClass:
package com{
import flash.display.*
import flash.utils.*
import flash.net.*
import flash.events.*
public class bulletClass extends MovieClip {
public var damage:Number = 0;
public function bulletClass() {
//SOME MOVEMENT CODE HERE
}
public function addAvatar(Obj:MovieClip){
this.addChild(Obj);
}
}
}
Well ... if I may say so, this code looks quite wrong. Either something is missing from the code or this code will never make the bullets fly.
First off, you can set x and y of the new bullet directly (replace everything after "orientate this bullet from players body" with this):
tmpBulletId.x = Object(root).localSurvivor.x;
tmpBulletId.y = Object(root).localSurvivor.y;
Perhaps this already helps, but your code there should already do the same.
But to let these bullets fly into any direction, you also need to add an event listener, like so:
tmpBulletId.addEventListener(Event.ENTER_FRAME, moveBullet);
function moveBullet(e:Event) {
var movedBullet:MovieClip = MovieClip(e.currentTarget);
if (movedBullet.x < 0 || movedBullet.x > movedBullet.stage.width ||
movedBullet.y < 0 || movedBullet.y > movedBullet.stage.height) {
// remove move listener, because the bullet moved out of stage
movedBullet.removeEventListener(Event.ENTER_FRAME);
}
// remove the comment (the //) from the line that you need
MovieClip(e.currentTarget).x += 1; // move right
// MovieClip(e.currentTarget).y -= 1; // move up
// MovieClip(e.currentTarget).x -= 1; // move left
// MovieClip(e.currentTarget).y += 1; // move down
}
This example lets your bullet fly to the right. If you need it flying into another direction, just comment out the line with the "move right" comment and uncomment one of the other lines.
This is of course a very simple example, but it should get you started.
I hope this helps, and that my answer is not the wrong answer to the question.
As far as I have expirienced it you can have only one copy of MovieClip object added to specific child. Best approach is to use ByteArray for the clip source and instantiate new MovieClip and pass the ByteArray as a source. It have something to do with child/parent relation since a DisplayObject can have only one parent (and a way to detach the object from scene too).
Well i ended up writeing the whole code from scratch for a 3rd time and ran into a similar problem and just for reference to anybody else that comes to a problem thats random as this one i found that problem was likly does to a conversion error somewhere that doesn't necessarily break any compiling rules. Just that i was calling a movieclip and not the class it self.