Clearing content from a movieclip in a blank keyframe in AS3 - actionscript-3

var loader:URLLoader;
var allWords:Array;
var thisWord:String;
var textContainer:MovieClip;
var textFields:Array;
var textStyle:TextFormat;
var underline:MovieClip;
var numCorrect:uint;
var totalLetters:uint;
var misses:uint;
var missesToLose:uint;
function initializeGame():void
{
loader = new URLLoader();
allWords = new Array();
textContainer = new MovieClip();
textFields = new Array();
textStyle = new TextFormat();
textStyle.font = "Courier New";
textStyle.size = 48;
textStyle.bold = true;
Hi All,
I have created this game and only added the beginning portion of the code. The entire code would be tedious to go through. I want to click a button and go to a clear keyframe, however when I test the movie the underline movieclip still shows. How can I clear the frame completely, do I have to removeChild for the movieclip? How do I do that? Is there a way to completely unload the SWF for this game after it is loaded? If so what code can I use?
Thanks

Related

trouble resetting a flash game

I'm trying to build a simple flash game in which I need to be able to restart the game if the user dies. However resetting all of the variables doesn't seem to be accomplishing anything. All of my game elements are stored in arrays and I thought that maybe setting each of them to the array constructor wasn't deleting the objects that they were pointing to and that they were left on the screen as a result. Does anyone know of a way to delete those elements (since I can't iterate over the list to delete them for obvious reasons) or does anyone know of a better way to reset a game in flash? For reference, here's the init function and the variable declarations at the top of my program that are supposed to start/reset the game.
public class Main extends MovieClip {
//put field variables here
static var hudLayer:Sprite; //layer used to represent HUD elements
static var gameLayer:Sprite; //layer used to represent objects in the game space
static var uiTextLayer:Sprite; //layer used to represent text that should appear ON TOP of the HUD
static var backgroundLayer:Sprite; //layer used to display the background image
static var players: Array; //array of all the player objects for reference
static var backgrounds:Array; //array of all the background objects
static var lines: Array; //array of all the lines
static var powerUps:Array; //array of all the powerups
static var enemies:Array; //array of all the enemies
static var miscellaneousObjects:Array; //array of miscellaneous objects that I'd like to be able to keep track of
var xCoords:Array, yCoords:Array; //Used to temporarily hold x and y coordinates when making new drawings
static var grav:Number; //coefficient representing the force of gravity
static var isPaused:Boolean; //manages pausing mechanic
static var timer:Timer; //used for time delayed updating of game elements
var pt:Point; //variable used by collision detection
var asteroidTiming:Number; //used to properly delay creating of asteroids on the screen
static var asteroidDelay:Number; //current delay between when asteroids are deployed, changes over course of execution
static var score:Number; //this should be self-explanatory
var scoreField:TextField; //used to display the score
static var myTextFormat:TextFormat; //used to format the text in the scoreField
static var inGameOver:Boolean; //used to determine if we're at the game over screen
[Frame(factoryClass="Preloader")]
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
public function init(e:Event = null):void {
removeEventListener(Event.ADDED_TO_STAGE, init);
//set up the Sprite Layers
backgroundLayer = new Sprite();
gameLayer = new Sprite();
hudLayer = new Sprite();
uiTextLayer = new Sprite();
addChild(backgroundLayer);
addChild(gameLayer);
addChild(hudLayer);
addChild(uiTextLayer);
//instantiate important variables
xCoords = new Array();
yCoords = new Array();
players = new Array();
backgrounds = new Array();
enemies = new Array();
powerUps = new Array();
miscellaneousObjects = new Array();
grav = .04;
addBackGround();
addPlayer(400, 50);
isPaused = false;
lines = new Array();
score = 0;
inGameOver = false;
//instantiate text fields
scoreField = new TextField();
scoreField.text = "Score: " + score;
hudLayer.addChild(scoreField);
scoreField.x = 20;
scoreField.y = 20;
scoreField.textColor = 0xFFFFFF;
myTextFormat = new TextFormat();
myTextFormat.size = 15;
scoreField.setTextFormat(myTextFormat);
//set up timer
timer = new Timer(5);
timer.addEventListener(TimerEvent.TIMER, function():void { update()});
timer.start()
asteroidTiming = 0;
asteroidDelay = 150;
//set up mouse listener
stage.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownEvent);
//set up key listener
stage.addEventListener(KeyboardEvent.KEY_DOWN, keyEvent);
//tests
}
Since I can't see all your code, I will guess that you are not using removechild() to get rid of display objects off the stage.
To create a object:
var object:DisplayObject = new DisplayObject();
To make it visible on the display list:
parent.addChild(object);
To remove it from the display list:
parent.removeChild(object);
To erase its memory:
object=null;
(These four things must be done in this order, for this to work properly. IF you make something null without removing it from the display list, you leave it there, still visible, with no way of referencing it. It like lost in your application.
You have to make sure you always use removeChild() before making a variable null, or overwriting the variable.

For loops, arrays and movie clips - how to achieve a dynamic system

I am working on a Flash scene that reads from an XML file to "build" up an animation itself.
Reading the XML is no problem, that works like a charm. My issue is when I come to placing the assets (images) on to the stage.
My code is below:
import flash.display.Sprite;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.display.MovieClip;
var xmlLoader:URLLoader;
var builderXml:XML;
var container:MovieClip = new MovieClip();
var assetsArray:Array = new Array();
var bg:Sprite;
stage.addChild(container);
init();
function init():void
{
xmlLoader = new URLLoader();
xmlLoader.load(new URLRequest("build_me.xml"));
xmlLoader.addEventListener(Event.COMPLETE, processXML);
}
function processXML(e:Event):void {
builderXml = new XML(e.target.data);
for (var i:int = 0; i < builderXml.assets.*.length(); i++){
var image:MovieClip = new MovieClip();
var assetArray:Array = new Array();
image.x = builderXml.assets.asset[i].start.position.x;
image.y = builderXml.assets.asset[i].start.position.y;
trace(image.x);
assetArray.push(builderXml.assets.asset[i].source);
assetArray.push(builderXml.assets.asset[i].start.scale);
assetArray.push(builderXml.assets.asset[i].start.position.x);
assetArray.push(builderXml.assets.asset[i].start.position.y);
assetArray.push(builderXml.assets.asset[i].start.rotation);
assetArray.push(image);
assetsArray.push(assetArray);
var lc:LoaderContext = new LoaderContext();
lc.checkPolicyFile = false;
var loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, onImageLoaded);
var _myURLRequest = new URLRequest(builderXml.assets.asset[i].source);
loader.load(_myURLRequest, lc);
function onImageLoaded(e:Event):void
{
loader.contentLoaderInfo.removeEventListener(Event.COMPLETE, onImageLoaded);
image.addChild(e.target.content);
}
container.addChild(assetsArray[i][5]);
}
trace(assetsArray);
}
My XML has 2 assets listed, one 1280 x 720 image for a backdrop and the other is a simple logo that I want to position, using set x and y coordinates.
The problem is that both assets are being added to the same movieclip, despite the fact I am creating a new MC instance inside the FOR loop.
How can I get the assets to adhere to separate movieclips that I can then store in the array (pretty sure I am storing the current MC properly in the array, just happens that the MC contains 2 images, not 1 a piece)
Also, why is it that I cannot access the variable "i" inside the "onImageLoaded" function? It sits inside the FOR loop...
You are using a global variable inside a listener, and expect it to not being changed when the listener would actually fire. Listeners are asynchronous, so you should track which of the loaders fired a Event.COMPLETE event so that you could retrieve a correct instance of image MC out of those prepared at the XML parsing step, and only then stuff the loader's content inside it. This my answer has a method of doing just that, the method you should use is similar to the one that's used to retrieve a corresponding progress bar over there.

AS3. EventListener.Click depends on position

I'm doing a button on AS3 made out of a sprite wich (just a simple square). When I add the event listener so that it acts as a button it works but depending on button.x, so when I put the button where I want the button stops working.
Thanks
public function pintaInterficieTrad(){
while(numChildren != 0) removeChildAt(0);
var idioma = new TextField();
idioma.text=traductor.*[numTrad].*;
idioma.width=200;
idioma.selectable=false;
idioma.setTextFormat(format);
idioma.x=20;
idioma.y=20;
addChild(idioma);
var trad = new Sprite();
trad.graphics.lineStyle(5,0x00ff00);
trad.graphics.beginFill(0x000000);
trad.graphics.drawRect(300,20,150,70);
addChild(trad);
var textTrad = new TextField();
if(numTrad==0) {
textTrad.text="Traduir";
}else{
textTrad.text="Traducir";
}
textTrad.width=200;
textTrad.selectable=false;
textTrad.setTextFormat(format);
textTrad.x=270;
textTrad.y=40;
addChild(textTrad);
var getBack = new Sprite();
getBack.graphics.lineStyle(5,0x00ff00);
getBack.graphics.beginFill(0x000000);
getBack.graphics.drawRect(500,20,150,70);
addChild(getBack);
var textgetBack = new TextField();
if(numTrad==0) {
textgetBack.text="Tornar";
}else{
textgetBack.text="Volver";
}
textgetBack.width=200;
textgetBack.selectable=false;
textgetBack.setTextFormat(format);
textgetBack.x=470;
textgetBack.y=40;
addChild(textgetBack);
trad.addEventListener(MouseEvent.CLICK,traduirBtn);
getBack.addEventListener(MouseEvent.CLICK,tornarBtn);
var userBox = new Sprite();
userBox.graphics.lineStyle(2,0x00ff00);
userBox.graphics.beginFill(0xffffff);
userBox.graphics.drawRect(40,130,610,160);
addChild(userBox);
var tradBox = new Sprite();
tradBox.graphics.lineStyle(2,0x00ff00);
tradBox.graphics.beginFill(0xffffff);
tradBox.graphics.drawRect(40,320,610,160);
addChild(tradBox);
var formatTxt = new TextFormat();
formatTxt.color=0x000000;
formatTxt.size=14;
var textUser = new TextField();
var textTraduit = new TextField();
textUser.defaultTextFormat=formatTxt;
textUser.text = textUsuari;
textUser.width = 600;
textUser.height = 150;
textUser.x=45;
textUser.y=130;
addChild(textUser);
textTraduit.text = traduccio;
textTraduit.setTextFormat(formatTxt);
textTraduit.width = 600;
textTraduit.height = 150;
textTraduit.x=45;
textTraduit.y=325;
addChild(textTraduit);
}
public function traduirBtn(e){
while(numChildren != 0) removeChildAt(0);
tradueix();
pintaInterficieTrad();
}
public function tornarBtn(e){
while(numChildren != 0) removeChildAt(0);
pintaMenu();
}
}
If I put the squares on x=0 they do what they're suposed to do...
seems like the button you're talking about is trad. You're addChilding it quite early in your code, which means that antoher displayobject could get above it at the same position. When you click at that position, the click event will only get send to the top most element, so try adding the elements you want people to interact with as the last (buttons, text field inputs, etc.)
Your problem is in the fact that you are adding the text over the button and the text is being clicked, not the button.
Add the text to the button itself and your click event will work.
Also verify that no other component is covering the button. Even if transparent, like a textbox.

Actionscript 3: Converting bytearray to PNG and display on the scene

I'm getting getting a PNG image stored in SQL through a WCF get call. The image is encoded as a base64 string and delivered to my AS3 code. I need to extract the image from the data and show it on the scene.
Among other things, I have also tried this...
var imgArray:ByteArray = Base64.decodeToByteArray(responseXML.ImageObject);
var myRect:Rectangle = new Rectangle(100,100,200,200);
var bmd:BitmapData = new BitmapData(200,200,true,0xAAAAAAAA);
bmd.setPixels(myRect, imgArray);
var image:Bitmap = new Bitmap(bmd,"auto",true);
this.addChild(image);
but to no avail.
HELP!
why don't you use a loader and loadbytes? It's native.
var loader:Loader = new Loader();
loader.contentLoaderInfo.addEventListener(Event.COMPLETE, handleLoad)
loader.loadbytes(byteArray);
private function handleLoad(e:Event):void {
var loader:Loader = e.currentTarget as Loader;
// removelistener,etc
trace(loader.content as Bitmap);
}
The problem with your code is that PNG is compressed, bitmap is uncompressed.
I used DanielH's input and got the image to load on my stage. Here is what I did in the event handler function...
function ImageLoaded(e:Event):void
{
var bmd:BitmapData = new BitmapData(imageLoader.ImageLoader.width,imageLoader.ImageLoader.height,true, 0xFFFFFF);
bmd.draw(imageLoader.ImageLoader);
var image:Bitmap = new Bitmap(bmd,"auto",true);
image.width=40;
image.height=40;
if(!CheckAndStoreImageIDKey(imageLoader.ImageID))
{
Images[imageLoader.ImageID] = image;
}
}
Try PNGDecoder (http://www.ionsden.com/content/pngdecoder)
import ion.utils.png.PNGDecoder;
var bmd:BitmapData = PNGDecoder.decodeImage(imgArray);

as3 moving image from one mc to another

With the code below I created some imgMcA and some imgMcB then I loaded images into imgMcA ones. ImgMcBs have no image at that moment. So if one of imgMcA is clicked the image should be transferred to one of the empty imgMcBs (may be randomly) and if imgmcB is clicked later the image should move back to its imgMcA back. I could not find out how I can accomplish this.
Thanks in advance
function imageList(mcname, img, index){
var imgMcA:MovieClip=new MovieClip();
imgMcA.graphics.beginFill(0x000000);
imgMcA.graphics.drawRect(0,0,imgWidth,imgHeight);
imgMcA.graphics.endFill();
imgMcA.name=lemma;
imgMcA.addEventListener(MouseEvent.CLICK, moveImage);
var imgMcB:MovieClip=new MovieClip();
imgMcB.graphics.beginFill(0x000000);
imgMcB.graphics.drawRect(0,0,imgWidth,imgHeight);
imgMcB.graphics.endFill();
imgMcB.name=index;
addChild(imgMcB);
var imgLoader:Loader = new Loader();
imgLoader.load(new URLRequest(img));
imgLoader.contentLoaderInfo.addEventListener(Event.COMPLETE, changeProperties);
imgLoader.mouseEnabled=false;
imgMcA.addChild(imgLoader);
}
function moveImage(evnt:MouseEvent){
}
You could linked mcA & mcB by adding them to the same parent.
function createBlock():void
{
var imgLoader:Loader = new Loader();
//add the loading code here...
var mcA:Sprite = new Sprite();
var mcB:Sprite = new Sprite();
// add Click event listeners for both Mcs here...
var parent:Sprite = new Sprite();
//add Children
parent.addChild(mcA);
parent.addChild(mcB);
addChild(parent);
}
function mouseClickHandler(event:MouseEvent)
{
var dispatcher:Sprite = event.currentTarget as Sprite;
//if you added a Loader to it
if( dispatcher.numChildren > 0)
{
//retrieve the image
var img:Loader = dispatcher.getChildAt(0);
//identify the parent
var parent:Sprite = dispatcher.parent;
var index:int = parent.getChildIndex(dispatcher);
//identify the receiving MC
//of course this only works with two children!!!
if(index > 0)
var receiver:Sprite = parent.getChildAt(0) as Sprite;
else
receiver = parent.getChildAt(1) as Sprite;
//add the image to the other MC
receiver.addChild(img);
}
}
The rest is not too complicated to achieve. You will need to use a Boolean and add a TextField. If the TextField contains text, set the Boolean to true.
It may be worth looking at Classes or you could use an Object as a container for the MovieClips, the TextField and the Boolean, although a Class will give you more flexibility...
With a Class, you wouldn't have to iterate in order to find what does what. Your Click listener would look something like this:
private function mouseClickHandler(event:MouseEvent)
{
receiver.addChild( image );
if( hasText)
imageReturn();
}