Actionscript3 how to get the index of object clicked - actionscript-3

I'm trying to have this hero shoot the bullet. Ex: The bullet has fire and ice type. if the hero placed is fire type then it will shoot fire bullet, if it's ice type then it will shoot ice bullet. And each bullet have each own effects and damages.
So, I've tried to get the index of hero chosen and later on the index will be used to define which bullet used by tracing (heroesArray.indexOf(heroClicked)); but the value of heroclicked is (object Hero1). so I can't use it since the array of heroesArray is [hero1,hero2]. I did splitting and joining too but it kinda messed up...
My question is how to get the String value that only contains the variable of clicked object (hero1 or hero2)? Is there any 'vocabulary' to get the variable name like getqualifiedclassname used for getting class name of an object?
Or is there any other idea to create bullet type the same as hero type without using indexOf ?
Thanks !
Here is the code :
package {
import flash.display.MovieClip
import flash.events.MouseEvent
import flash.events.Event
import flash.display.Sprite
import flash.utils.*
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 bulletArray:Array;
private var bullet1:MovieClip = new Bullet1();
private var bullet2:MovieClip = new Bullet2();
private var moveHero:Boolean = false;
private var movingHero:MovieClip;
private var _money:Money = new Money();
private var _main:Main;
private var _enemy:Enemy = new Enemy(_main);
public function Hero(main:Main)
{ _main = main;
heroesArray = [hero1,hero2];
bulletArray = [bullet1,bullet2];
}
private function playerMoving(e:Event):void
{
if (moveHero == true)
{
movingHero.x = _main.mouseX;
movingHero.y = _main.mouseY;
}
}
private 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);
moveHero = true;
var heroClass:Class = getDefinitionByName(getQualifiedClassName(heroClicked)) as Class;
movingHero = new heroClass();
heroContainer.addChild(movingHero);
movingHero.addEventListener(MouseEvent.CLICK, placeHero);
}
}
private function placeHero(e:MouseEvent):void
{
var heroClicked:MovieClip = e.currentTarget as MovieClip;
var heroRow:int = Math.floor(_main.mouseY/75);
var heroCol:int = Math.floor((_main.mouseX-10)/65);
if(heroRow>0 && heroCol>0 && heroRow<6 && heroCol<10&&
_main.field[heroRow][heroCol]==0)
{
movingHero.fireRate =75;
movingHero.recharge = 0;
movingHero.firing = false;
movingHero.heroRow = heroRow;
movingHero.x = 42+heroCol*65;
movingHero.y = 10+heroRow*75;
_main.field[heroRow][heroCol]=1;
moveHero = false;
movingHero.removeEventListener(MouseEvent.CLICK, placeHero);
}
}
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;
heroesArray[i].addEventListener(MouseEvent.CLICK, chooseHero);
heroesArray[i].addEventListener(Event.ENTER_FRAME, playerMoving);
}
}
}
}

You've pretty much got the answer right in front of you. The two heros are of classes Hero1 and Hero2, and you find the class via
var heroClass:Class = getDefinitionByName(getQualifiedClassName(heroClicked)) as Class;
All you need to do is compare heroClass to those two classes like so:
if(heroClass == Hero1)
{
...
}
else
{
...
}
Linking hero to bullet type
If you don't know, or don't want to learn classes (see my comment for an excellent tutorial) then you'll need a lookup table/Dictionary so that you can link bullet type to hero.
//Put this in your constructor after the bullet types and heroes have been declared
var bulletDict = new Dictionary();
bulletDict[hero1] = bulletTypeIce; //Note the lack of quotations around hero1 and 2
bulletDict[hero2] = bulletTypeFire;
So, to get the bullet type out:
var bulletType = bulletDict[heroClicked];

Related

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

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.

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.

Best way of passing values from a button with as3 event

I develop my own way of doing this simple task. However, I'm now wondering if there is a better way to do it.
The buttons:
var menuBtnEscrit:MovieClip = new MovieClip();
var mbe:btnEscritorio = new btnEscritorio();
menuBtnEscrit.addChild(mbe);
menuBtnEscrit.val = "escrit";
menuBtnEscrit.x = 80;
menuBtnEscrit.addEventListener(MouseEvent.CLICK, novoCont);
dMenu.addChild(menuBtnEscrit);
var menuBtnPublic:MovieClip = new MovieClip();
var mbp:btnPublic = new btnPublic();
menuBtnPublic.addChild(mbp);
menuBtnPublic.val = "public";
menuBtnPublic.x = 244;
menuBtnPublic.addEventListener(MouseEvent.CLICK, novoCont);
dMenu.addChild(menuBtnPublic);
And I can keep going, or create buttons trough some algorithm, and put more properties and take advantage of a MovieClip.
The handler:
private function novoCont(e=null){
if(e!=null) selecCont = new String(e.target.parent.val);
clearDisplay(dSubMenu);
clearDisplay(dConteudo);
var func:String = "cont_"+selecCont;
this[func]();
}
As you can see, there is some common task for all buttons.
If I click the first button, it will call cont_escrit() function. This mechanics works, but it is the best practice? Is there a way of optimize it?
public class BaseButton extends Button {
private var _func:Function;
public function get handler():Function {
return _func;
}
public function set handler(value:Function):void {
_func = value;
}
}
So hero you can create mbe like this
mbe = new BaseButton ();
mbe.hanler = cont_escrit;
The event hanler would be
private function novoCont(e=null){
if(e!=null) {
var selecContent:BaseButton = e.targe as BaseButton ;
var handler:Function = selecContent.handler;
handler();
}
}
Here is an example.
var menuBtnEscrit:MovieClip = new MovieClip();
var mbe:btnEscritorio = new btnEscritorio();
menuBtnEscrit.addChild(mbe);
//menuBtnEscrit.val = "escrit";
menuBtnEscrit.func = this.cont_escrit;
menuBtnEscrit.x = 80;
menuBtnEscrit.addEventListener(MouseEvent.CLICK, novoCont);
private function novoCont(e=null){
if(e!=null) {
var mc:MovieClip = e.target as MovieClip;
var func:Function = mc.func;
func();
}
clearDisplay(dSubMenu);
clearDisplay(dConteudo);
}

Actionscript 3 compare two MovieClips

I dynamically add MovieClips to an DisplayObjectContainer. Some of these MovieClips loop through all children of DisplayObjectContainer to check gravitation and collision. Though, when I check if the current child is not equal to the caller MovieClip it seems to check the type only.
So basically, when I check MovieClip equality it seems to check the type only.
Main.as:
var planet:Planet = new Planet(holder);
planet.x = 0;
planet.y = 0;
planet.spawn();
var planet2:Planet = new Planet(holder);
planet2.x = 50;
planet2.y = 50;
planet2.spawn();
Planet.as:
public class Planet {
public var x:Number = 0;
public var y:Number = 0;
private var _holder:DisplayObjectContainer;
private var _mc:MovieClip;
public function Planet(holder:DisplayObjectContainer) {
_holder = holder;
_mc = new PlanetMovieClip();
_mc.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
public function spawn():void {
_holder.addChild(_mc);
}
private function enterFrameHandler(evt:Event):void {
for(var i:int = 0; i < _holder.numChildren; i++) {
var child:MovieClip = _holder.getChildAt(i) as MovieClip;
// the other planet never passes this check
if(child !== _mc) {
trace('child is not the same');
}
}
}
}
So am I doing something wrong, should I approach an other method or should I just add an property that generates a random token used for identification?
you should remove as MovieClip; in _holder.getChildAt(i);
I would change !== with !=
The rest of your code seems ok.
First of all you have error in the code you have given to create Planet movieclip.
It should be
var planet:Planet = new Planet(holder);
planet.x = 0;
planet.y = 0;
planet.spawn();
var planet2:Planet = new Planet(holder)
planet2.x = 50;
planet2.y = 50;
planet2.spawn();
Did you check for null in Planet.as ?
if(child!=null) {
if(child !== _mc)
trace('child is not the same');
else
trace("child same");
}
And ofcourse you can always assign some unique name to the movieclips, and use it for comparing.

AS3 object array to class

I am new and having an issue with the use of classes in as3.
I have created an array of objects in my main timeline
function badPlayer()
{
var bads:Array = new Array();
for (var i=0; i<5; i++)
{
var mc = new bman();
mc.name=["mc"+i];
bads.push(mc);
_backGround.addChild(mc);
mc.x = 100;
mc.y = 100;
trace (bads);
Baddies(_backGround.mc); //here I am trying to export mc to my class
}
}
Here is a snip-it from my class. My trace statement wont even output.
public class Baddies extends MovieClip
{
private var pistolSound:pistolShot = new pistolShot();
//private var mc = new mc();
private var _rotateSpeedMax:Number = 2;
private var _gravity:Number = .68;
private var _bulletSpeed:Number = 2;
private var _maxDistance:Number = 200;
private var _reloadSpeed:Number = 500; //milliseconds
private var _barrelLength:Number = 20;
private var _bulletSpread:Number = 5;
private var _isLoaded:Boolean = true;
private var _isFiring:Boolean = true;
private var _endX:Number;
private var _endY:Number;
private var _startX:Number;
private var _startY:Number;
private var _reloadTimer:Timer;
private var _bullets:Array = [];
private var _gun:MovieClip;
private var _enemy:MovieClip;
private var _yx:Number;
private var _yy:Number;
private var _pcos:Number;
private var _psin:Number;
private var _trueRotation:Number;
public function Baddies()
{
trace("working");
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
Basically I am trying to create several bad guys (bman) and have the same code apply to each of them. I have also tried to change the linkage name of bman to Baddies with no success.
There are a few thing that are very wrong with this code.
Baddies(_backGround.mc); //here I am trying to export mc to my class
This is a typecast, as already stated in the comments. By the way Baddies isn't a good name, because it plural. You probably want to create a new bad guy, which would be done with this line:
var baddie = new Baddies();
Now your constructor uses the stage variable. This won't work because the object isn't on the stage, therefore stage is null (it may works if you drag and drop an instance to the stage in the editor). So before using the stage you actually need to add the object to the stage:
public function Baddies() {
trace("new baddie created");
}
public function init(mc:MovieClip) {
mc.addChild(this); // display this baddie
trace("working");
stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
}
And in the badPlayer function:
var baddie = new Baddies();
baddie.init(_backGround);