Yaniv
Yaniv

Reputation: 7

AS3 Accessing classes and variables

I am new to AS3 and I try to make a simple flash game. My problem concerns accessing a specific array outside of its class. I succeeded accessing some variables and function but I am quite stuck on this one.

There are 3 classes : Game which is the main class tied to the flash file, Level1 which spawn background element and enemies, and finally the Enemy class.

The Game class instantiate the Level1 class which spawn enemies (with Enemy class) and push them to an array. When the enemy get hit, a method in the Enemy class remove it from the display list and then tries to remove it from the array located in the Level1 Class, wich fails and throw :

1119: Access of possibly undefined property level1 through a reference with static type Class.

Another problem is some time the bullets stop in the middle of screen, I havn't been able to track down this bug as well.

Any way, this is my first code related post and if it's too messy, tell me and I'll try to make it more readable. Sorry for any inconveniance and thank you for your help -Yaniv

 package 
{
    import flash.display.MovieClip;

    import flash.events.MouseEvent;
    import flash.events.Event;
    import flash.text.*;
    import flash.geom.Point;

    public class Game extends MovieClip
    {
        public var player:Player;
        public var level1:Level1;
        public var bullet:Bullet;
        private var bullets_arr:Array;
        var fire_on : Boolean;
        var fire_counter : int;

        public function Game()
        {
            level1=new Level1(this.stage);

            player = new Player  ;
            addChild(player);
            player.y = 600;
            bullets_arr = [];
            addEventListener(Event.ENTER_FRAME,Main);
            stage.addEventListener(MouseEvent.MOUSE_DOWN,mouseDownHandler);
            stage.addEventListener(MouseEvent.MOUSE_UP,mouseUpHandler);
        }

        function mouseDownHandler($e:MouseEvent):void
        {
            fire_on = true;
        }

        function mouseUpHandler($e:MouseEvent):void
        {
            fire_on = false;
            fire_counter = 0;
        }

        function fire():void
        {
            bullet = new Bullet  ;
            addChild(bullet);
            bullet.x = player.x;
            bullet.y = player.y - 32;
            bullets_arr.push(bullet);
        }

        public function Main(e: Event):void
        {
            player.x = mouseX;

            if (bullets_arr)
            {
                for (var m:int = 0; m < bullets_arr.length; m++)
                {
                    bullets_arr[m].y -=  20;

                    if(level1.enemies_arr)
                    {   
                        for (var n:int = 0; n < level1.enemies_arr.length; n++)
                        {
                            if (bullets_arr[m])
                            {
                                if (level1.enemies_arr[n])
                                {
                                    if (level1.enemies_arr[n].hitTestObject(bullets_arr[m]))
                                    {
                                        if(bullets_arr[m].parent)
                                        {
                                            bullets_arr[m].parent.removeChild(bullets_arr[m]);
                                            bullets_arr.splice(bullets_arr[m],1);
                                            level1.enemies_arr[n].DoDamage(10);
                                        }
                                    }
                                }
                            }
                        }
                    }
                }
            }

            if(fire_on)
            {
                fire_counter++;
                if(fire_counter == 01)
                {

                    fire();
                }
                else if(fire_counter >5)
                {
                    fire_counter =0;
                }
            }
        }
    }
}




package  {

    import flash.display.MovieClip;
    import flash.display.Stage;
    import flash.events.Event;

    public class Level1 extends MovieClip{

        var i:int;
        var j:int;
        var frame :int;
        public var enemy:Enemy;
        public var enemies_arr:Array;


        public function Level1(target:Stage) 
        {
            frame = 0;
            enemies_arr = [];

            for (var i:int = 0; i < 3; i++)
            {
                for (var j:int = 0; j < 3; j++)
                {
                    enemy = new Enemy;
                    enemy.x = j*100 + 260;
                    enemy.y = i*40 - 150;
                    target.addChild(enemy);
                    enemies_arr.push(enemy);
                }
            }
        }
    }
}



package
{
    import flash.display.MovieClip;

    public class Enemy extends MovieClip
    {

        var Health : int;
        var splash:Splash;

        function Enemy()
        {
            Health =30;
        }
        public function DoDamage(Damage:int)
        {
            Health -= Damage;
            if (Health <= 0)
            {
                Die();
            }
        }
        public function Die()
        {
            if(this.parent)
            {
                this.parent.removeChild(this);

                //HERE IS THE ERROR
                Game.level1.enemies_arr.splice(this,1);
            }
        }
    }
}

Upvotes: 0

Views: 1721

Answers (2)

Panzercrisis
Panzercrisis

Reputation: 4750

The syntacitical problem you're running into is that you're trying to get level1 from the class Game, when level1 is an instance variable, not a static variable. As an instance variable, level1 is a completely different variable for each instance of game, so if you simply say Game.level1, the compiler wonders, "Which Game?"

To change this, you could simply change level1 into a static variable, by changing this:

public var level1:Level1;

to this:

public static var level1:Level1;

That way the variable would be the same across all instances, and you shouldn't have any trouble accessing it on this line:

Game.level1.enemies_arr.splice(this,1);

I will say though that there could be issues here with certain design principles (it may be that you should use callbacks or signals or something for modularity), but the quick-and-easy fix is to just add the word static to level1's declaration.

Upvotes: 1

Pan
Pan

Reputation: 2101

You should call level1 on the Game instance.

In a simple way, you could define the Game as Singleton

public class Game extends MovieClip {

   private static var _instance:Game;

   public static function getInstance():Game {

      if (_instance == null) {

           _instance = new Game();
      }

      return _instance ;

   }
}

So the Die function will be like this

   public function Die()
    {
        if(this.parent)
        {
            this.parent.removeChild(this);

            //HERE IS THE ERROR
            Game.getInstance().level1.enemies_arr.splice(this,1);
        }
    }

Upvotes: 1

Related Questions