Error 1119 in Actionscript 3 (as3) Access of possibly undefined property text through a reference with static type money_txt - actionscript-3

This is in the main class
package {
import flash.display.MovieClip;
import flash.events.MouseEvent;
import flash.display.Sprite;
import flash.events.Event;
public class main extends MovieClip {
public var scene = 0;
public var _money = 0;
public var gain = 1;
public var clicks = 0;
public function main() {
addEventListener(Event.ENTER_FRAME, loop);
mainbtn.addEventListener(MouseEvent.CLICK, handler);
playbtn.addEventListener(MouseEvent.CLICK, playHandler);
}
var mainbtn:button = new button();
var playbtn:playbutton = new playbutton();
var playtxt:playtext = new playtext();
var cash:money_txt = new money_txt();
var scene0:MovieClip = new MovieClip();
var scene1:MovieClip = new MovieClip();
public function loop(e:Event):void {
if(scene == 0) {
addChild(scene0)
scene0.addChild(playbtn);
playbtn.x = 300;
playbtn.y = 200;
scene0.addChild(playtxt);
playtxt.x = 300;
playtxt.y = 100;
} else {
scene0.removeChild(playbtn);
scene0.removeChild(playtxt);
}
if(scene == 1) {
addChild(scene1);
scene1.addChild(mainbtn);
mainbtn.x = 300;
mainbtn.y = 200;
scene1.addChild(cash);
cash.text = 'Money: ' + _money.toString();
} else {
scene1.removeChild(mainbtn);
}
}
public function playclickHandler(e:MovieClip) {
scene = 1;
}
public function handler(e:MouseEvent):void {
_money += gain;
clicks++;
trace('yep');
}
public function playHandler(e:MouseEvent):void {
scene = 1;
}
}
}
And This is where the error would be
C:\Users\Slime\Desktop\Art-ish\game\main.as, Line 47, Column 10 1119: Access of possibly undefined property text through a reference with static type money_txt.
Thanks for helping if you can!

these should be defined as public
public var mainbtn:button = new button();
public var playbtn:playbutton = new playbutton();
public var playtxt:playtext = new playtext();
public var cash:money_txt = new money_txt();
public var scene0:MovieClip = new MovieClip();
public var scene1:MovieClip = new MovieClip();
also it is hard to tell if money_txt, playtext, playbutton and button are classes or MovieClip instances. Convention dictates that Classes should start with a capital letter and instances with lower.
update
The issue is that if button and playbutton are buttons and playtext and money_txt are MovieClips, you should instantiate them as such.
for example if you have
public var mainbtn:button = new button();
but there is no class with name of button, mainbtn will be null. What you may need to do is
public var mainbtn:Button;
public var cash:MovieClip;
and as a part of your main or some other function, assign the instances
mainbtn = this['button'];
cash = this['money_txt'];
you can check if this worked by checking trace(cash);, which will return null if the assignment did not work.
I should stress again though, it is hard to to know what exactly is going wrong without knowing what your setup is. I'm assuming money_txt and the other classes you are defining are not actually classes with their own linkage IDs, but buttons and movieclips inside the MovieClip or stage you are putting this code in.

Related

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.

Actionscript 3.0 I'm trying to figure out how to access properties of event target

I'm trying to figure out how to reference the class of a target. Here is some of the code:
xmlDoc = new XML(xmlLoader.data);
//trace(xmlDoc.Video[1].Desc);
for (var i:int = 0; i < xmlDoc.Video.length(); i++)
{
xmlObj = new FilmVideo(xmlDoc.Video[i].Name, xmlDoc.Video[i].title, xmlDoc.Video[i].Thumb, xmlDoc.Video[i].URL, xmlDoc.Video[i].APILoader);
XMLItem[i] = xmlObj;
//trace(XMLItem);
MovieClip(root).main_mc.thumb_mc.addChild(XMLItem[i]);
if (i <= 0) {
XMLItem[i].x = 20;
XMLItem[i].y = 0;
} else if (i > 0){
XMLItem[i].x = XMLItem[i-1].x + XMLItem[i-1].width + 120;
XMLItem[i].y = 0;
}
XMLItem[i].addEventListener(MouseEvent.CLICK, makeThumbClick);
XMLItem[i].addEventListener(MouseEvent.MOUSE_OVER, makeThumbRollOver);
XMLItem[i].addEventListener(MouseEvent.ROLL_OUT, makeThumbRollOut);
}
}
function makeThumbClick(e:MouseEvent)
{
//var myFilmVideo:FilmVideo = FilmVideo(e.target);
MovieClip(root).main_mc.play();
trace(FilmVideo(e.target));
/MovieClip(root).main_mc.theater_mc.videoLoader(FilmVideo(e.target)._APILoad, FilmVideo(e.target)._videoURL);
}
The XMLItem is an array that's storing a class object I custom made (the class name is FilmVideo based off movieclip). The _thumbToMC is a method within my custom class that returns a movieclip. The class has info stored within its properties I would like to pass through a function called in the makeThumbClick function. However, I have no idea how. e.target reference the _thumbToMC movieclip rather than the class. I do I reference the class? Thank you in advance :)
Here is the class:
package filmvideo
{
import flash.display.Loader;
import flash.display.MovieClip;
import flash.display.Sprite;
import flash.net.URLRequest;
public class FilmVideo extends MovieClip
{
public var _nameXML:String = "";
public var _title:String = "";
public var _thumbURL:URLRequest;
public var _videoURL:URLRequest;
public var _APILoad:String = "";
public var loader:Loader = new Loader();
public function FilmVideo(name:String, title:String, thumbURL:String, videoURL:String, APILoad:String)
{
_nameXML = name;
_title = title;
_thumbURL = new URLRequest(thumbURL);
_videoURL = new URLRequest(videoURL);
_APILoad = APILoad;
//trace(_name);
//trace(_title);
//trace(thumbURL);
//trace(videoURL);
//trace(_APILoad);
this.addChild(loader);
loader.load(_thumbURL);
}
}
}
You could simplify your class to:
package filmvideo
{
import flash.display.Loader;
import flash.display.MovieClip;
import flash.net.URLRequest;
public class FilmVideo extends MovieClip
{
public var _nameXML:String = "";
public var _title:String = "";
public var _thumbURL:URLRequest;
public var _videoURL:URLRequest;
public var _APILoad:String = "";
public var loader:Loader = new Loader();
public function FilmVideo(name:String, title:String, thumbURL:String, videoURL:String, APILoad:String)
{
_nameXML = name;
_title = title;
_thumbURL = new URLRequest(thumbURL);
_videoURL = new URLRequest(videoURL);
_APILoad = APILoad;
//trace(_name);
//trace(_title);
//trace(thumbURL);
//trace(videoURL);
//trace(_APILoad);
this.addChild(loader);
loader.load(_thumbURL);
}
}
}
Then you can use FilmVideo as a MovieClip (since it extends the MovieClip class).
And use 'currentTarget' instead of 'target', because it always points to the listened object, while 'target' points to the object which fired the event. more info here
xmlDoc = new XML(xmlLoader.data);
//trace(xmlDoc.Video[1].Desc);
for (var i:int = 0; i < xmlDoc.Video.length(); i++)
{
xmlObj = new FilmVideo(xmlDoc.Video[i].Name, xmlDoc.Video[i].title, xmlDoc.Video[i].Thumb, xmlDoc.Video[i].URL, xmlDoc.Video[i].APILoader);
XMLItem[i] = xmlObj;
//trace(XMLItem);
Object(root).main_mc.thumb_mc.addChild(XMLItem[i]);
if (i <= 0) {
XMLItem[i].x = 20;
XMLItem[i].y = 0;
} else if (i > 0){
XMLItem[i].x = XMLItem[i-1].x + XMLItem[i-1].width + 120;
trace(XMLItem[i].width);
XMLItem[i].y = 0;
}
XMLItem[i].addEventListener(MouseEvent.CLICK, makeThumbClick);
XMLItem[i].addEventListener(MouseEvent.MOUSE_OVER, makeThumbRollOver);
XMLItem[i].addEventListener(MouseEvent.ROLL_OUT, makeThumbRollOut);
}
function makeThumbClick(e:MouseEvent)
{
//var myFilmVideo:FilmVideo = FilmVideo(e.target);
MovieClip(root).main_mc.play();
trace(myFilmVideo._APILoad);
MovieClip(root).main_mc.theater_mc.videoLoader(FilmVideo(e.currentTarget)._APILoad, FilmVideo(e.currentTarget)._videoURL);
}
If you don't want to do this way
Add a reference (inside the class) to the _thumbToMC back to it's FilmVideo object.
_thumbMC._filmVideo = this;
Then:
function makeThumbClick(e:MouseEvent)
{
//var myFilmVideo:FilmVideo = FilmVideo(e.target);
MovieClip(root).main_mc.play();
MovieClip(root).main_mc.theater_mc.videoLoader(MovieClip(e.currentTarget)._filmVideo._APILoad, MovieClip(e.currentTarget)._filmVideo._videoURL);
}
I'm not 100% sure I understand the question, but assuming you want to retrieve the properties of the FilmVideo instance (which it appears the user is clicking on) then maybe this is what you are looking for;
function makeThumbClick(e:MouseEvent){
var myFilmVideo:FilmVideo = FilmVideo(e.target);
// access properties of _thumbToMC
myFilmVideo.randomproperty = 123;
}

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.

Using variable from another class as3

i separated one big file into multiple file to have it cleaned and i got a problem now.
I have my main.as, character.as, camera.as.
What i'm trying to do is access a variable from another class which i set later on that class. Ill show you what i mean.
From my main.as im loading each class and add them as child so it get displayed on screen.
public function buildGame()
{
var loadMap:Sprite = new nf_MapBuilder();
var xChar:Sprite = new nf_Character();
var xCam:Sprite = new nf_Camera();
var UserControl:nf_UserControl = new nf_UserControl();
addChild(loadMap);
addChild(xChar);
addChild(xCam);
addChild(UserControl);
}
Everything show on screen like it needed. Then it goes to my character.as:
package as3
{
import flash.display.Sprite;
import flash.events.Event;
public class nf_Character extends Sprite
{
public var character_pos:Array = new Array();
public var character_is_moving:Boolean = false;
public var character_x_dir:int = 0;
public var character_y_dir:int = 0;
public var character:hero = new hero();
public function nf_Character()
{
addEventListener(Event.ADDED_TO_STAGE,xCharLoad);
}
public function xCharLoad(e:Event)
{
character_pos = [2,2];
character.x=64*(character_pos[1]);
character.y=64*(character_pos[0]);
addChild(character);
}
}
}
There is the problem. I need to use those variable i set there in my character.as to use it in my camera.as:
package as3
{
import flash.display.Sprite;
import flash.events.Event;
import flash.geom.Rectangle;
import flash.display.StageScaleMode;
import as3.nf_Character;
public class nf_Camera extends Sprite
{
private var xChar:nf_Character = new nf_Character();
//Camera variables
var stageW2:Number;
var stageH2:Number;
var view:Rectangle;
public function nf_Camera()
{
addEventListener(Event.ADDED_TO_STAGE,xCamGo);
}
public function xCamGo(e:Event):void
{
trace("Camera pos - " + xChar.x + " " + xChar.character.y);
view = new Rectangle(0,0,stage.stageWidth,stage.stageHeight)
stageW2 = stage.stageWidth / 2 - 32;
stageH2 = stage.stageHeight / 2 - 32;
addEventListener(Event.ENTER_FRAME,CamView);
}
public function CamView(e:Event):void
{
view.x = xChar.character.x - stageW2;
view.y = xChar.character.y - stageH2;
scrollRect = view;
}
}
}
When it was all in one big file it was ok i just had to set the variable in the class and acessing it trough every function but now im kinda confused. Anyone see how i could do this?
In short, I think you should subscribe to an event from your character in your main class which is fired whenever the character moves. In the handler for that event you could call a method on the camera to set it's position according to the current position of the character.
main.as
private var xChar:Sprite = new nf_Character();
private var xCam:Sprite = new nf_Camera();
public function buildGame()
{
var loadMap:Sprite = new nf_MapBuilder();
var UserControl:nf_UserControl = new nf_UserControl();
// listen for when the character has moved
xChar.addEventListener(MoveEvent.MOVED, characterMovedHandler);
addChild(loadMap);
addChild(xChar);
addChild(xCam);
addChild(UserControl);
}
private function characterMovedHandler(event:MoveEvent):void
{
xCam.setPosition(xChar.x, xChar.y);
}
nf_Character.as
public class nf_Character extends Sprite
{
public var character_pos:Array = new Array();
public var character_is_moving:Boolean = false;
public var character_x_dir:int = 0;
public var character_y_dir:int = 0;
public var character:hero = new hero();
public function nf_Character()
{
addEventListener(Event.ADDED_TO_STAGE,xCharLoad);
}
public function xCharLoad(e:Event)
{
character_pos = [2,2];
character.x=64*(character_pos[1]);
character.y=64*(character_pos[0]);
addChild(character);
}
public function xCharMoved()
{
// Dispatch a custom event when the character moves
dispatchEvent(new MovedEvent(MovedEvent.MOVED));
}
}
nf_Camera.as
public class nf_Camera extends Sprite
{
private var xChar:nf_Character = new nf_Character();
//Camera variables
var stageW2:Number;
var stageH2:Number;
var view:Rectangle;
public function nf_Camera()
{
addEventListener(Event.ADDED_TO_STAGE,xCamGo);
}
public function xCamGo(e:Event):void
{
trace("Camera pos - " + xChar.x + " " + xChar.character.y);
view = new Rectangle(0,0,stage.stageWidth,stage.stageHeight)
stageW2 = stage.stageWidth / 2 - 32;
stageH2 = stage.stageHeight / 2 - 32;
// Probably only need one enterframe either in your character class or main
//addEventListener(Event.ENTER_FRAME,CamView);
}
public function setPosition(x:Number, y:Number):void
{
view.x = xChar.character.x - stageW2;
view.y = xChar.character.y - stageH2;
scrollRect = view;
}
}
Out of interest, how are you moving the character?
You can pass your character class instance to your camera class instance as an argument of the constructor. You will then have a reference to the character inside the camera class and you can access it's variables
// Inside buildGame() in main.
var xChar:nf_Character = new nf_Character();
var xCam:nf_Camera = new nf_Camera(xChar);
// Inside nf_Camera
public function nf_Camera(char:nf_Character) {
xChar = char;
}

Use MouseEvent for getting Object`s public variables

I have a simple problem which is not easy at the moment. this is a text field class which add a text field to a movieclip (passed from root class) and also save(buffer) some data (like xml file name) in it`s public variables:
package src {
import flash.display.Shape;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.MouseEvent;
import flash.text.TextField;
import flash.text.TextFieldAutoSize;
import flash.text.TextFormat;
public class menuitem00 extends Shape {
public var activateFlag:Boolean = false;
public var name00:String = "";
public var xml00:String = "";
public var txt00:TextField = new TextField();
private var OM:MovieClip;
private var id00:Number = 0;
public function menuitem00(n:int ,OE:MovieClip ,xmlf:String):void {
trace (" Text Field Object with buffer ");
OM = OE; id00 = n; xml00 = xmlf;
}
public function init():void{
// textfield
txt00.selectable = false;
txt00.autoSize = TextFieldAutoSize.LEFT;
txt00.defaultTextFormat = new TextFormat("Impact", 36,0x66AAFF);
txt00.text = name00;
txt00.border = true;
txt00.borderColor = 0x00FF00;
txt00.sharpness = 100;
txt00.x = 0;
txt00.y = (id00 * txt00.height) + 1;
txt00.z = 0;
OM.addChild(txt00);
}
}
}
.. now I use a for loop to add instance of that class to a movie clip on stage:
for (var i:int = 0; i<Bunker[0]["trans0size"]; i++) {
menuData[i] = new menuitem00(i, menu_mc, Bunker[0]["transfile0" + i]);// pass i , a movieclip named menu_mc and an xml file name
menuData[i].name00 = Bunker[0]["transtitle0" + i]; // pass text
menuData[i].activateFlag = true; // set actveFlag to true
menuData[i].init(); // run init() inside the instance. it adds textfield to the menu_mc and also set name00 as Text for the textField
}
also I add mouse event for clicking on the stage,
stage.addEventListener(MouseEvent.CLICK, clk, false, 0, true);
public function clk(evt:MouseEvent):void{ //// mouse
trace (" Name: " + evt.target.text);
//trace (evt.target.xml00);
}
HERE IS MY PROBLEM --> I want to get "xml00" var from that instance on the stage by mouse click but, trace (evt.target.xml00); is not working .. also trace (evt.target.name00); is not working. I can get everything like .alpha or .text from txt00 but not other variables in my object. Any idea ?
don't add the click-listener to the STAGE but to you object.
menuData[i].addEventListener(MouseEvent.CLICK, clk, ...);
and add the following line to your menuitem00 class:
this.mouseChildren = false;
so you can be sure that the evt.target is an object of this class and not a child (like the textfield or something else).
edit
if you want to keep the stage-listener, try this:
stage.addEventListener(MouseEvent.CLICK, clk, ...);
private function clk (evt:MouseEvent):void
{
if (evt.currentTarget is menuitem00)
{
var item:menuitem00 = evt.currentTarget as menuitem00;
trace(item.xml00); // or any other public variable
}
}
but still add the mouseChildren = false; to your class.
edit2
make the menuitem00 class a sprite (and rename it pls):
public class MenuItem extends Sprite {
private var _activateFlag:Boolean;
private var _xml:String;
private var _txt:TextField;
private var _id:Number;
public function MenuItem (n:int, xmlf:String) {
trace (" Text Field Object with buffer ");
_id = n;
_xml = xmlf;
_activeFlag = true;
this.mouseChildren = false;
// create txt
_txt = new TextField();
// do the formating here ...
this.addChild(_txt);
}
public function getXml():String {
return _xml;
}
}
in the for loop you would do sth like this:
for (var i:int = 0; i<Bunker[0]["trans0size"]; i++) {
var item:MenuItem = new MenuItem(i, Bunker[0]["transfile0" + i]);
item.addEventListener(MouseEvent.CLICK, clk, false, 0, true);
menu_mc.addChild(item);
menuData[i] = item;
}
private function clk (evt:MouseEvent):void {
var item:MenuItem = evt.target as MenuItem;
if (item != null) {
trace(item.getXml()); // use a getter and don't access the variable directly
}
}
and pls re-read your actionscript (or programming) books, you're doing some really bad things i your code that you shouldn't.