AS3:Calling a switch case from another class does't work - actionscript-3

i am making a game in flash and the problem that i am having is with two classes a class called Menu for the welcome screen which has a startgame button and the engine class which runs everything when i run the game for the first time i set the menu to appear automatically by this code:
public var state:int;
public const MENU:int = 0;
public const GAME:int = 1;
// create the variable for the menu
private var _menu:Menu;
public var sBg1:ScrollBg;
public var sBg2:ScrollBg;
public function Engine(menu:Menu)
{
_menu = menu;
//we add event listener when the engine is added to the stage
addEventListener(Event.ADDED_TO_STAGE, onAdded);
}
private function onAdded(e:Event):void {
//then we remove the event listener and initiate the init function
removeEventListener(Event.ADDED_TO_STAGE, onAdded);
init();
}
private function init():void {
//the init function set the game state at first to menu and run the drawUI function
state = MENU;
drawUI();
}
public function drawUI():void
{
//the drawUI function draw the needed elements on stage according to the state of the game
switch(state){
case MENU:
_menu = new Menu();
addChild(_menu);
break;
case GAME:
sBg1= new ScrollBg();
addChild(sBg1);
sBg1.x = 0;
sBg1.y = 0;
//if(contains(_menu)){
//removeChild(_menu);}
trace('this the game');
break;
}
}
and i change the state from menu to the actual game using this code in the menu class:
public var start_btn:MovieClip;
private var _engine:Engine;
public function Menu()
{
addEventListener(Event.ADDED_TO_STAGE, displayMenu);
}
private function displayMenu(e:Event):void
{
removeEventListener(Event.ADDED_TO_STAGE, displayMenu);
start_btn = new startBtn();
start_btn.x = 100;
start_btn.y = 200;
addChild(start_btn);
start_btn.addEventListener(MouseEvent.CLICK, startGame);
}
private function startGame(e:MouseEvent):void
{
start_btn.removeEventListener(MouseEvent.CLICK, startGame);
_engine = new Engine(this);
_engine.state = 1;
_engine.drawUI();
}
i use the drawUI function each time for the menu for example it places the start button and for the game it places the background but for some reason i only get the trace statement saying (this the game) but the background is not displayed any clues .
i spend more then 4 hours trying to find out what is the problem and i still can't if anyone can help me that would be great.
Thanks

If you see the trace but nothing on screen that is most likely because the ScrollBg class doesn't have anything to display. Make sure that class has some sprites or images in it.

Related

how to access dynamic/static movieclip with linked class?

hi this question still bothering me. It looks simple.
I got movieclips in the lib and on stage which has a link-class "Box.as" and another which linked to "Circle.as".
I want to access the movieclip of the Box.as from the Circle.as or vice-versa.
public class Circle extends MovieClip
{
private var _circle:MovieClip;
private var _box:Box;
public function Circle()
{
_circle = new MovieClip();
if (stage) onStage();
else this.addEventListener(Event.ADDED_TO_STAGE,onStage);
}
private function onStage(e:Event = null)
{
_circle = stage.getChildByName("blue_circle") as MovieClip;
this.addEventListener(Event.ENTER_FRAME,hitTarget);
}
private function hitTarget(e:Event):void
{
if (_circle.hitTestObject(_box.mc)) //test if 2 movieclips are colliding
{ // _box.mc is just created the same as _circle
trace("hi");
}
}
this code ain't workin. And I wanted to use one that can access even if the movieclip wasn't on stage(which has no instance name).
Hope you can help me. Thanks.
Looks like you're really close! You just forgot to create a new instance of your class Box. So inside your public function Circle() just add
_box = new Box();
Let me know if that works. If it doesn't, there might be something wrong with your linking...
Your whole code will look like this
public class Circle extends MovieClip
{
private var _circle:MovieClip;
private var _box:Box;
public function Circle()
{
_box = new Box();
_circle = new MovieClip();
if (stage) onStage();
else this.addEventListener(Event.ADDED_TO_STAGE,onStage);
}
private function onStage(e:Event = null)
{
_circle = stage.getChildByName("blue_circle") as MovieClip;
this.addEventListener(Event.ENTER_FRAME,hitTarget);
}
private function hitTarget(e:Event):void
{
if (_circle.hitTestObject(_box.mc)) //test if 2 movieclips are colliding
{ // _box.mc is just created the same as _circle
trace("hi");
}
}

Action Script 3.0 Mouse Event in a class package

am having problem with using mouse click event inside a class, i am an absolute beginner to Action Script.
what i want is that if i click the btn_MClick button it should run the script, but everytime i click it i get error message that btn_MClick is undefined.
btn_MClick is on stage and with the instance name if btn_MClick
public class gunShip1 extends MovieClip
{
var moveCount = 0;
public function gunShip1()
{
stage.addEventListener(KeyboardEvent.KEY_DOWN, moveGunShip1);
stage.addEventListener(KeyboardEvent.KEY_DOWN, ShootGunShip1)
btn_MClick.addEventListener(MouseEvent.MOUSE_DOWN.KEY_DOWN, ShootGunShip1);;
}
function ShootGunShip1(evt: MouseEvent)
{
var s_Bullet:survBullet = new survBullet();
var stagePos:Point = this.localToGlobal (new Point(this.width / 2-10, this.height));;
s_Bullet.x = stagePos.x;
s_Bullet.y = stagePos.y;
parent.addChild(s_Bullet);
//play sound
var gun_sound:ricochetshot = new ricochetshot();
gun_sound.play();
}
}
Please, i have absolutely no idea what to do, and somehow it feels like the whole process is wrong.
Your class gunShip1 does not have the property btn_MClick, the root, or document class does.
Basically what's happening is that you've placed your button on the stage, which makes it an instance that belongs to the root container. At the moment, you're trying to refer to the button as a property of gunShip1.
What you should really do here is have the button click managed separately to gunShip1, and have that separate code invoke methods of gunShip1. For example, you could have this in your document class:
public class Game extends MovieClip
{
private var _ship:gunShip1;
public function Game()
{
_ship = new gunShip1();
// The Document Class will have reference to objects on the stage.
btn_MClick.addEventListener(MouseEvent.CLICK, _click);
}
private function _click(e:MouseEvent):void
{
_ship.shoot();
}
}
And then your updated shoot method in gunShip1:
public function shoot():void
{
var s_Bullet:survBullet = new survBullet();
var stagePos:Point = this.localToGlobal (new Point(this.width / 2 - 10, this.height));
s_Bullet.x = stagePos.x;
s_Bullet.y = stagePos.y;
parent.addChild(s_Bullet);
var gun_sound:ricochetshot = new ricochetshot();
gun_sound.play();
}
The idea is that the gunShip1 should not be responsible for dealing with user input (mouse, keyboard, etc). Instead, that should be a separate class which informs gunShip1 that it should do something.

AS3: Error 1009: Null reference

I am making a game in ActionScript 3. I have a Menu Class with a method that renders a Menu.
I make an instance of Menu in my Main class, and then call the method. When I debug the application I get a null reference error. This is the code of the menu class:
package
{
import flash.display.MovieClip;
import menucomponents.*;
public class Menu extends MovieClip
{
public function Menu()
{
super();
}
public function initMenuComponents():void{
var arrMenuButtons:Array = new Array();
var btnPlay:MovieClip = new Play();
var btnOptions:MovieClip = new Options();
var btnLikeOnFacebbook:MovieClip = new LikeOnFacebook();
var btnShareOnFacebook:MovieClip = new ShareOnFacebook()
arrMenuButtons.push(btnPlay);
arrMenuButtons.push(btnOptions);
arrMenuButtons.push(btnLikeOnFacebbook);
arrMenuButtons.push(btnShareOnFacebook);
var i:int = 0;
for each(var item in arrMenuButtons){
item.x = (stage.stageWidth / 2) - (item.width / 2);
item.y = 100 + i*50;
item.buttonMode = true;
i++;
}
}
}
}
Thanks in advance.
Your issue is likely that stage is not populated yet when your for loop runs. Try the following:
public class Main extends MovieClip {
public function Main() {
super();
var menu:Menu = new Menu();
//it's good practice - as sometimes stage actually isn't populated yet when your main constructor runs - to check, though in FlashPro i've never actually encountered this (flex/flashBuilder I have)
if(stage){
addedToStage(null);
}else{
//stage isn't ready, lets wait until it is
this.addEventListener(Event.ADDED_TO_STAGE,addedToStage);
}
}
private function addedToStage(e:Event):void {
menu.addEventListener(Event.ADDED_TO_STAGE,menuAdded); //this will ensure that stage is available in the menu instance when menuAdded is called.
stage.addChild(menu);
}
private function menuAdded(e:Event):void {
menu.initMenuComponents();
}
}

AS3 Mouse Over Change Image

Currently I'm trying to change image loaded in a sprite with mouseover event and change it back with mouseout. But it's not working correctly, am i missing something?
public class Tab extends Sprite
{
var imageLoader:Loader = new Loader();
var TabSprite:Sprite = new Sprite();
var SkinImages:Array = [Skin.TAB_ACTIVE,Skin.TAB_DISABLED,Skin.TAB_HOVER,Skin.TAB_VIEW];
public function Tab()
{
for each (var Image:String in SkinImages){
imageLoader.load(new URLRequest(Image));
}
TabSprite.buttonMode = true;
addChild(TabSprite);
TabSprite.addChild(imageLoader);
TabSprite.addEventListener(MouseEvent.MOUSE_OVER, onTabHover);
}
private function onTabHover(e:MouseEvent){
trace("HOVER");
TabSprite.removeEventListener(MouseEvent.MOUSE_OVER, onTabHover);
imageLoader.load(new URLRequest(Skin.TAB_HOVER));
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e:Event):void{
TabSprite.addEventListener(MouseEvent.MOUSE_OUT, onTabOut);
});
}
private function onTabOut(e:MouseEvent){
trace("OUT");
TabSprite.removeEventListener(MouseEvent.MOUSE_OUT, onTabOut);
imageLoader.load(new URLRequest(Skin.TAB_VIEW));
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e:Event):void{
TabSprite.addEventListener(MouseEvent.MOUSE_OVER, onTabHover);
});
}
}
You shouldn't nest listeners that way. Just add two in the constructor:
TabSprite.addEventListener(MouseEvent.ROLL_OVER, onTabHover);
TabSprite.addEventListener(MouseEvent.ROLL_OUT, onTabOut);
Note changing MOUSE_OVER to ROLL_OVER it's better in most cases. You shouldn't also load images at every mouse event. Preload them, and then use. Also using anonymous functions in listeners is bad practice as you are not able to remove that listener:
imageLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e:Event):void{
TabSprite.addEventListener(MouseEvent.MOUSE_OUT, onTabOut);
});
And in fact you are not removing it - this is bad.
for each (var Image:String in SkinImages){
imageLoader.load(new URLRequest(Image));
}
I doubt it works, I think you cannot load many images at once by using one loader.
Try this:
public class Tab extends Sprite
{
var imageOverLoader:Loader = new Loader();
var imageOutLoader:Loader = new Loader();
var TabSprite:Sprite = new Sprite();
var SkinImages:Array = Skin.TAB_ACTIVE,Skin.TAB_DISABLED,Skin.TAB_HOVER,Skin.TAB_VIEW];
public function Tab()
{
TabSprite.buttonMode = true;
this.addChild(TabSprite); // you also need to add as a Child "Tab" object in the Main Class
imageOutLoader.load(new URLRequest(Skin.TAB_VIEW));
imageOverLoader.load(new URLRequest(Skin.TAB_HOVER));
TabSprite.addChild(imageOutLoader);
TabSprite.addEventListener(MouseEvent.ROLL_OVER, onTabHover);
TabSprite.addEventListener(MouseEvent.ROLL_OUT, onTabOut);
}
private function onTabHover(e:MouseEvent){
TabSprite.removeChild(imageOutLoader);
TabSprite.addChild(imageOverLoader);
trace("HOVER");
}
private function onTabOut(e:MouseEvent){
TabSprite.removeChild(imageOverLoader);
TabSprite.addChild(imageOutLoader);
trace("OUT");
}
}
Try this.

AS3 question - Best way to lockout buttons

Hello and thanks for reading this.
I made buttons using as3 within flash but what I'd like to do is make them inactive for a few seconds when one is pressed. Normally I'd use google to solve this kind of a problem but I dont even know how to word it properly.
Thanks
You could :
Set the .enabled property to false in order to have your click event handlers disabled.
Add a new locking variable and surround all the code in your click handler with 'if(lockingVariable)'. Then all you would need to do is set this to false. Ideally, though, you'd just disable the button.
As for doing it for a few seconds, look into the timer class. This link should be helpful. The typical pattern goes something like this :
var myTimer:Timer = new Timer(1000, 1); // 1 second
myTimer.addEventListener(TimerEvent.TIMER, runOnce);
myTimer.start();
function runOnce(event:TimerEvent):void {
trace("runOnce() called # " + getTimer() + " ms");
}
All you would have to do is have a re-enabling callback as the method for line 2 and your button would be disabled for 1 second.
Try using this as a base class for your buttons:
package
{
import flash.display.SimpleButton;
import flash.events.MouseEvent;
import flash.events.Event;
public class MyButton extends SimpleButton
{
// vars
public const DELAY:uint = 30;
private var _timer:int = 0;
/**
* Constructor
*/
public function MyButton()
{
addEventListener(MouseEvent.CLICK, _click);
}
/**
* Called on Event.ENTER_FRAME
*/
private function _handle(e:Event):void
{
_timer --;
if(_timer < 1) removeEventListener(Event.ENTER_FRAME, _handle);
}
/**
* Called on MouseEvent.CLICK
*/
private function _click(e:MouseEvent):void
{
if(_timer > 0) return;
_timer = DELAY;
addEventListener(Event.ENTER_FRAME, _handle);
// do your stuff below
clickAction();
}
/**
* Override this and fill with your actions
*/
protected function clickAction():void
{
trace("override me");
}
}
}
Here's an example of overriding the clickAction() method in MyButton:
package
{
public class MyPlayButton extends MyButton
{
override protected function clickAction():void
{
trace("play button clicked");
}
}
}
The way I would do it is simply set the enabled property of the button to false for a set amount of time, using a Timer, once the button is pressed.
myBut.addEventListener(MouseEvent.CLICK, doStuff);
function doStuff(e:MouseEvent){
//write whatever the button does here
disableBut();
}
function disableBut(){
myBut.enabled = false;
var timer:Timer = new Timer(3000, 1);
timer.addEventListener(TimerEvent.TIMER, enableBut);
timer.start()
}
function enableBut(e:TimerEvent){
myBut.enabled = true;
}
Remember that the length of time that the button is disabled for is set in the first parameter of the Timer() constructor, and is in milliseconds. In my example you can see that myBut is disabled for 3 seconds.