views:

707

answers:

3

When I try to access some of the private properties of the document class from another class, it outputs this error:

1119: Access of possibly undefined property _player through a reference with static type flash.display:Stage.

Here's the code from the document class:

    package 
{
    import flash.display.MovieClip;
    import flash.events.Event;
    import flash.events.KeyboardEvent;
    import flash.utils.Timer;
    import flash.events.TimerEvent;
    import flash.ui.Keyboard;
    import collision;
    import player;
    import ground;

    public class engine extends MovieClip
    {
     public var _player:player;
     private var _ground:ground;
     private var _collision:collision;
     private var _right:Boolean;
     private var _space:Boolean;
     private var _left:Boolean;
     private var _touchGround:Boolean;
     private var _jump:Boolean;
     private var _jumpVel:int;
     private var _q:int;
     private var _vx:int;
     private var _vy:int;

     public function engine()
     {
      _player = new player();
      _ground = new ground();
      _collision = new collision();
      addChild(_player);
      addChild(_ground);
      _player.x = stage.stageWidth/2 - _player.width/2;
      _player.y = stage.stageHeight/2 - _player.height/2;
      _ground.x = stage.stageWidth/2 - _ground.width/2;
      _ground.y = stage.stageHeight/2 - _ground.height/2;
      _ground.y += 150;
      _ground.x += 300;
      _q = 0;
      stage.addEventListener(Event.ENTER_FRAME, enterFrame);
      stage.addEventListener(KeyboardEvent.KEY_DOWN,keyDownHandler);
      stage.addEventListener(KeyboardEvent.KEY_UP,keyUpHandler);
     }
     private function enterFrame(e:Event) 
     {
      if(_right)
      {
       if(_vx > 15) 
       {
        _vx = 15;
       }
       _vx += 2;
      }
      if(_left) 
      {
       if(_vx < -15)
       {
        _vx = -15;
       }
       _vx -= 2;
      }
      if(_space && _touchGround)
      {
       _jump = true;
      }
      if(_jump)
      {
       _jumpVel = 20 - _q;
       if(_q == 20)
       {
        _q = 0;
        _jumpVel = 0;
        _jump = false;
       }
       else
       {
        _ground.y += _jumpVel;
        _q ++;
       }
      }
      _collision.detectCollisions();
      _ground.x -= _vx;
      _ground.y += _vy;
      if(_vx > 0)
      {
       _vx--;
       if(_vx < 0)
       {
        _vx = 0;
       }
      }
      else if(_vx < 0)
      {
       _vx++;
       if(_vx > 0)
       {
        _vx = 0;
       }
      }
      if(_vy > 0) 
       {
        _vy = 0;
       }
      else if(_vy < -10) 
       {
        _vy = -10;
       }
       trace(_vy);
     }

     private function keyDownHandler(e:KeyboardEvent)
     {
      if(e.keyCode == Keyboard.RIGHT)
      {
       _right = true;
      }
      if(e.keyCode == Keyboard.LEFT) 
      {
       _left = true;
      }
      if(e.keyCode == Keyboard.SPACE)
      {
       _space = true;
      }
     }
     private function keyUpHandler(e:KeyboardEvent)
     {
      if(e.keyCode == Keyboard.RIGHT)
      {
       _right = false;
      }
      if(e.keyCode == Keyboard.LEFT) 
      {
       _left = false;
      }
      if(e.keyCode == Keyboard.SPACE)
      {
       _space = false;
      }

     }
    }
}

Here's the code from the 'collision' class.

package
{

    import flash.display.MovieClip;
    import player;
    import engine;

    public class collision extends MovieClip
    {

    private var _playerCol:player = engine._player;


     public function collision()
     {
     }
     public function detectCollisions():void
     {
      _playerCol.y += 7;
     }
    }
}

I'm trying to access the property '_player' from the collision class, but am getting an error.

+1  A: 

Root._player doesn't exist. Try accessing it via the engine class.

So, if an engine object exists at the root and is called _engine, you can access _player like the following:

var plyr:player = _engine._player;

EDIT: The collision class doesn't "know" about the engine class; they both exist separately from one another so there's no way to get them to communicate with each other without doing something different. One method, mentioned in comments, is to make the _player property static in engine. So

public static var _player:player;

Another way would be to make the engine class a singleton (as mentioned in another answer).

Another way would be to pass the instance of the engine class to the collision class; that way the collision class is able to "see" the instance variables (properties) available in engine. To do that, you could do something like:

// do this inside the engine constructor
_collision = new collision();
_collision._engine = this;

(Collision should have a var called _engine:engine, to do this, of course.)

You may want to step back from your design and think about how each part should interact with one another. It's possible that there's a different way to do things which will make each object better able to communicate with one another (or, by separating concerns, take responsibility for what each class is supposed to do without directly interacting with other classes).

Michael Todd
Thanks for the answer. Actually, engine is the name of the document class, I should have clarified that. I'm trying to access the _player property within engine from 'collision'. Either way, I tried what you said to do, by creating a property in the collision class that references the _player property in engine, but i'm still getting the error. I'll update the code in the question so you can see what I did. Thanks again for the answer though.
Miles
make _player static. public static var _player:Player; Then you'll be able to use it.
bhups
+1  A: 

If you want to go a little further with a slighly more advanced approach, you can also implement your Engine class as a singleton (there is a nice flash example here).

Making your engine class singleton means that you make sure there will be only one instance of the engine class in your memory and there only will be an instance until a part of your application needs it. You can access all the properties of a Singleton in a static manor.

Accessing the player property would then come down to:

private var _playerCol:player = Engine.instance._player;

The advantage is that now you can access all the public functions and variables of your Engine class easily.

The singleton pattern is used in allot of Flash libraries and applications, so it could be worth the time to explore them a little.

Les
+1  A: 

At the moment you are trying to access _player as if it is a static member of the Engine class. You could make the _player static but that is messy in my opinion. A better and more OO way would be to pass a reference into the constructor:

private var _engine:Engine
private var _playerCol:player;
public function collision(engine:Engine){        

   _engine = engine;
   _playerCol = _engine._player
}

and so in your Doc class you would have this line

_collision = new collision(this);

PS. As a tip classes should really have a capital at the start, and if a variable is going to be public remove the underscore, otherwise leave the variable as private and create public properties for it.

Allan
Hey, that worked like a charm. Thanks a ton.
Miles