How to solve the legend error#2025 in AS3? - actionscript-3

thanks for seeing my post.
Go to the problem:
i have 2 Movieclip named "thebugboss" and "spiderboss"in the library, they all linkage to their Class. I drag it to stage and name it "bugboss" and "spiderbossit". I push them to the boss array too. When i kill the boss, it have some output message 2025 but my code still work.
But i worry because my code is not cleanly now, and i think it may be error everywhen. This is my code:
var currentboss:Number=0;
stage.addEventListener(Event.ENTER_FRAME, defeatboss);
function defeatboss(e:Event):void
{
for (var kb:int=0; kb<bossArray.length; kb++)
{
var bosshientai=bossArray[kb];
if (bosshientai.hp<=0)
{
if (currentboss==0)
{
addReward(bosshientai.x ,bosshientai.y ,3);
addReward(bosshientai.x-10 ,bosshientai.y ,3);
addReward(bosshientai.x-20 ,bosshientai.y ,3);
addReward(bosshientai.x-30 ,bosshientai.y ,3);
removeChild(bosshientai);
bossArray.splice(kb, 1);
stage.removeEventListener(Event.ENTER_FRAME, bugbossLoop);
bugTimer.stop();
bugTimer2.stop();
bugTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, buggo);
bugTimer2.removeEventListener(TimerEvent.TIMER_COMPLETE, bugstop);
currentboss++;
}
if (currentboss==1)
{
addReward(bosshientai.x ,bosshientai.y ,3);
addReward(bosshientai.x-10 ,bosshientai.y ,3);
addReward(bosshientai.x-20 ,bosshientai.y ,3);
addReward(bosshientai.x-30 ,bosshientai.y ,3);
removeChild(bosshientai);
bossArray.splice(kb, 1);
stage.removeEventListener(Event.ENTER_FRAME, spiderLoop);
spiTimer.stop();
spiTimer2.stop();
spiTimer.removeEventListener(TimerEvent.TIMER_COMPLETE, spigo);
spiTimer2.removeEventListener(TimerEvent.TIMER_COMPLETE, spistop);
currentboss++;
}
}
}
}
You just need to care about the "removeChild". it error like this:
ArgumentError: Error #2025: The supplied DisplayObject must be a child of the caller.
at flash.display::DisplayObjectContainer/removeChild()
at Holyshitman_fla::MainTimeline/defeatboss()
How to solve this problem plz, although my code still work. If that problem too difficult, just tell me is it affect to my game.
Thanks you so much. And sorry too, because my English is not good.

"I drag thebugboss to the stage, then I name it bugboss. I use this : bossArray.push(bugboss);. And the bosshientai is like this"
Don't drag the boss to stage. Add it by code. Your code like bugboss.x appears to work because it is talking to the stage object with instance name bugboss.
removeChild expects a variable not a dragged item.
"The supplied DisplayObject must be a child of the caller" The error happens because your shown code did not add it (you dragged), so now code cannot remove something that itself did not add.
Assuming linkage name is thebugboss:
1) Create new instance (ie: a new copy) of the thebugboss class:
public var bugboss : thebugboss = new thebugboss();
2) Add to stage and also add to array.
stage.AddChild(bugboss);
bossArray.push(bugboss);
3) Try your other code as usual (test removeChild() )

Related

External ActionScript Only Executed When Testing Single Scene

New to AS 3.0 and I seem to have an issue where an external AS file is run when I test an individual scene in Flash Pro but not when I test the entire movie or when I test from Flash Builder. Anyone know what the problem might be?
Here's the code from the AS file:
package {
import flash.display.MovieClip;
public class Level1 extends MovieClip {
public var myplayer:MyPlayer;
public function Level1() {
super();
myplayer.x = 516;
myplayer.y = 371;
if (myplayer.x == 516)
{
trace("player x is 516");
}
else if (myplayer.y == 371)
{
trace("player y is 371");
}
}
}
}
Any ideas?
EDIT
I think I figured out the problem. The swf contained two scenes, and the external AS file started running at the start of Scene 1, but the myPlayer movie clip was not instantiated until Scene2, which, I think was causing the problem I was having, in addition to giving a 1009 null object error.
So I simply deleted the first scene, and now everything works fine. Maybe I will put that first scene in a separate SWF? Or, is there some way to delay a script's execution until a certain scene?
Your problem:
When the constructor of your doucment class runs, myPlayer doesn't yet exist so it throws a 1009 runtime error and exits the constructor at the first reference to myPlayer.
Solutions:
Put all the myPlayer code on the first frame of the MyPlayer timeline. OR use your current document class as the class file for MyPlayer (instead of documentClass). Change all references to myPlayer to this.
Listen for frame changes and check until myPlayer is populated, then run your code.
this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
function enterFrameHandler(e):void {
if(myPlayer){
//run the myPlayer code
this.removeEventListener(Event.ENTER_FRAME,enterFrameHandler);
}
}
If your frame rate is 24fps, this code though will run 24 times every second (until it finds myPlayer), so it's not the most performant way to go.
Use events. Add an event to the first frame of myPlayer (or to a class file for MyPLayer) that tells the document class that it exists now.
stage.dispatchEvent(new Event("myPlayerReady"));
Then listen for that event on the document class:
stage.addEventListener("myPlayerReady",playerReadyHandler);
playerReadyHandler(e:Event):void {
//your player code
var myPlayer = MyPlayer(e.target); //you can even get the reference from the event object
}
Thanks for your constructive, helpful responses, LDMS. I thought I had found a solution when I hadn't. Your advice worked. What I did was add the following code to the timeline of MyPlayer
this.x = 516;
this.y = 371;
if (this.x == 516)
{
trace("player x is 516");
}
if (this.y == 371)
{
trace("player y is 371");
}
and I removed the code from the document class. Everything seems to be working fine now. Thanks again for your help!

MovieClip(root) line seems to be crashing my game

Inside my classes, I invoke this function
MovieClip(root).increaseScore();
which handles the score in the main .as file.
It all works fine during the execution of the level. However when the level is finished and the screen goes to another frame, the game crashes and gives me this error
TypeError: Error #1009: Cannot access a property or method of a null
object reference.
on the line above.
How do I fix this?
Thanks
edit:
This is were I tell it to addScore, this is in the GameController.as file
private function removeBubble(bubble, addScore:Boolean)
{
var delay:Timer = new Timer(200, 1);
delay.addEventListener(TimerEvent.TIMER_COMPLETE, function(e:TimerEvent)
{
if(bubble.parent==mcGameStage)
{
var j:int = bubbleList.indexOf(bubble);
bubbleList.splice(j,1);
if(addScore) bubble.addScore();
mcGameUI.txtScorePlayer.text = String(playerScore);
mcGameStage.removeChild(bubble);
}
e.currentTarget.removeEventListener(e.type, arguments.callee);
checkWin();
});
delay.start();
}
here is the checkWin function:
private function checkWin()
{
if (playerBlue + playerRed + playerYellow + playerOrange + playerPurple + playerGreen == 0)
{
gameWin();
}
}
private function gameWin()
{
while (bubbleList.numChildren > 0)
{
bubbleList.removeChildAt(0);
}
mcGameUI.btnMixBlue.removeEventListener(MouseEvent.CLICK, mixBlue);
mcGameUI.btnMixRed.removeEventListener(MouseEvent.CLICK, mixRed);
mcGameUI.btnMixYellow.removeEventListener(MouseEvent.CLICK, mixYellow);
mcGameUI.btnNeedle.removeEventListener(MouseEvent.CLICK, activateNeedle);
mcGameStage.removeEventListener(Event.ENTER_FRAME,update);
mcGameStage.removeEventListener(MouseEvent.CLICK, checkToHit);
removeEventListener(Event.ADDED_TO_STAGE, gameAddedToStage );
stage.removeEventListener(KeyboardEvent.KEY_DOWN,keyDownHandler);
stage.removeEventListener(KeyboardEvent.KEY_UP,keyUpHandler);
if (mouseCursor != null)
{
mouseCursor.removeEventListener(Event.ENTER_FRAME,followMouse);
mouseCursor = null;
}
gotoAndPlay("level1win");
}
And inside my classes,
public function addScore()
{
root["increaseScore"]();
}
This is what increaseScore does
public function increaseScore()
{
playerScore += 1000;
}
So where is the null object? D:
Also I am very inexperienced using the debugger so I apologize if this could be easily solved with that. I tried it and couldn't figure it out before coming here.
What is OPP method?
What is FrameScript?
Also, the class is MovieClip
thanks :)
Fixing this is done with the help of the debugger!
The error is telling you that something is null and you're trying to access it. That's not good, so let's think what could be null?
1) Your movie clip instance might be null.
2) increaseScore() method of your movie clip instance might try to access something that is null
You didn't post any code that I could analyse at the time I'm writing this answer, so I can't say for sure.
Some possible problems:
Your class is not called MovieClip, but you're just trying to cast your root object to a MovieClip. Thing is, MovieClip's don't have a increaseScore() method. You should instead call the increaseScore() method with
root["increaseScore"]();
This will call the method of your root timeline, but since we are using weak-typing, you might have problems with debugging it later. But I guess that's the price you pay when writing all the code in a frame instead of using OPP approach.
The true reason here is said in the error: Cannot access a property or method of a null object reference.
What this means is that MovieClip(root) is null (it doesn't even bother to check if the function is present). The reasons for this might be three:
Your document class is not MovieClip (could be Sprite).
The class you use root in, is not DisplayObject. The property is part of the DislpayObject class and so if you use it on other kind of classes that does not extend it, it won't work.
You are using this piece of code before you have added the instance to the stage (most probable cause). The root property represents the top-most display object in the tree. If you haven't added the child to the tree, it has no roots :) Check out parent - the error should be the same.

Why aren't properties reset when object is re-cast as original type?

I tried to ask this question here, but couldnot get a satisfactory answer. (Why should compiler allow super-class of a parameter in a function)
Trying to ask again.
Why casting, doesnot loose the member functions, when done on classes ? In the following, i expected, that after casting to Sprite, the class should loose all it's information regarding the current frame. But it retains the information, as if casting is just a "show-off", not "actually done" internally ?
import flash.display.MovieClip;
import flash.display.Sprite;
var mc:MovieClip
mc.gotoAndStop(2);
trace(mc.currentFrame); // output 2 --> that's ok
var sprite:Sprite = Sprite(mc)
trace( MovieClip(sprite).currentFrame);//output 2, value not lost, which is questionable
Output:
2
2
I know, the answer can be, it's how Adobe did it. But what's the logic ? Ideal logic should be that, after casting, and recasting, all the values must be restored to default. ( '0' in this case )
V.
Cast will not clear the member fields. Casting show what others can access
from this object but not change the object.
In flash objects are passed by reference. Imagine you have a object in memory ( mc in your case ). When you create sprite by casting the mc you pass the reference ( memory address ) to sprite var. At this point mc and sprite points to same address in memory. When you cast sprite to MovieClip you pass same address from mc. And this address is address for MovieClip mc at this point currentFrame will access the value of mc. Casting is not like copy constructors
Edit.
By using this link I create simple code that proove my words:
var memoryHash:String;
var mc: MovieClip = new MovieClip();
var s: Sprite = Sprite( mc );
try
{
FakeClass(mc);
}
catch (e:Error)
{
memoryHash = String(e).replace(/.*([#|\$].*?) to .*$/gi, '$1');
}
trace( memoryHash );
try
{
FakeClass(s);
}
catch (e:Error)
{
memoryHash = String(e).replace(/.*([#|\$].*?) to .*$/gi, '$1');
}
trace( memoryHash );
And the Fake class:
package {
public class FakeClass {
public function FakeClass() {}
}
}
The output will show the memory address of mc and s. As you can see thay are equal. In my mashine the output is
#35ed041
#35ed041
I'm not sure what you're trying to do here, but things like MovieClip(sprite).currentFrame are obviously going to lead to weird results. Because you're casting your sprite as a movieclip, it will have a currentframe. Try doing currentFrame on a sprite and see what happens.

"The supplied DisplayObject must be a child of the caller" error

Been struggling with this in multiple projects. I try to spawn enemies in a Flash game and perform cleanup by removing the out of bounds enemies.
Here's how:
enemyArray contains references to the spawned enemy objects.
enemyLayer is the movieclip that contains the spawned enemies.
public function spawnEnemy():void
{
var mc:MovieClip = new Enemy();
enemyLayer.addChild(mc);
enemyArray.push(mc);
for (var i:int = 0; i<=enemyArray.length-1;i++)
{
enemyArray[i].z-=30; //Moves the enemies
if (enemyArray[i].z <=-400) //performs cleanup
{
enemyLayer.removeChild(enemyArray[i]);
}
}
}
But I get this error
The supplied DisplayObject must be a child of the caller
What am I doing wrong?
I've tried: removeChild(enemyArray[i]) as well, removing the enemyLayer reference, but get the same error.
Make sure you remove your items from the array after you removed them from the display list
if (enemyArray[i].z <=-400) //performs cleanup
{
enemyLayer.removeChild(enemyArray[i]);
enemyArray.splice(i, 1);//removing enemyArray[i] from the manager array
}
That wouldn't resolve his problem Engineer, because if 'somehow' movieclip to be removed exists but in different container, it would not be removed.
I'd suggest doing this:
enemyArray[i].parent.removeChild(enemyArray[i]);
Although this is not the best way to do this and is quite bad code it helps me everytime I have a problem like this.
EDIT: Problem is that you're not modifiying your array object. You just add enemies you never remove them. That's why you get that error. Array contains an enemy which is already removed from the display list.

Removing an event listener as well as a sprite at the same time AS3

I’m having trouble removing the an event listener as well as the sprite at the same time. I currently get an error:
TypeError: Error #1009: Cannot access
a property or method of a null object
reference.
And if I comment out removeChild, I have no error but, obviously, the sprite remains on the screen. Any ideas how I can rid myself of that error?
//Bullet extends Sprite Class
bullet:Bullet = new Bullet();
mc.addChild(bullet);
bullet.addEventListener(Event.ENTER_FRAME, shoot);
function shoot(e:Event):void {
var shot:Bullet = e.currentTarget as Bullet;
//check shot is outside the frame
if (shot.x < 0 - shot.width || shot.x > stage.stageWidth || shot.y > 525)
{
//trying to remove the thing and it's listener
e.currentTarget.removeEventListener(e.type,arguments.callee);
e.currentTarget.parent.removeChild(shot);
}
else
{
shot.setInMotion();
}
}
Apart from a missing var before bullet:Bullet, I don't see anything wrong in the example code. You should set a breakpoint right after:
var shot:Bullet = e.currentTarget as Bullet;
And figure out why shot is null. I suspect there is something amiss in a piece of code outside of the little bit you're providing as the example. If the code is working with only the removeChild line commented out, it tells me that e.currentTarget is not null, but that it's also not a reference to an instance of type Bullet (i.e. the "as" cast is returning null).
Try reversing these lines
Maybe the reference to e.currentTarget is getting lost through the object references
e.currentTarget.removeEventListener(e.type,arguments.callee);
e.currentTarget.parent.removeChild(shot);
to
e.currentTarget.parent.removeChild(shot);
e.currentTarget.removeEventListener(e.type,arguments.callee);