how to access dynamic/static movieclip with linked class? - actionscript-3

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");
}
}

Related

Actionscript 3 Call to a possibly undefined method

Here is the problem, the object is moved together with the clicked object. I want it to be moveable following the mouse pointer, but let the clicked object stays. so when an object is clicked, there will be 2 objects in the stage(the static and moving one).
I think I've figured it out by adding a new object to be moved. in function onClickHero I've tried movingHero = new heroes but it says "call to a possibly undefined method heroes". My question is there any other way how to make another clone of the clicked object since I made it in array? And why does movingHero = new heroes doesn't work?
I'm still amateur at classes. Sorry if it's messed up. Thanks for helping.
package {
import flash.display.MovieClip
import flash.events.MouseEvent
import flash.events.Event
import flash.display.Sprite
public class Hero {
private var heroesArray:Array;
private var heroContainer:Sprite = new Sprite;
private var hero1:MovieClip = new Hero1();
private var hero2:MovieClip = new Hero2();
private var moveHero:Boolean = false;
private var movingHero:MovieClip;
private var _money:Money = new Money();
private var _main:Main;
public function Hero(main:Main)
{ _main = main;
heroesArray = [hero1,hero2];
heroesArray.forEach(addHero);
}
public function addHero(heroes:MovieClip,index:int,array:Array):void
{
heroes.addEventListener(Event.ENTER_FRAME, playerMoving);
heroes.addEventListener(MouseEvent.CLICK, chooseHero);
}
public function playerMoving(e:Event):void
{
if (moveHero == true)
{
movingHero.x = _main.mouseX;
movingHero.y = _main.mouseY;
}
}
public function chooseHero(e:MouseEvent):void
{
var heroClicked:MovieClip = e.currentTarget as MovieClip;
var cost:int = _main._money.money ;
if(cost >= 10 && moveHero == false)
{
_main._money.money -= 10;
_main._money.addText(_main);
onClickHero(heroClicked);
moveHero = true;
}
}
public function onClickHero(heroes:MovieClip):void
{
movingHero = heroes;
heroContainer.addChild(movingHero);
}
public function displayHero(stage:Object):void
{
stage.addChild(heroContainer);
for (var i:int = 0; i<2;i++)
{
stage.addChild(heroesArray[i]);
heroesArray[i].x = 37;
heroesArray[i].y = 80+i*70;
heroesArray[i].width=60;
heroesArray[i].height=55;
heroesArray[i].buttonMode = true;
}
}
}
}
EDIT: I've tried to make movingHero = new Hero1(); but since I don't know which hero will be clicked so I can't just use Hero1 from library. and If I use movingHero = heroClicked I only get the value of hero1 which is a var from Hero1 movieclip. So, is there any way to call the movie clip from library the same as which hero was clicked in stage?
You seemingly want to clone an object while not knowing its type. If that object also containg game logic, it's not the best idea to say spawn new heroes of either type, this might make a mess of your code. But if not, you can get the exact class of the object given, and make an object of that class via the following code:
public function onClickHero(heroes:MovieClip):void
{
if (!heroes) {
trace('heroes is null!');
return;
}
var heroClass:Class = getDefinitionByName(getQualifiedClassName(heroes)) as Class;
movingHero = new heroClass(); // instantiate that class
heroContainer.addChild(movingHero);
// movingHero.startDrag(); if needed
}
Don't forget to clean up the movingHero once it's no longer needed.

How to change cursor on Roll Over event

I'm making a point and click game in AS3 with flash.
I've changed the skin of my cursor by creating a new class "Souris". It's working just fine. Now I'm trying to change the skin of the cursor when it's on an object on the scene.
I've read that the MouseEvent.ROLL_OVER is the good method but I can't figure out how to do it...
I've got my Souris class like that :
public class Souris extends MovieClip
{
private var engine:Engine;
private var stageRef:Stage;
private var p:Point = new Point();
public function Souris(stageRef:Stage)
{
Mouse.hide(); //make the mouse disappear
mouseEnabled = false; //don't let our cursor block anything
mouseChildren = false;
this.stageRef = stageRef;
x = stageRef.mouseX;
y = stageRef.mouseY;
stageRef.addEventListener(MouseEvent.MOUSE_MOVE, updateMouse, false, 0, true);
stageRef.addEventListener(Event.MOUSE_LEAVE, mouseLeaveHandler, false, 0, true);
stageRef.addEventListener(Event.ADDED, updateStack, false, 0, true);
stageRef.addEventListener(MouseEvent.ROLL_OVER,hover);
}
private function updateStack(e:Event) : void
{
stageRef.addChild(this);
}
private function hover(e:MouseEvent):void {
souris.visible = false;
}
private function mouseLeaveHandler(e:Event) : void
{
visible = false;
Mouse.show(); //in case of right click
stageRef.addEventListener(MouseEvent.MOUSE_MOVE, mouseReturnHandler, false, 0, true);
}
private function mouseReturnHandler(e:Event) : void
{
visible = true;
Mouse.hide(); //in case of right click
removeEventListener(MouseEvent.MOUSE_MOVE, mouseReturnHandler);
}
private function updateMouse(e:MouseEvent) : void
{
x = stageRef.mouseX;
y = stageRef.mouseY;
e.updateAfterEvent();
}
}
}
}
In my main class (Engine class) I've got :
private var souris:Souris;
public function Engine(){
souris = new Souris(stage);
stage.addChild(souris);
}
private function startGame(e:Event):void{
....
..
I've tried to put in the "Souris" class
stageRef.addEventListener(MouseEvent.ROLL_OVER,hover);
private function hover(e:MouseEvent):void {
Engine.souris.visible = false;
handCursor.visible = true ;
}
But it seems wrong...
I don't know what to put in my hover function. (I've got the "handCursor" in my library).
Thank you very much for your help!
If you have "handCursor" in your library, then you need to assign a class to it, like 'HandCursor'. I advise that classes start with an uppercase letter.
So your code would need to create a new instance of it then show it, like
var handCursor:HandCursor = new HandCursor; handCursor.visible = false;
handCursor.visible = false; makes it not visible, then to make it visible, you would:
handCursor.visible = true;
Also, handCursor is a local variable if put in a function, to make it global to use in all functions, you would need to put it at the beginning of your Class.
Also, are you getting any errors? If so, please share them.

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:Calling a switch case from another class does't work

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.

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.