cannot convert flash.display::Stage#2a2cdf99 to flash.display.MovieClip? - actionscript-3

So I'm creating a platform game in Actionscript 3.0, trying to call a function that spawns blocks based on an array. The code is in a 'Game' class and is directed towards a movieclip on my .fla
When it is ran I get the error:
"cannot convert flash.display::Stage#2a2cdf99 to flash.display.MovieClip."
Here's the code:
public function GameScreen(stageRef:Stage = null )
{
this.stageRef = stageRef;
btnReturn.addEventListener(MouseEvent.MOUSE_DOWN, returnMainMenu, false, 0, true);
mcMain.addEventListener(Event.ENTER_FRAME, moveChar);
this.addEventListener(Event.ENTER_FRAME, createLvl);
this.stageRef.addEventListener(KeyboardEvent.KEY_DOWN, checkKeysDown);
this.stageRef.addEventListener(KeyboardEvent.KEY_UP, checkKeysUp);
this.stageRef.addChild(blockHolder);
}
And
private function createLvl(event:Event):void
{
var lvlArray:Array = MovieClip(root)['lvlArray' +lvlCurrent];
var lvlColumns:int = Math.ceil(lvlArray.length/16);
for(var i:int = 0;i<lvlArray.length;i++){
if(lvlArray[i] == 1){
if(i/lvlColumns == int(i/lvlColumns)){
row ++;
}
var newBlock:Block = new Block();
newBlock.graphics.beginFill(0xFFFFFF);
newBlock.graphics.drawRect(0,0,50,50);
newBlock.x = (i-(row-1)*lvlColumns)*newBlock.width;
newBlock.y = (row - 1)*newBlock.height;
blockHolder.addChild(newBlock);
} else if (lvlArray[i] == 'MAIN'){
mcMain.x = (i-(row-1)*lvlColumns)*newBlock.width;
mcMain.y = (row-1)*newBlock.height;
}
}
row = 0;
}
Please help =(
Thanks!

First of all:
Turn on "permit debugging" in your publish settings. This will give you line numbers with your errors, so you can determine the exact location of your error.
Post the entire stack trace. That error by itself is not a lot to go on.
Given the error and the code you've posted, the error must be caused by your use of MovieClip(root). The root property does not always point to the main timeline in Flash, it will point to the Stage if the display object is added directly to the stage. For example:
trace(stage.addChild(new Sprite()).root) // [object Stage]
Documentation on root: http://help.adobe.com/en_US/FlashPlatform/reference/actionscript/3/flash/display/DisplayObject.html#root

Related

Possible misuse of evt.target.name. "Error #1010: A term is undefined and has no properties."

So far this program is supposed to make an child object visible when the parent object is moused over, but I can't seem to get it to work. I'm in a little over my head here. Here's my code:
var iconCompArray:Array = new Array();
stage.addEventListener(MouseEvent.MOUSE_MOVE, moveMouse);
addIcons();
function addIcons():void
{
var iconComp:IconComp = new IconComp();
iconComp.x = stage.stageWidth/4;
iconComp.y = stage.stageHeight/4;
iconComp.iconImage.gotoAndStop(2);
iconComp.iconHighlight.visible = false;
iconComp.iconTitle.text = "Program X";
iconCompArray.push(iconComp);
addChild(iconComp);
}
function moveMouse(evt:MouseEvent):void
{
for (var i:int = 0; i < iconCompArray.length; i++)
{
if (evt.target.name == iconCompArray[i])
{
iconCompArray[i].iconHighlight.visible = true;
}
}
}
A new "iconComp" is pulled from the library and added to the stage through the iconCompArray. The idea was that when you mouse over the icon, a blue box would appear around it (iconHighlight.visible). But for some reason, what I have here doesn't work. I think I may have used evt.target.name incorrectly but I can't find a solution. Here's the error message that appears in the output:
TypeError: Error #1010: A term is undefined and has no properties.
at as3_fla::MainTimeline/addIcons()
at as3_fla::MainTimeline/frame1()
From the error you get the problem seems to be in the addIcons functions. You should check that the name of all your movie clip's childs is correct. The movie clip's property mouseChildren should be set to false. Also, it would be probably better if you use MOUSE_OVER and MOUSE_OUT events instead of MOUSE_MOVE.
function addIcons():void
{
var iconComp:IconComp = new IconComp();
iconComp.x = stage.stageWidth / 4;
iconComp.y = stage.stageHeight / 4;
iconComp.iconImage.gotoAndStop(2);
iconComp.iconHighlight.visible = false;
iconComp.iconTitle.text = "Program X";
iconComp.mouseChildren = false;
iconComp.addEventListener(MouseEvent.MOUSE_OVER, onIconOver);
iconComp.addEventListener(MouseEvent.MOUSE_OUT, onIconOut);
iconCompArray.push(iconComp);
addChild(iconComp);
}
And the event listeners should look like this:
function onIconOver(evt:MouseEvent):void {
IconComp(evt.target).iconHighlight.visible = true;
}
function onIconOut(evt:MouseEvent):void {
IconComp(evt.target).iconHighlight.visible = false;
}
You can also see the line of code that gives you that error if youy publish the swf in debug mode (Ctrl+Shift+Enter).

AS3 Cannot access a property or method of null object reference, issue with gotoAndPlay

so I'm still fairly new to AS3 and I'm getting my head around the errors and stuff and I'm trying to figure out why this is not working how it should, the function still executes but it leaves an error on my console. Here is my code:
import flash.events.MouseEvent;
import flash.display.MovieClip;
stop();
var activeHitArray:Array = new Array(word_select_box);
var activeDropArray:Array = new Array(answer1_word, answer2_word, answer3_word);
var hitPositionsArray: Array = new Array();
for (var numi:int = 0; numi < activeDropArray.length; numi++) {
activeDropArray[numi].buttonMode = true;
activeDropArray[numi].addEventListener(MouseEvent.MOUSE_DOWN, mousedown1);
activeDropArray[numi].addEventListener(MouseEvent.MOUSE_UP, mouseup1);
hitPositionsArray.push({xPos:activeDropArray[numi].x, yPos:activeDropArray[numi].y});
}
function mousedown1(event:MouseEvent):void {
event.currentTarget.startDrag();
setChildIndex(MovieClip(event.currentTarget), numChildren - 1);
}
function mouseup1(event:MouseEvent):void {
var dropindex1:int = activeDropArray.indexOf(event.currentTarget);
var target:MovieClip = event.currentTarget as MovieClip;
target.stopDrag();
if(target.hitTestObject(activeDropArray[dropindex1])){
// target.x = activeHitArray[dropindex1].x;
//target.y = activeHitArray[dropindex1].y;
if(answer1_word.hitTestObject(word_select_box)){
gotoAndStop("6");
}
} else {
target.x = hitPositionsArray[dropindex1].xPos;
target.y = hitPositionsArray[dropindex1].yPos;
}
}
And the Error I'm getting through is:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at game_flv_fla::MainTimeline/frame6()
at flash.display::MovieClip/gotoAndStop()
at game_flv_fla::MainTimeline/mouseup1()
The only thing I can think of is that it is something to do with the gotoAndPlay() because when I place a trace into it's place I get no errors.
I copied your code, compiled and lauched it in Flash IDE. It works! :)
There were no errors.
But I know where the isue may lay. The addEventListeners are still on, no matter if there still are the objects they were linked to. You need to clean all active things before going to next frame:
if(target.hitTestObject(activeDropArray[dropindex1])){
if(answer1_word.hitTestObject(word_select_box)){
for (var i:uint = 0; i < activeDropArray.length; i++) {
activeDropArray[i].removeEventListener(MouseEvent.MOUSE_DOWN, mousedown1);
activeDropArray[i].removeEventListener(MouseEvent.MOUSE_UP, mouseup1);
}
gotoAndStop("6");
}
}

AS3 - Yet another TypeError: Error #1009 Cannot acces

I am creating a "Space Invaders" game in AS3. Got everything working now, but keep ketting a #1009 error and i'm looking at it for quite a time now and i just don't see the problem. Some extra eyes could help out I think!
This is what the debugger says:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at testbestandkopie_fla::MainTimeline/winGame()[testbestandkopie_fla.MainTimeline::frame1:352]
at testbestandkopie_fla::MainTimeline/enemyHitTest()[testbestandkopie_fla.MainTimeline::frame1:338]
at testbestandkopie_fla::MainTimeline/onTick()[testbestandkopie_fla.MainTimeline::frame1:117]
at flash.utils::Timer/_timerDispatch()
at flash.utils::Timer/tick()
Below I will paste the code that has to do with the error:
1: Creating the AS Linkage names:
//Sound FX-------------------------------------------------------------------------
var startFX:Sound = new startGameSound();
var laserFX:Sound = new laserSound();
var explosionFX:Sound = new explosionSound();
var musicFX:Sound = new backgroundMusic();
var loseFX:Sound = new endGameSound();
var winFX:Sound = new winGameSound();
var SfxTransform = new SoundTransform();
var myChannelMisc:SoundChannel = new SoundChannel();
var myChannelMusic:SoundChannel = new SoundChannel();
var myChannelWin:SoundChannel = new SoundChannel();
var myChannelLose:SoundChannel = new SoundChannel();
//---------------------------------------------------------------------------------
2: [Line 117] The AS line 117 is the highlighted one:
//Handlers Functions---------------------------------------------------------------
function onTick(e:TimerEvent) { //A continuous run of some functions below.
moveCharacter();
moveEnemyField();
playerCollisionDetectWall();
enemyCollisionDetectWall();
enemyCollisionDetectWallBottom();
moveLasers();
enemyHitTest(); <---- line 117
}
3: [Line 338] The function enemyHitTest(); where it starts the winGame(); function:
function enemyHitTest() {
//For each of the three enemys
for (var i:int = 0; i < enemyArray.length; i++) {
//the each of the six lasers
for (var j:int = 0; j < 6; j++) {
//don't consider lasers that aren't in play:
if (laserArray[j].y > SpelerMC.y) continue;
if (enemyArray[i].visible && enemyArray[i].hitTestObject(laserArray[j])) {
score += 10;
myChannelMisc = explosionFX.play();
SfxTransform.volume = 0.3;
myChannelMisc.soundTransform = SfxTransform;
scoreTxt.text = score.toString();
trace("Invader nummer " + i + " neergeschoten!");
enemyArray[i].visible = false;
//Now we remove the laser when hitting.
laserArray[j].x = j * 70 + 100;
laserArray[j].y = 895;
}
else if(score == 660) {
//If you reach a score of 660 (66 enemy's x 10 = 660) you win the game.
winGame(); <---- Line 338
}
}
}
}
4: [Line 352] Where the winGame(); function run's after getting 660 points at the enemyHit.
function winGame() {
winScreen.visible = true;
gameTimer.stop();
//Stop the music.
myChannelMusic.stop();
//Start the "You Win" music.
myChannelWin = winFX.play();
SfxTransform.volume = 0.02;
myChannelWin.soundTransform = SfxTransform; <---- line 352
}
So as you can see, it run's through these functions. I've already checked if something is wrong with my file in the Library, but the AS Linkage name is exactly the same as the var I defined above. Maybe a few extra eyes can see what's going wrong here, and explain me why..
Thanks in advance!
As per the livedocs :
winFX.play() method may return null if you have no sound card or if you run out of available sound channels. The maximum number of sound channels available at once is 32.
Check if either of the issues above is applicable to you....
As Mark said, the class winGameSound is the culprit here. The call winFX.play() returns a null, not a sound channel. So you can not apply a sound transform to the null object.
The only info one can currently get is that the class inherits Sound class & returns null with play() call.

Flash Error #1063 Argument count mismatch AS3

I'm trying to mix two tutorials in one game. Level 3 is previously used in a action script file but I transferred it into a normal AS3 timeline.
I get this error:
ArgumentError: Error #1063: Argument count mismatch on adventure_fla::MainTimeline/newObjects(). Expected 0, got 1.
at flash.events::EventDispatcher/flash.events:EventDispatcher::dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at flash.utils::Timer/flash.utils:Timer::tick()
This is the code... sorry if its messy.
const speed:Number = 5.0;
var nextObject:Timer;
// array of objects
var objects:Array = new Array();
function initGame():void{
player.x=200;
player.y=400;
stage.addEventListener(MouseEvent.MOUSE_MOVE,movePlayer);
Mouse.hide();
player.gotoAndStop("arrow");
setGameTimer();
newObjects();
addEventListener(Event.ENTER_FRAME, moveObject);
}
function movePlayer(e:MouseEvent):void{
player.x=mouseX;
e.updateAfterEvent();}
function setGameTimer():void {
trace("GAME TIMER STARTED");
var gameTimer:Timer = new Timer(40000, 1);
gameTimer.addEventListener(TimerEvent.TIMER_COMPLETE, endGame);
gameTimer.start()
}
function endGame(e:Event):void {
trace("Game Over");
// remove all objects
for (var i:int=objects.length-1; i>=0; i--) {
removeChild(objects[i]);
objects.splice(i, 1);
} }
function setNextObject():void {
nextObject = new Timer(1000, 1);
nextObject.addEventListener(TimerEvent.TIMER_COMPLETE, newObjects);
nextObject.start();
function newObjects():void{
//create next object
// array of good and bad objects
var badObjects:Array = ["Bad_1", "Bad_2"]
var goodObjects:Array = ["Good_1", "Good_2"]
// create random number
if (Math.random() < .5 ) {
//based of treat object length
var r:int = Math.floor(Math.random()*goodObjects.length);
// get the treat object by name and cast it as its own class in a temporary variable
var classRef:Class = getDefinitionByName(goodObjects[r]) as Class;
// now we can make a new version of the class
var newObjects:MovieClip = new classRef();
// dynamic var (because mc is an object) typestr it as good
newObjects.typestr = "good";
} else {
// for bad same as above
r = Math.floor(Math.random()*badObjects.length);
var classRef:Class = getDefinitionByName(badObjects[r]) as Class;
var newObjects:MovieClip = new classRef();
// typestr it bad
newObjects.typestr = "bad";
}
// random pos
newObjects.x = Math.random()* 500;
newObjects.scaleX = newObjects.scaleY = .4;
addChild(newObjects);
// push it to array
objects.push(newObjects);
// create another one
setNextObject();
}
function moveObject(e:Event):void {
// cycle thru objects using a for loop
for (var i:int=objects.length-1; i>=0; i--) {
//move objects down based on speed
objects[i].y += speed;
objects[i].rotation += speed;
// if objects leaves the stage
if (objects[i].y > 400) {
removeChild(objects[i]);
objects.splice(i, 1);
}
}
}
newObjects does not take any arguments, but it's used as an event listener (which requires it to take the event object).
It should probably look something like function newObjects(event:TimerEvent):void.
A function used as event listener should accept one parameter of type Event, depending on what class of events it listens to. You are listening to an event of a TimerEvent class, so yes, declare parameter as TimerEvent. To add a function that does not need parameters passed to it as an event listener, use default value construction like this:
function newObjects(event:TimerEvent=null):void {...}
The "=null" addition will allow you to pass no parameters to your function, and the declared parameter will allow you to not get exceptions when it will be called as an event handler.

Why can't my class see an array on the timeline?

I have a class that controls an enemy. From within that class, it checks for collisions with an array on the main timeline. I've done it this way before and it works fine, so I have no idea what I've done wrong this time. It keeps giving me an
ReferenceError: Error #1069: Property
bulletArray not found on
flash.display.Stage and there is no
default value.
error from within the enemy class.
Here's my code (shortened to remove the unimportant parts):
On timeline:
var bulletArray:Array = new Array();
function shoot(e:TimerEvent)
{
var bullet:MovieClip = new Bullet(player.rotation);
bullet.x = player.x;
bullet.y = player.y;
bulletArray.push(bullet);
stage.addChild(bullet);
}
In class:
private var thisParent:*;
thisParent=event.currentTarget.parent;
private function updateBeingShot()
{
for (var i=0; i<thisParent.bulletArray.length; i++) {
if (this.hitTestObject(thisParent.bulletArray[i]) && thisParent.bulletArray[i] != null) {
health--;
thisParent.bulletArray[i].removeEventListener(Event.ENTER_FRAME, thisParent.bulletArray[i].enterFrameHandler);
thisParent.removeChild(thisParent.bulletArray[i]);
thisParent.bulletArray.splice(i,1);
}
}
Any help would be greatly appreciated! Thanks.
My guess is that event.currentTarget is the instance where you declared the bulletArray variable. Using event.currentTarget.parent will refer to stage outside your scope. I donĀ“t know how you declare the listeners. Try using event.target instead of event.currentTarget and see if you get the same error.
My advice is that you put all your code in a class.
If you are going to do it this way you need to pass in a reference to the timeline.
private var _timeline:Object;
// constructor
public function YourClass(timeline:Object) {
_timeline = timeline;
}
private function updateBeginShot() {
// ..
trace(_timeline.bulletArray); // outputs [array contents]
// ..
}