Actionscript 3:如何访问文档类的属性?

时间:2009-11-14 20:24:29

标签: actionscript-3

当我尝试从另一个类访问文档类的某些私有属性时,它会输出以下错误:

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

以下是文档类中的代码:

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

        }
    }
}

以下是'碰撞'类的代码。

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

我正在尝试从碰撞类访问属性'_player',但是收到错误。

3 个答案:

答案 0 :(得分:3)

目前您正在尝试访问_player,就像它是Engine类的静态成员一样。您可以使_player静态,但这可能会导致代码异味。一种安全的方法是将引用传递给构造函数:

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

   _engine = engine;
   _playerCol = _engine._player
}        

所以在你的Doc课程中你会有这一行

_collision = new collision(this);

PS。由于提示类在开始时应该确实有一个资本,如果变量将是公共的,则删除下划线,否则将变量保留为私有并为其创建公共属性。此外,您可能想要考虑更改您的结构,因为它有点笨拙。我建议您查看组件实体系统。

答案 1 :(得分:2)

Root._player不存在。尝试通过引擎类访问它。

因此,如果根目录中存在引擎对象并且名为_engine,则可以访问_player,如下所示:

var plyr:player = _engine._player;
编辑:碰撞类没有“知道”引擎类;它们彼此分开存在,所以在没有做出不同的事情的情况下,没有办法让它们彼此沟通。注释中提到的一种方法是在引擎中使_player属性为静态。所以

public static var _player:player;

另一种方法是使引擎类成为单例(如另一个答案中所述)。

另一种方法是将引擎类的实例传递给碰撞类;这样,碰撞类就能够“看到”引擎中可用的实例变量(属性)。为此,您可以执行以下操作:

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

(碰撞应该有一个名为_engine:engine的var,当然要做到这一点。)

您可能希望退出设计并思考每个部分应如何相互作用。有可能有一种不同的方式来做事情,这将使每个对象更好地相互通信(或者,通过分离关注点,对每个类应该做什么负责,而不用直接与之交互其他课程。)

答案 2 :(得分:2)

如果你想稍微采用更高级的方法,你也可以将你的引擎类实现为singleton(有一个很好的flash示例 here )。

使您的引擎类单例意味着您确保内存中只有一个引擎类实例,并且在您的应用程序的一部分需要它之前只会有一个实例。您可以在静态庄园中访问Singleton的所有属性。

访问玩家属性将归结为:

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

优点是现在您可以轻松访问Engine类的所有公共函数和变量。

单例模式用于分配Flash库和应用程序,所以值得花些时间来探索它们。