Changing the UrlLoader.load - actionscript-3

package {
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.text.StyleSheet;
import flash.text.TextField;
import flash.text.TextFieldType;
import flash.text.TextFormat;
import flash.text.*
import flash.net.*
public class SpeechBox extends MovieClip{
public var textLoader:URLLoader = new URLLoader();
public var box:Sprite = new Sprite();
public var nextBox:Sprite = new Sprite();
private var nextText:TextField = new TextField();
private var textBox:TextField = new TextField();
private var speechText:String;
public var _speechBoxCheck:Timer = new Timer(1000);
public var clickedNext:Boolean = false;
public function SpeechBox()
{
textLoader.addEventListener(Event.COMPLETE, onLoaded);
textBox.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownScroll);
_speechBoxCheck.addEventListener(TimerEvent.TIMER, speechBoxCheck);
_speechBoxCheck.start();
//////////////////SPEECH BOX///////////////////
box.graphics.lineStyle(3.5,0xffffff);
box.graphics.beginFill(0x003366, .35);
box.graphics.drawRoundRect(0,0,650,145,20);
box.graphics.endFill();
box.x = 100;
box.y = 450;
addChild(box);
//////////////////SPEECH TEXT///////////////////
var speechFont = new DataText();
var textFormat:TextFormat = new TextFormat();
textFormat.font = speechFont.fontName;
textFormat.align = TextFormatAlign.LEFT;
textFormat.leading = 3;
textFormat.color = 0xFFFFFF;
textFormat.size = 16;
textBox.defaultTextFormat = textFormat;
textBox.width = 620;
textBox.height = 115;
textBox.x = box.x + 14;
textBox.y = box.y + 14;
textBox.multiline = true;
textBox.wordWrap = true;
textBox.selectable = false;
addChild(textBox);
//////////////////NEXT BUTTON///////////////////
nextBox.graphics.beginFill(0x000000, 0);
nextBox.graphics.drawRect(0,0,50,30);
nextBox.graphics.endFill();
nextBox.x = box.x + 600;
nextBox.y = box.y + 115;
nextText.defaultTextFormat = textFormat;
nextText.text = "Next";
nextText.textColor = 0xffffff;
nextText.autoSize = "left";
nextText.selectable = false;
nextText.mouseEnabled = false;
nextText.x = nextBox.x + 2
nextText.y = nextBox.y + 5
nextBox.buttonMode = true;
//nextBox.mouseEnabled = true;
nextBox.addEventListener(MouseEvent.MOUSE_DOWN, clickNext);
nextBox.addEventListener(MouseEvent.MOUSE_OVER, moveOver);
nextBox.addEventListener(MouseEvent.MOUSE_OUT, moveOut);
}
function onLoaded(e:Event):void {
trace(e.target.data);
textBox.text = e.target.data;
}
function mouseDownScroll(event:MouseEvent):void
{
textBox.scrollV+=4;
textBox.addEventListener(MouseEvent.MOUSE_UP,mouseup);
}
function mouseup(event:MouseEvent):void
{
if(textBox.scrollV == textBox.maxScrollV)
{
addChild(nextBox);
addChild(nextText);
}
}
function clickNext(event:MouseEvent):void
{
trace("click");
clickedNext = true;
_speechBoxCheck.stop();
(parent as Main).onTransition.start();
textBox.scrollV = 0;
textLoader.removeEventListener(Event.COMPLETE, onLoaded);
this.parent.removeChild(this);
}
function moveOver(event:MouseEvent):void
{
nextText.textColor = 0xffcc00;
}
function moveOut(event:MouseEvent):void
{
nextText.textColor = 0xffffff;
}
///////////////////////////////////////////////////////////////
function speechBoxCheck(event:TimerEvent)
{
if ((parent as Main).introduction == true)
{
textLoader.load(new URLRequest("Texts/LV1introduction.txt"));
trace("beginning");
(parent as Main).onTransition.stop();
}
if ((parent as Main).levelNum == 1)
{
textLoader.load(new URLRequest("Texts/LV1complete.txt"));
trace("go to lv 2")
(parent as Main).onTransition.stop();
}
if ((parent as Main).levelNum == 2)
{
textLoader.load(new URLRequest("Texts/LV2complete.txt"));
trace("go to lv 3")
(parent as Main).onTransition.stop();
}
}
}
}
EDIT: When the game starts, the LV1 introduction text starts. Once the scrollV equals maxScrollV, a next buttons appears. Click that, it will delete itself and the game starts. Once you beat stage one, levelNum automatically equals 2 and I add this class again from my main document class. However, it will show the same text over and over, regardless of what level.
So does the urlLoader always stay the same? If so, how can I change it?

URLLoader can be reused to load another data with new URLRequest instance. It is completely OK to reuse same URLLoader instance to load another file. Your problem is not in URLLoader, but in logics or somewhere else. You'd better try debuggers to make sure variable level has correct value of 2.
Why are you loading text file EVERY second? It would be ok to load them only level is changed.
does this textLoader instance have event listeners attached?
:::::::::EDITED:::::::::
You are removing event Listeners from textLoader in clickNext() call. textLoader will load file, but will not run onLoaded() to update textBox.text
Your speechBoxCheck() method is doing it wrong. 1. You must make only 1 load() call in speechBox() method. Your conditionals in the method are not exclusive, and it may cause trouble when multiple load() calls are made (previous loading operation will be canceled). consider "else if" chain.
it is not recommended to do something like loading files in this fashion. Unnecessary I/O operations, especially in runtime, should be avoided. Only load files when it is needed; In this case, it is when level changes.

Related

Access of undefined propety and other errors (AS3)

ok so I am trying to work on making my scripts external .as files.
I had them on the timeline and they worked fine but when I put them in the as file they don't work at all.
This is my code as of right now
so I got the script working externally thank you very much :)
I just need to addchild to the stage. I use
import Scripts.resources.main;
var Main:main = new main;
addChild(Main);
In my external script I addchild in the main function now.
package Scripts.resources
{
import flash.events.Event;
import flash.events.MouseEvent;
import flash.net.URLRequest;
import flash.net.URLVariables;
import flash.net.URLLoader;
import flash.net.URLRequestMethod;
import flash.events.OutputProgressEvent;
import flash.display.Sprite;
import flash.display.MovieClip;
import flash.display.Stage;
import flash.events.EventDispatcher;
public class main extends EventDispatcher{
private var _stage:Stage;
var url:String = "php/data_user.php";
//declare our graphic vars
var stmBar:resourceBar;
var tenBar:resourceBar;
var potBar:resourceBar;
var spdBar:resourceBar;
var crtBar:resourceBar;
var awrBar:resourceBar;
var resBar:resourceBar;
var statUp:Sprite;
//This Returns the number of milliseconds since midnight January 1, 1970
//Tacking the time variable at the end of your php file locations will ensure their is no caching
var now:Date = new Date();
var time:Number = now.getTime();
/*
* These should point to your PHP files. I recommend NOT using an http path because accessing
* the site via 'www.yoursite.com' versus 'yoursite.com' makes a difference and will cause undefined
* issues. Instead use a relative path like: var registerLocation:String = "membership/php/register.php";
*/
var registerLocation:String = "php/register.php" + "?" + time;
var loginLocation:String = "php/login.php" + "?" + time;
var editProfileLocation:String = "php/editprofile.php" + "?" + time;
var forgotPWLocation:String = "php/forgotpw.php" + "?" + time;
var statsLocation:String = "php/user_stats.php" + "?" + time;
var statsGylph:String = "php/data_user.php" + "?" + time;
//userInfo is the Object that gets populated that stores all of the users information.
var userInfo:Object = new Object();
//The minimum length of a password.
var passwordLength:Number = 4;
/*
* var cookie refers to swfObjects addVariable. If you look at membership.php, where swf
* object is defined, addVariable shows a var called usercookie.
* This help decide if the program should remember the users username or not.
*/
//cookieUserName would be the username that gets put into the user field if the cookie has been set
public function main(stage:Stage)
{
_stage = stage;
var _loader:URLLoader = new URLLoader();
var _request:URLRequest = new URLRequest(url + "?id=" + userInfo.id);
_request.method = URLRequestMethod.GET;
_loader.addEventListener(Event.COMPLETE, onLoadData);
_loader.load(_request);
_stage.addChild(stmBar);
stmBar.x = -50;
stmBar.y = 200;
}
public function MyClass(){
this.addEventListener(Event.ADDED_TO_STAGE, addedToStage);
}
private function addedToStage(e:Event):void {
this.removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
//this code will run after you've added this object to the stage
//it is the equivalent of when timeline code runs
}
function onLoadData(e:Event):void {
var str:String = e.target.data;
var array:Array =str.split("-");
for(var i:int;i < array.length; i++)
output(i+1,array[i]);
}
public function output(field:Number,i:int):void
{
if (field == 5)
{
stmBar = new resourceBar(0, 0, i, "Stamina", 0x990000);
stmBar.x = -200;
stmBar.y = 50;
}
else if (field == 6)
{
tenBar = new resourceBar(0, 0, i, "Tenacity", 0xFF9900);
tenBar.x = 200;
tenBar.y = 50;
}
else if (field == 7)
{
potBar = new resourceBar(0, 0, i, "Potency", 0xCC3399);
potBar.x = -200;
potBar.y = 100;
}
else if (field == 8)
{
spdBar = new resourceBar(0, 0, i, "Speed", 0x00CC00);
spdBar.x = 200;
spdBar.y = 100;
}
else if (field == 9)
{
crtBar = new resourceBar(0, 0, i, "Crit", 0x009999);
crtBar.x = -200;
crtBar.y = 150;
}
else if (field == 10)
{
awrBar = new resourceBar(0, 0, i, "Awareness", 0x3399CC);
awrBar.x = 200;
awrBar.y = 150;
}
else if (field == 11)
{
resBar = new resourceBar(0, 0, i, "Resistance", 0x999999);
resBar.x = -200;
resBar.y = 200;
addEventListener(Event.ENTER_FRAME, onLoop);
}
function onLoop(e:Event):void
{
stmBar.change(1);
tenBar.change(1);
potBar.change(1);
spdBar.change(1);
crtBar.change(1);
awrBar.change(1);
resBar.change(1);
}
}
}
}
my problem is it won't add the children in the main function when I addchild of main. am I able to add a child with children inside it?
In class files, all code needs to be wrapped in a function. So where you have:
_loader = new URLLoader();
_request = new URLRequest(url + "?id=" + (STAGE.parent as MovieClip).userInfo.id);
_request.method = URLRequestMethod.GET;
_loader.addEventListener(Event.COMPLETE, onLoadData);
_loader.load(_request);
You need to place it in a function for the code to be valid. If you want that bit of code to run right away, then you can place it in a constructor (that is the function in class that runs when you instantiate with the new keyword, eg new main(). If main is your document class, then the constructor is the very first code to run in the application.
Constructors are public functions that have the exact name of your Class.
public function main(){
_loader = new URLLoader();
_request = new URLRequest(url + "?id=" + (STAGE.parent as MovieClip).userInfo.id);
_request.method = URLRequestMethod.GET;
_loader.addEventListener(Event.COMPLETE, onLoadData);
_loader.load(_request);
}
Something to keep in mind, is that in the constructor of display objects, the stage/parent/root keywords will NOT have any value, as those are populated once the display object has been added to the display. So, it's common to use this approach:
package MyClass extends Sprite {
public function MyClass(){
this.addEventListener(Event.ADDED_TO_STAGE, addedToStage);
}
private function addedToStage(e:Event):void {
this.removeEventListener(Event.ADDED_TO_STAGE, addedToStage);
//this code will run after you've added this object to the stage
//it is the equivalent of when timeline code runs
}
}
Also, a tip now that you are writing class files - follow the convention of making class names start with an Uppercase letter, and instances of classes start with lowercase letters.

Updating and displaying a variable in AS3

I have been following an AS3 tutorial for an avoider game, the trouble is the tutorial is for CS5 and I am using Flash Develop. I am completely stuck trying to update and display the score. I have read through several posts on SO and elsewhere and still can't seem to fix it.
Here is the Score class that I call to display the score and it contains the function that updates the "score" value.
package
{
import flash.display.Sprite;
import flash.events.TextEvent;
import flash.text.TextField
import flash.text.TextFormat
public class Score extends Sprite
{
public var scoreDisplay:String;
public var currentValue:int;
public function Score()
{
updateDisplay()
}
public function updateDisplay():void
{
scoreDisplay = currentValue.toString();
var format:TextFormat = new TextFormat();
format.size = 25;
format.font = "Verdana"
var myText:TextField = new TextField();
myText.defaultTextFormat = format;
myText.text = scoreDisplay;
myText.background = true;
myText.autoSize
myText.width = 50;
myText.height = 35;
addChild(myText)
myText.x = 340
myText.y = 10
myText.mouseEnabled = false
}
public function addToValue( amountToAdd:Number ):void
{
trace("addToValue")
trace(currentValue)
currentValue = currentValue + amountToAdd;
trace(currentValue + " 1")
}
}
}
and here is the Game class I am running to increase the "score" per tick.
package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.events.TimerEvent;
import flash.text.TextField;
import flash.text.TextFormat;
import flash.utils.Timer;
import Score;
public class Game extends Sprite
{
public var army:Array;
public var gameTimer:Timer;
public var player:Player;
public var background:Sprite;
public function Game()
{
army = new Array();
var newenemy:Enemy = new Enemy(100, -15);
army.push(newenemy);
addChild(newenemy);
player = new Player();
addChild(player);
player.x = mouseX;
player.y = mouseY;
gameTimer = new Timer(20);
gameTimer.addEventListener(TimerEvent.TIMER, move);
gameTimer.addEventListener(TimerEvent.TIMER, onTick);
gameTimer.start();
}
private function move(timerEvent:TimerEvent):void
{
player.x = mouseX;
player.y = mouseY;
for each (var enemy:Enemy in army)
{
enemy.moveDownABit();
if (player.hitTestObject(enemy))
{
gameTimer.stop();
dispatchEvent( new AvatarEvent( AvatarEvent.DEAD));
}
}
}
public function onTick(e:Event):void
{
if (Math.random() < .1)
{
var randomX:Number = Math.random() * 400;
var newEnemy:Enemy = new Enemy(randomX, -15);
army.push(newEnemy);
addChild(newEnemy);
var instanceScore:Score = new Score();
instanceScore.addToValue(10)
}
}
}
}
My trace function outputs "addToValue, 0, 10 1" and repeats that, never changing the 'curentValue' variable past 0. I can tell that the 'amountToAdd' is functioning properly but have no idea why 'currentValue' is always reset to 0.
questions on SO that I viewed;
Display dynamic variable on next key frame AS3
Avoider Game Tutorial: Score not working
The problem is this:
var instanceScore:Score = new Score();
This means that every time there is a tick, you create new score. When you create new score, it starts from 0. You update it to 10, and on the next tick, you ignore the old value of 10 by creating a whole new class. The new class has a value of 0, as it never has it's value increased before. Then you increase it again.. and a new tick starts (looping)
What you need to do is to instantiate score instance ONLY ONCE and save it as a class member variable. Then you can call increase to it.

Correct usage of addtoStage when loading external swf

I am loading an external swf file into a parent swf file.
Previously, I was getting error 1009 and fixed that by using a listener event to add the swf to the stage before running any scripts.
The swf however fails to load completely when embedded into a parent swf as seen in this URL
http://viewer.zmags.com/publication/06b68a69?viewType=pubPreview#/06b68a69/1
Here is the code I am using.
Thank you for any input.
package
{
import com.greensock.TweenLite;
import flash.display.DisplayObject;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.display.SpreadMethod;
import flash.display.Sprite;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.utils.getDefinitionByName;
public class slider5 extends Sprite
{
public var thumbPath:String = "Trailchair_thumb";
public var featPath:String = "Trailchair";
public var sliderIndex:Number = 1;
public var currBg:Bitmap = new Bitmap();
public var thumbCount:Number = 8;
public var thumbHolder:Sprite = new Sprite();
public var thumbMask:Sprite = new Sprite();
public var thumbX:Number = 0;
public var thmPadding:Number = 10;
public var thmWidth:Number;
public var navLeft:Sprite = new Sprite();
public var navRight:Sprite = new Sprite();
public var timer:Timer = new Timer(5000,0);
public var sliderDir:String = "fwd";
public function slider5()
{
addEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
}
public function onAddedToStage(e:Event):void{
removeEventListener(Event.ADDED_TO_STAGE, onAddedToStage);
//THE BACKGROUND IMAGE
currBg.alpha = 1;
stage.addChildAt(currBg, 0);
changeBg(sliderIndex);
//The thumbMask a sprite with graphic rectangle
thumbMask.x = 87;
thumbMask.y = 572;
thumbMask.graphics.beginFill(0xFFFFFF);
thumbMask.graphics.drawRect(0,0, 406, 181);
stage.addChildAt(thumbMask, 2);
//The thumbSlider
thumbHolder.x = 228;
thumbHolder.y = 573;
stage.addChildAt(thumbHolder, 1);
thumbHolder.mask = thumbMask;
buildThumbs();
//add the nav
navLeft.x = 100;
navLeft.y = 609;
navRight.x = 496;
navRight.y = 609;
stage.addChildAt(navLeft, 4);
stage.addChildAt(navRight, 4);
var navBmp:Bitmap = new Bitmap();
navBmp.bitmapData = new navarrow(109,109);
var navBmp_Rt:Bitmap = new Bitmap();
navBmp_Rt.bitmapData = new navarrow(109,109);
navLeft.addChild(navBmp);
navLeft.scaleX *= -1;
navRight.addChild(navBmp_Rt);
navLeft.useHandCursor = true;
navLeft.buttonMode = true;
navRight.useHandCursor = true;
navRight.buttonMode = true;
navLeft.name = "left";
navRight.name = "right";
navLeft.addEventListener(MouseEvent.CLICK, navClick);
navRight.addEventListener(MouseEvent.CLICK, navClick);
//add the active item frame
var frame:Sprite = new Sprite();
frame.x = 226;
frame.y = 570;
frame.graphics.lineStyle(10, 0x000000);
frame.graphics.drawRect(0,0,131, 181);
stage.addChildAt(frame, 6);
timer.addEventListener(TimerEvent.TIMER, timeEvt);
timer.start();
}
public function changeBg(index):void
{
//set the first slide from our library and add to the stage
var currBg_Class:Class = getDefinitionByName( featPath + index ) as Class;
currBg.bitmapData = new currBg_Class(597,842);
//fade it in
TweenLite.from(currBg, 0.5, {alpha:0});
}
public function buildThumbs():void
{
var currThm:Class;
for (var i:uint = 1; i<=thumbCount; i++)
{
currThm = getDefinitionByName( thumbPath + i ) as Class;
var thmBmp:Bitmap = new Bitmap();
thmBmp.bitmapData = new currThm(126,176);
thmBmp.x = thumbX;
thumbHolder.addChild(thmBmp);
thumbX += thmBmp.width + thmPadding;
}
thmWidth = thmBmp.width + thmPadding;
}
public function navClick(e):void
{
timer.reset();
timer.start();
var dir:String = e.currentTarget.name;
if (dir=="left" && thumbHolder.x < 228 )
{
sliderIndex--;
TweenLite.to(thumbHolder, 0.5, {x:thumbHolder.x + thmWidth});
//thumbHolder.x = thumbHolder.x + thmWidth;
}
else if (dir=="right" && thumbHolder.x > - 724 )
{
sliderIndex++;
TweenLite.to(thumbHolder, 0.5, {x:thumbHolder.x - thmWidth});
//thumbHolder.x = thumbHolder.x - thmWidth;
}
if (sliderIndex == thumbCount)
{
sliderDir = "bk";
}
if (sliderIndex == 1)
{
sliderDir = "fwd";
}
changeBg(sliderIndex);
}
public function timeEvt(e):void
{
if (sliderDir == "fwd")
{
navRight.dispatchEvent(new Event(MouseEvent.CLICK));
}
else if (sliderDir == "bk")
{
navLeft.dispatchEvent(new Event(MouseEvent.CLICK));
}
}
}
}
If you still need it you can try these two suggestions. Note I didnt know about Zmags and initially assumed that it was your own domain name. That's why I suggested you use the Loader class. It worked for me when I did a test version of a parent.swf' that loaded a test 'child.swf' containing your code. It actually loaded the child swf without problems.
Change from extending Sprite to extending MovieClip
Avoid checking for added to stage in this project
Explanations:
Extending MovieClip instead of Sprite
I Long story short Flash wont like your swf extending Sprite then being opened by a parent loader that extends Movieclip. The ZMag player will be extending MovieClip. It's logical and the docs do confirm this in a way. Whether it fixes your issue or not just keep it MovieClip when using ZMags.
Avoiding Stage referencing in your code..
Looking at this Zmags Q&A documentaion:
http://community.zmags.com/articles/Knowledgebase/Common-questions-on-flash-integration
Looking at Question 4.. In their answer these two stand out.
Reference of the stage parameter in the uploaded SWF conflicting with the publication
Badly or locally referenced resources in the SWF you uploaded which cannot be found
Is it really necessary to have an added_to_stage check in this? If it wont hurt then I suggest dropping the stage_added checking from function slider5() and instead cut/paste in there the code you have from the function onAddedToStage(e:Event).
Hope it helps.

flash actionscript error 5007 while file is not linked or included in any way

I created an xfl file called myfile.xfl and linked it to Main.as.
Because my script is kind of extensive, I planned to distribute it over several as-files.
The Main.as looks like this and is linked correctly from the xfl-file:
package {
import flash.net.URLLoader;
import flash.net.URLRequest;
import flash.xml.*;
import flash.events.Event;
import flash.display.Loader;
import flash.display.LoaderInfo;
import flash.display.MovieClip;
import flash.text.*;
import flash.events.MouseEvent;
import flash.media.Sound;
import flash.media.SoundChannel;
public class Main extends MovieClip
{
var bestand:String;
var titelFont:Font = new Titelfont();
var werkFont:Font = new Werkfont();
var titelfmt:TextFormat = new TextFormat();
var werkfmt:TextFormat = new TextFormat();
var inputfmt:TextFormat = new TextFormat();
var snd:Sound;
var cnl:SoundChannel = new SoundChannel();
var xmlLoader:URLLoader;
var myList:XML;
var introClip:Containerclip = new Containerclip();
var dicteeClip:Containerclip = new Containerclip();
public function Main()
{
//DE INFORMATIE UIT DE URL //
//bestand = LoaderInfo(this.root.loaderInfo).parameters["bestand"];
//bestand += ".xml";
bestand = "xml/bron.xml"
loadXml();
}
function loadXml():void
{
xmlLoader = new URLLoader(new URLRequest(bestand));
xmlLoader.addEventListener(Event.COMPLETE,xmlLoaded);
}
function xmlLoaded(event:Event):void
{
myList = new XML(event.target.data);
myList.ignoreWhite = true;
createTextFormat();
createIntro();
createDictee();
createResultaten();
}
include "CreateStuff.as"
include "Dictee.as"
}
}
You can see my includes at the end: createstuff.as and dictee.as.
I was working on a third include, called Sound.as, and tried to preview my file when error 5007 popped up. "5007: An ActionScript file must have at least one externally visible definition"
I removed the include Sound.as line from my Main.as, thinking that must have cause the problem for some reason. When I republished the error popped up again, and flash automatically reopened the Sound.as file. While there is no link from anywhere to it anymore.
My other files are CreateStuff.as :
function createTextFormat() : void {
titelfmt.size = 32;
titelfmt.color = 0x003399;
titelfmt.font = titelFont.fontName;
werkfmt.size = 24;
werkfmt.color = 0x000000;
werkfmt.font = werkFont.fontName;
inputfmt.size = 32;
inputfmt.color = 0x333333;
inputfmt.font = werkFont.fontName;
//inputfmt.
}
function createTextfield (fmt) : TextField {
var tf:TextField = new TextField();
tf.defaultTextFormat = fmt;
if (fmt == titelfmt) {
tf.multiline = false;
tf.autoSize = "center";
tf.selectable = false;
tf.y = 10;
tf.x = stage.stageWidth / 2;
} else if (fmt == werkfmt) {
tf.autoSize = "left";
tf.multiline = true;
} else if (fmt == inputfmt) {
tf.multiline = true;
tf.width = 300;
tf.height = 40;
tf.border = true;
tf.borderColor = 0xCCCCCC;
tf.type = TextFieldType.INPUT;
}
return (tf);
}
function createIntro() : void {
introClip.x = 0;
introClip.y = 0;
introClip.name = "introClip";
var nttf:TextField = createTextfield(titelfmt);
nttf.text = "Instructie"
introClip.addChild(nttf);
var itf:TextField = createTextfield(werkfmt);
itf.text = "Wat weet jij nog?\nLuister naar de woorden.\nSchrijf ze op.";
itf.width = 300;
itf.x = stage.stageWidth / 2 - 150;
itf.y = 120;
itf.selectable = false;
introClip.addChild(itf);
var startBtn:Beginknop = new Beginknop();
startBtn.x = stage.stageWidth / 2 - startBtn.width / 2;
startBtn.y = 300;
startBtn.addEventListener(MouseEvent.CLICK, showDictee);
introClip.addChild(startBtn);
addChild(introClip);
}
function createResultaten() : void {
}
And Dictee.as :
function createDictee () : void {
dicteeClip.x = 0;
dicteeClip.y = 0;
var nttf:TextField = createTextfield(titelfmt);
nttf.text = "Dictee"
dicteeClip.addChild(nttf);
var iptf:TextField = createTextfield(inputfmt);
iptf.x = 135;
iptf.y = 205;
dicteeClip.addChild(iptf)
var dicteeSpeaker:Luidspreker = new Luidspreker();
dicteeSpeaker.x = stage.stageWidth / 2 - dicteeSpeaker.width/2;
dicteeSpeaker.y = iptf.y - dicteeSpeaker.height - 40;
//dicteeSpeaker.addEventListener (MouseEvent.CLICK, playSnd);
dicteeSpeaker.name = dicteeSpeaker;
dicteeClip.addChild(dicteeSpeaker);
var volgendeKnop:Controleknop = new Controleknop();
volgendeKnop.x = iptf.x + iptf.width + 30;
volgendeKnop.y = iptf.y;
dicteeClip.addChild(volgendeKnop);
}
function showDictee(event:MouseEvent) : void {
addChild(dicteeClip);
removeChild(introClip);
speelDictee();
}
function speelDictee() : void {
//bepaal geluid
//afspelen geluid
//volgende knop-actie
}
I initially called the file Sound.as but thought the error might come from that Sound is a reserved word, so I changed it to Sounds.as
I'm well out of my depth here and I have no clue why the error pops up. Or the file Sound.as while it is not linked.
My flash version is Flash-CC but the tag doesn't exist yet so I couldn't specify it in the tags.
#5007 is commonly caused by
Not correctly using a package
Including an import statement any level below the package level
I'm answering this question because for some reason the error disappeared and I have no idea why. I don't want to leave it open, I'd prefer to delete it as it's of no use to anyone but I'm not sure how to do that.

Error #2025: The supplied DisplayObject must be a child of the caller - Not sure how to fix

So I get an error saying that the supplied DisplayObject must be a child of the caller. What happens is my game works first time around in that clicking the 'Play' button calls the startGame function and removes the menu so that the game is shown, but then at the end of the game when the playAgainBtn is clicked, instead of simply playing the game again / restarting the game, I get this error:
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
It specifically points to this line:
menuLayer.removeChild(mainMenu);
Here is the code:
package {
import flash.display.MovieClip;
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.display.Stage;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.events.TimerEvent;
import flash.utils.Timer;
import flash.ui.Mouse;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.text.TextFormat;
import flash.text.TextField;
import flash.text.AntiAliasType;
import flash.display.Loader;
import flash.net.URLRequest;
import flash.net.URLLoader;
import flash.system.LoaderContext;
import flash.display.Sprite;
import flash.net.Socket;
import caurina.transitions.Tweener;
import flash.text.Font;
public class Main extends MovieClip {
public static var backgroundLayer:Sprite = new Sprite;
public static var gameLayer:Sprite = new Sprite;
public static var interfaceLayer:Sprite = new Sprite;
public static var endGameLayer:Sprite = new Sprite;
public static var menuLayer:Sprite = new Sprite;
public static var gameOverLayer:Sprite = new Sprite;
public static var howToLayer:Sprite = new Sprite;
public static var scoresLayer:Sprite = new Sprite;
public static var aboutLayer:Sprite = new Sprite;
public var mainMenu:menuMain = new menuMain;
public var gameEnd:endGame = new endGame;
public var howtoPlay:howToPlay = new howToPlay;
public var gameAbout:aboutGame = new aboutGame;
public var intro:IntroSound = new IntroSound();
public var soundControl:SoundChannel = new SoundChannel();
public var gameTime:int;
public var levelDuration:int;
public var crosshair:crosshair_mc;
static var score:Number;
var enemyShipTimer:Timer;
var enemyShipTimerMed:Timer;
var enemyShipTimerSmall:Timer;
static var scoreHeader:TextField = new TextField();
static var scoreText:TextField = new TextField();
static var timeHeader:TextField = new TextField();
static var timeText:TextField = new TextField();
static var scoreFormat = new TextFormat("Arial Rounded MT Bold", 20, 0xFFFFFF);
public var gameOverscoreFormat = new TextFormat("Arial Rounded MT Bold", 32, 0xFFFFFF);
public function Main()
{
addChild(gameLayer);
addChild(backgroundLayer);
addChild(interfaceLayer);
addChild(menuLayer);
menuLayer.addChild(mainMenu);
interfaceLayer.addChild(howtoPlay);
interfaceLayer.addChild(gameEnd);
interfaceLayer.addChild(gameAbout);
soundControl = intro.play(0, 100);
addMenuListeners();
}
public function menuReturn(e:Event)
{
addChild(gameLayer);
addChild(backgroundLayer);
addChild(interfaceLayer);
addChild(menuLayer);
menuLayer.addChild(mainMenu);
interfaceLayer.addChild(howtoPlay);
interfaceLayer.addChild(gameEnd);
interfaceLayer.addChild(gameAbout);
}
public function showAbout(e:Event)
{
menuLayer.removeChild(mainMenu);
interfaceLayer.addChild(gameAbout);
}
public function startGame(e:Event)
{
removeMenuListeners();
soundControl.stop();
interfaceLayer.removeChild(howtoPlay);
interfaceLayer.removeChild(gameAbout);
interfaceLayer.removeChild(gameEnd);
menuLayer.removeChild(mainMenu);
levelDuration = 30;
gameTime = levelDuration;
var gameTimer:Timer = new Timer(1000,levelDuration);
gameTimer.addEventListener(TimerEvent.TIMER, updateTime);
gameTimer.addEventListener(TimerEvent.TIMER_COMPLETE, timeExpired)
gameTimer.start();
scoreHeader = new TextField();
scoreHeader.text = String("Score: ");
interfaceLayer.addChild(scoreHeader);
scoreHeader.x = 5;
scoreHeader.selectable = false;
scoreHeader.embedFonts = true;
scoreHeader.antiAliasType = AntiAliasType.ADVANCED;
scoreText = new TextField();
scoreText.text = String("0");
interfaceLayer.addChild(scoreText);
scoreText.x = 75;
scoreText.y = 0;
scoreText.selectable = false;
scoreText.embedFonts = true;
scoreText.antiAliasType = AntiAliasType.ADVANCED;
timeHeader = new TextField();
timeHeader.text = String("Time: ");
interfaceLayer.addChild(timeHeader);
timeHeader.x = 500;
timeHeader.y = 0;
timeHeader.selectable = false;
timeHeader.embedFonts = true;
timeHeader.antiAliasType = AntiAliasType.ADVANCED;
timeText = new TextField();
timeText.text = gameTime.toString();
interfaceLayer.addChild(timeText);
timeText.x = 558;
timeText.y = 0;
timeText.selectable = false;
timeText.embedFonts = true;
timeText.antiAliasType = AntiAliasType.ADVANCED;
scoreHeader.setTextFormat(scoreFormat);
scoreText.setTextFormat(scoreFormat);
timeHeader.setTextFormat(scoreFormat);
timeText.setTextFormat(scoreFormat);
var timeScorebg:Sprite = new Sprite();
backgroundLayer.addChild(timeScorebg);
timeScorebg.graphics.beginFill(0x333333);
timeScorebg.graphics.drawRect(0,0,600,30);
timeScorebg.graphics.endFill();
timeScorebg.y = 0;
enemyShipTimer = new Timer(2000);
enemyShipTimer.addEventListener("timer", sendEnemy);
enemyShipTimer.start();
enemyShipTimerMed = new Timer(2500);
enemyShipTimerMed.addEventListener("timer", sendEnemyMed);
enemyShipTimerMed.start();
enemyShipTimerSmall = new Timer(2750);
enemyShipTimerSmall.addEventListener("timer", sendEnemySmall);
enemyShipTimerSmall.start();
crosshair = new crosshair_mc();
gameLayer.addChild(crosshair);
crosshair.mouseEnabled = crosshair.mouseChildren = false;
Mouse.hide();
gameLayer.addEventListener(Event.ENTER_FRAME, moveCursor);
resetScore();
}
function addMenuListeners():void
{
mainMenu.playBtn.addEventListener(MouseEvent.CLICK, startGame);
mainMenu.howToPlayBtn.addEventListener(MouseEvent.CLICK, showInstructions);
mainMenu.aboutBtn.addEventListener(MouseEvent.CLICK, showAbout);
howtoPlay.backBtn.addEventListener(MouseEvent.CLICK, menuReturn);
gameEnd.playagainBtn.addEventListener(MouseEvent.CLICK, startGame);
gameAbout.backBtn.addEventListener(MouseEvent.CLICK, menuReturn);
}
function removeMenuListeners():void
{
mainMenu.playBtn.removeEventListener(MouseEvent.CLICK, startGame);
mainMenu.howToPlayBtn.removeEventListener(MouseEvent.CLICK, showInstructions);
mainMenu.aboutBtn.removeEventListener(MouseEvent.CLICK, showAbout);
howtoPlay.backBtn.removeEventListener(MouseEvent.CLICK, menuReturn);
gameEnd.playagainBtn.removeEventListener(MouseEvent.CLICK, startGame);
gameAbout.backBtn.removeEventListener(MouseEvent.CLICK, menuReturn);
}
public function showInstructions(e:Event)
{
menuLayer.removeChild(mainMenu);
interfaceLayer.addChild(howtoPlay);
}
function sendEnemy(e:Event)
{
var enemy = new EnemyShip();
gameLayer.addChild(enemy);
gameLayer.addChild(crosshair);
}
function sendEnemyMed(e:Event)
{
var enemymed = new EnemyShipMed();
gameLayer.addChild(enemymed);
gameLayer.addChild(crosshair);
}
function sendEnemySmall(e:Event)
{
var enemysmall = new EnemyShipSmall();
gameLayer.addChild(enemysmall);
gameLayer.addChild(crosshair);
}
static function updateScore(points)
{
score += points;
scoreText.text = String(score);
scoreHeader.setTextFormat(scoreFormat);
scoreText.setTextFormat(scoreFormat);
}
static function resetScore()
{
score = 0;
scoreText.text = String(score);
scoreText.setTextFormat(scoreFormat);
}
function updateTime(e:TimerEvent):void
{
gameTime--;
timeText.defaultTextFormat = scoreFormat;
timeText.text = String(gameTime);
}
function timeExpired(e:TimerEvent):void
{
var gameTimer:Timer = e.target as Timer;
gameTimer.removeEventListener(TimerEvent.TIMER, updateTime)
gameTimer.removeEventListener(TimerEvent.TIMER, timeExpired)
interfaceLayer.addChild(gameEnd);
var thisFont:Font = new myFont();
var myFormat:TextFormat = new TextFormat();
myFormat.font = thisFont.fontName;
scoreText = new TextField();
scoreText.defaultTextFormat = myFormat;
scoreText.text = String(score);
interfaceLayer.addChild(scoreText);
scoreText.x = 278;
scoreText.y = 180;
scoreText.selectable = false;
scoreText.embedFonts = true;
scoreText.antiAliasType = AntiAliasType.ADVANCED;
scoreText.setTextFormat(gameOverscoreFormat);
Mouse.show();
removeChild(gameLayer);
addMenuListeners();
}
function moveCursor(event:Event)
{
crosshair.x=mouseX;
crosshair.y=mouseY;
}
}
}
I'm not quite sure how to fix this, so any advice or solution will be welcome. I can't get it to work the way I intended without getting errors.
Thanks.
I believe the problem is calling menuLayer.removeChild(mainMenu); on the second play-through is throwing the error due to the fact that you'd already removed it once already. The quickest solution would be to do a check to ensure menuLayer contains mainMenu before you try and remove it:
if(menuLayer contains mainMenu)
menuLayer.removeChild(mainMenu);
(Note that I don't have access to the IDE right now, but I think this should work)
A more robust solution would be to call a different method when the play button is clicked from the main menu that removes mainMenu from menuLayer, then calls startGame (where as playAgain calls startGame directly).
EDIT
Ok I see what you mean. Perhaps something like this instead:
mainMenu.playBtn.addEventListener(MouseEvent.CLICK, playGame);
gameEnd.playagainBtn.addEventListener(MouseEvent.CLICK, playGameAgain);
...
public function playGame(e:Event)
{
menuLayer.removeChild(mainMenu);
startGame();
}
...
public function playGameAgain(e:Event)
{
startGame();
}
...
public function startGame()
I have no idea why your code is not working, but there is no need to fret, try:
MovieClip(menuLayer.parent).removeChild(menuLayer);
You remove mainMenu in two different locations. My guess is it is being removed once and then again moments later.
if ( mainMenu.parent == menuLayer ) {
menuLayer.removeChild( mainMenu );
}
This will verify that mainMenu is actually a child of menuLayer before removing it. You cannot remove a child from a parent that isn't actually its parent. Imagine the state taking a child away and taking custody of them from a kidnapper. It's not the prettiest comparison, but it gives the right idea.
I cannot verify this without seeing how the game over is handled, but I think potentially the problem is that you are not removing your event listeners each time the game is played. Therefore when you go back to the main menu and add them again, you now have TWO listeners for playAgainBtn.
So when you end a game and click on the playAgainBtn, startGame gets called TWICE. So the first time it removes things just fine, and the second time - there's nothing to remove. This issue will potentially exist with all of your event listeners given your current design.
If this is the case you simply need to remove your event listeners when the menu is removed.
I suggest that whenever you make the menu active you add the listeners, and then remove them whenever you hide it. Maybe have two methods, addMenuListeners and removeMenuListeners
You could create these two functions and use them where appropriate :
function addMenuListeners():void
{
mainMenu.playBtn.addEventListener(MouseEvent.CLICK, startGame);
mainMenu.howToPlayBtn.addEventListener(MouseEvent.CLICK, showInstructions);
mainMenu.aboutBtn.addEventListener(MouseEvent.CLICK, showAbout);
howtoPlay.backBtn.addEventListener(MouseEvent.CLICK, menuReturn);
gameEnd.playagainBtn.addEventListener(MouseEvent.CLICK, startGame);
gameAbout.backBtn.addEventListener(MouseEvent.CLICK, menuReturn);
}
function removeMenuListeners():void
{
mainMenu.playBtn.removeEventListener(MouseEvent.CLICK, startGame);
mainMenu.howToPlayBtn.removeEventListener(MouseEvent.CLICK, showInstructions);
mainMenu.aboutBtn.removeEventListener(MouseEvent.CLICK, showAbout);
howtoPlay.backBtn.removeEventListener(MouseEvent.CLICK, menuReturn);
gameEnd.playagainBtn.removeEventListener(MouseEvent.CLICK, startGame);
gameAbout.backBtn.removeEventListener(MouseEvent.CLICK, menuReturn);
}
If you follow the rule of always removing the event listeners when not in use, you can avoid this issue.
if( mainMenu.parent ){ mainmenu.parent.removeChild( mainMenu );} Or perhaps its already removed / not added at all?
Change this line
menuLayer.removeChild(mainMenu);
to this one..
if (mainMenu.parent != null && mainMenu.parent == menuLayer)
{
menuLayer.removeChild(mainMenu);
}
Hope it will solve.