AS3 pass MovieClip to super - actionscript-3

I have a Spaceship movieclip, with a movieclip Turret inside.
Spaceship extends the Unit class, where I want to rotate the Turret.
In my Spaceship constructor, I use super(this.turret); but this always returns null.
Passing other variables works, and before calling super(), I can successfully trace this.turret
So why can't I pass it to super? And how can I fix this?
[edit]
Perhaps it has something to do with the turret not being available/added to stage yet when super() is called? If so, how could I deal with that and get it "Unit" anyways?

When you pass turret into the constructor you are only passing a reference to the MovieClip with that instance name. What does the Unit constructor do with the parameter? I guess that your Unit class are not supposed to have a turret variable.
UPDATE 1:
public class SpaceShip extends Unit
{
public var turret : MovieClip;
public function SpaceShip()
{
super();
}
}
// Access from other class where ship has been referenced
public class Test extends Sprite
{
public var ship : SpaceShip;
public function ship()
{
// access the public variable (reference) turrent
ship.turrent.rotation += 25;
}
}

Related

Issues with Accessing Superclass Properties (AS3)

I am running into an issue where it seems to be ignoring functions I try to overload.
I have a class called Projectile that extends the Entity class. Projectile is passed an array of MovieClips to compare collision against. If it collides with one of those array elements, collidingWith is set to that object. The onCollision()function is then called to resolve what should happen to the colliding object.
Here is the relevant code:
public class Main extends MovieClip{
...
for(var i in projectileArray){
projectileArray[i].update();
}
...
}
public class Entity extends MovieClip{
protected var canCollideWith:Array; //Array of objects to test collision against
protected var collidingWith:Object; //Object this projectile collided with
...
protected function update(){
this.checkCollision()
}
protected function checkCollision(){
for(var in canCollideWith){
if (image.hitTestObject(canCollideWith[i])){
collidingWith = canCollideWith[i];
this.onCollision();
}
}
}
protected function onCollision(){
//To be overriden by child classes
trace("Entity onCollision");
}
}
public class Projectile extends Entity{
public function Projectile(...){
super.(...);
}
override protected function onCollision(){
trace("Projectile onCollision");
}
}
Based on trace statements I tried, I am able to overload Entity.update() and Entity.checkCollision, it will not let me override Entity.onCollision(). It will only ever go to the onCollision function of Projectile's superclass (Entity).
Further, when I attempt to access collidedWith from within any Projectile function, it remains at its default value, and is not sharing the value it should be set to from within Entity.checkCollision().
Am I missing something? Is there some OOP aspect I am overlooking?
Thanks in advance,
Glen
Nevermind, I figured out the problem. Projectiles can collide with Mortals, which are both subclasses of Entity. The trace statements for collision were being called from within the Mortal class, not Projectile, hence why the override did not appear to work.

AS3 - dispatch custom event with parameter (not working)

I read a lot of topics about dispatching event but I can't make my code work.
This topic and this topic are closed to what I would like to do, but it's not working in my case.
Here is the situation :
My scene is a battle field and has two ships
Each ship knows when it is touched by a fire, so it has to inform the scene that contains the graphic interface
So the ship dispatch a custom event with itself as parameter, so the scene knows when a ship is touched and which ship
I have 3 classes :
The custom event class is an event that has a property "Ship"
The EventDispatcher class
The symbole class that corresponds to my scene and listen to the event
1) CustomEvent class
public class FightEvent extends Event
{
public static const SHIP_TOUCHED:String = "SHIP_TOUCHED"; //type
public var object:Ship = null; //object to pass
public function FightEvent(type:String, pObject:Ship, bubbles:Boolean=true, cancelable:Boolean=false)
{
super(type, bubbles, cancelable);
object = pObject;
}
public override function clone():Event
{
return new FightEvent(type, object, bubbles, cancelable);
}
}
2) EventDispatcher
public class Ship extends EventDispatcher
{
private function updateDamages():void
{
//compute damages
dispatchEvent( new FightEvent( FightEvent.SHIP_TOUCHED, this ) );
}
}
3) Scene
public class Fight extends customMovieClip
{
private var playerShip:Ship; //I have two ships, player and enemy
private var enemyShip:Ship;
public function init():void
{
stage.addEventListener(FightEvent.SHIP_TOUCHED, onShipTouched);
//I made a test : the event listener is correctly added
}
private function onShipTouched(e:FightEvent):void
{
//update the graphic interface to show damages
}
}
My event listener is added, the code passes on the dispatch line, but onShipTouched is not called.
Please help, what did I miss ?
What is the element I didn't understand ?
Is it a good way to use events like this ? or should I set a reference to the scene inside the Ship class ?
Your Ship class is not a MovieClip, Sprite or their subclass in order for your event to bubble up the display list, just because they don't participate in a display list. So, you change your Ship to Sprite subclass (this one already inherits EventDispatcher), add graphics and addChild() both ships to the stage, this way your stage will receive events properly.
My logic was wrong :
I was doing this : the eventdispatcher is dispatching the event, and the stage is listening to the event. That is incorrect.
The right solution is : the eventdispatcher is dispatching the event, and is also listening to its own dispatched event. The eventlistener is added to the eventdispatcher in the scene, that contains the function to call.
As Vesper said, the parameter in FightEvent is useless, as the eventdispatcher is actually the event target.
DodgerThud, BotMaster, you gave me this answer, thank you for your help (Looks like I can't set a comment as "answer accepted").
Here the right code for the Fight class :
public class Fight extends customMovieClip
{
private var playerShip:Ship; //I have two ships, player and enemy
private var enemyShip:Ship;
public function init():void
{
enemyShip.addEventListener(FightEvent.SHIP_TOUCHED, onShipTouched);
playerShip.addEventListener(FightEvent.SHIP_TOUCHED, onShipTouched);
}
private function onShipTouched(e:FightEvent):void
{
//e.target == the ship that dispatched the event
}
}

AS3 - Accessing subclass of subclass

Im making this game, and I really want to access a "subclass of subclass". So I have something like this: MainClass > MonsterLibrary > SampleMonster.
I want to add this Sample Monster from MainClass, but I have to use it through MonsterLibrary, so I dont have to add monster by monster at my MainClass. Every monster respawn would be written in MonsterLibrary class.
I guess it should be something like this.
public class MainGame extends MovieClip {
public function MainGame() {
var mylibrary:MonsterLibrary = new MonsterLibrary();
mylibrary.MonsterLibrary();
Main class.
public class MonsterLibrary extends MovieClip {
#all var here.#
public function MonsterLibrary(){
var monster:SampleMonster = new SampleMonster(330,250);
addChild(monster);
}
MonsterLibrary class.
public class SampleMonster extends MonsterLibrary{
public function SampleMonster(startX:Number, startY:Number) {
//SETTING STARTING LOCATION
x = startX;
y = startY;
SampleMonster class.
I know Im doing it wrong, but I have no idea how to make this work. I keep getting this error ->
1061: Call to a possibly undefined method MonsterLibrary through a reference with static type MonsterLibrary.
You get that error because you're trying to directly call the constructor of MonsterLibrary:
public function MainGame()
{
var mylibrary:MonsterLibrary = new MonsterLibrary();
mylibrary.MonsterLibrary(); // <- wrong
...
}
The MonsterLibrary() function is the constructor of the MonsterLibrary class and it's called automatically when you use the new operator to create a new instance of the class.
If you want your MonsterLibrary class to act as a monster factory (a class that creates monster objects), create a new function that returns a monster:
...
public function CreateMonster ( sType:String ):SampleMonster
{
var oMonster:MovieClip = null; // you can use BaseMonster instead of MovieClip
if ( sType == "SampleMonster" )
{
oMonster = new SampleMonster ( ... );
... // initialize the monster here
}
...
return ( oMonster );
}
...
// get a monster and add it to the stage
var oMonster:MovieClip = oMonsterLibrary.CreateMonster ( "SampleMonster" );
oStage.addChild ( oMonster );
Note that MonsterLibrary doesn't need to extend MovieClip - it really doesn't need to extend any type (other than Object) since (I assume) it's not a visual object. Its purpose is to be a factory, not to be on the screen. oStage in the code above is your top-level display object - it could be the actual stage or a DisplayObject that acts as your stage.
The SampleMonster type shouldn't extend MonsterLibrary - a particular monster is not a library. Your monsters should derive either directly from MovieClip or (better) from a common base monster class; something like:
public class BaseMonster extends MovieClip
{
...
}
Then your SampleMonster can derive from this base monster:
public class SampleMonster extends BaseMonster
{
...
}
I'm confused at what you are trying to accomplish.
Are you looking to have the MonsterLibrary return a monster every time you call a method ?
ie you could have a method in MonsterLibrary class like this :
public function getMonster():SampleMonster
{
var monster:SampleMonster = new SampleMonster(330,250);
return monster;
}
Then your MainGame might look like this :
public class MainGame extends MovieClip {
public function MainGame() {
var mylibrary:MonsterLibrary = new MonsterLibrary();
var newMonster:SampleMonster = mylibrary.getMonster();
addChild(newMonster);
Going further you could have a parameter for the getMonster method to specify a monster type.
for example :
public function getMonster(monsterType:int):Monster
{
// create the appropriate monster and return it
}
Keep in mind that in your code adding the monster to the Display List of the MonsterLibrary, means it will never be seen UNLESS you add MonsterLibrary to the Display List of MainGame
Also you have SampleMonster extending MonsterLibrary, which is not going to work.
SampleMonster should probably extend MovieClip or Sprite or if you intend on having multiple monsters you'd want to have a base Monster Class that any specific monster might extend.

ActionScript3: Inheriting constructor arguments from parents

I'm making a game in action script 3. In it, I have an actor class from which player and enemy classes will be derived. I'm doing this so that unless I need to provide specific AI or fancy behavior (such as for bosses), I can just make a new clip in the library for each enemy without making an actionscript file.
However, I've run into a problem.
Whenever I try to pass arguments to the construction of an enemy (make it spawn with more health), I get error 1136 (Incorrect number of arguments.)
This is because the constructor created automatically at runtime doesn't have the same arguments as it's parent class. Is there any way to get around this without making a class file where I copy and paste the parent constructor function for each of my hundreds of enemies?
Edit
actually rereading your question I think you may be looking for super();
Example
public class Actor{
private var myHelth:uint;
public function Actor(helth:uint = 100){
myHelth = helth; //this will be set to 100 if nothing it passed in or the value passed
}
}
Class that extends Actor:
public class Boss extends Actor{
public function Boss(){
super(200); //passes 200 to Actor;
}
}
If you're trying to pass data into a classes constructor you need to make sure it's accepting arguments.
public class Actor{
private var myHelth:uint;
public function Actor(helth:uint = 100){
myHelth = helth; //this will be set to 100 if nothing it passed in or the value passed
}
}
Then to use
var a:Actor = new Actor(200); //setting health to 200
var b:Actor = new Actor(); //using the default of 100
Make sure your symbols in Flash Pro have appropriate AS linkage, then use pass constructor arguments in super statements:
Actor - base class
package
{
public class Actor
{
public function Actor(name:String, role:String)
{
}
}
}
Player - inherits from Actor defining its own constructor parameters:
package
{
public final class Player extends Actor
{
public function Player(... params:Array)
{
// pass desired inherited constructor parameters
super("name", "role");
}
}
}
Enemy - inherits from Actor defining its own constructor parameters:
package
{
public final class Enemy extends Actor
{
public function Enemy(... params:Array)
{
// pass desired inherited constructor parameters
super("name", "role");
}
}
}

Reference MovieClip After it is Added to Stage as a Child

I am currently having problems referencing a MovieClip child which I add to the Stage from the Document Class. Basically when the MovieClip child is added to the Stage from the Document Class, I want a certain MovieClip already on the Stage to reference it once it is on the Stage.
Also, if it is possible, I don't want the MovieClip referencing the child being added to the Stage to have parameters linking it with the Document Class, because I plan on nesting this MovieClip within another MovieClip later on in the future.
Here is the code for the MovieClip class which is referencing the child once it is added to the Stage:
package com.gameEngine.assetHolders
{
import com.gameEngine.documentClass.*;
import com.gameEngine.assetHolders.*;
import com.gameEngine.assetHolders.Levels.*;
import flash.display.*;
import flash.events.*;
public class FallingPlatform extends MovieClip
{
public var _document:Document;
// Trying to reference "_player"
public var _player:Player;
public var fallState:Boolean;
public var platformYSpeed:Number = 0;
public var platformGravityPower:Number = 0.75;
public function FallingPlatform()
{
this.addEventListener(Event.ADDED_TO_STAGE, initFallingPlatform);
// constructor code
}
public function initFallingPlatform(event:Event)
{
this.addEventListener(Event.ENTER_FRAME, dynamicFall);
this.addEventListener(Event.ENTER_FRAME, hitTest);
}
public function dynamicFall(event:Event)
{
if (this.fallState)
{
this.platformYSpeed += this.platformGravityPower;
y += this.platformYSpeed;
}
}
// Trying to reference "_player"
public function hitTest(event:Event)
{
if (this.hitTestPoint(_player.x, _player.y + 1, true))
{
this.fallState = true;
}
}
}
}
The player is initialized in the Document class, right? So for me, the best option is either passing the player reference in the constructor of your FallingPlatform class like this
public function FallingPlatform (thePlayer:Player) {
this._player = thePlayer
}
or having a setter method to pass it to it. In this way, you're not tying the structure of your code
public function set player (thePlayer:Player):void {
this._player = thePlayer
}
Hope it helps!
If you set a document class for a fla file every movieclip on the stage can be accessed by it's instance name - just as you wold create a var with its name.
Event more, you can do something like that:
If you place two movieclips on the stagefor example mc1 and mc2 you can add them as variables to the document class.
package{
public class DocClass{
public var mc1:MovieClip;
public var mc2:MovieClip;
[...]
}
}
and than you can access those movieclips from your class with code hints form your IDE (flash or flashbuilder)
the opposite is also availible: define variables in your class and than access them in flash
! it works best when your document class extends a Sprite, I haven;t tested it on extending from a MovieClip but it should also work