对象未定义但它似乎已定义 actionscript

Object Undefined but it seems to be Defined actionscript

首先,我对编码还是个新手,所以请放轻松。在我显示代码之前进行一些回溯。我有一本关于如何使用 ActionScript 3 制作游戏的书,唯一的问题是它主要是在假设你同时使用 Photoshop 和 Flash Builder 而不是 adobe animate/flash 的情况下工作的。所以它让你做一些事情,比如嵌入图像,我不确定如何更改代码来定义图像,这正是问题所在。但是与此同时,未定义访问的阶段即将到来!我真的,我的意思是舞台怎么可能是未定义的......无论如何,这是未定义属性之一的示例:

///
class BetterScrolling extends Sprite 
    var ForegroundImage: Class;
    var foregroundImage: DisplayObject = ForegroundImage();
    var foreground = ForegroundImage;
///

中间有一些代码。

///
function BetterScrolling(){
     foreground.x = -((foreground.width - stage.width) / 2);
    foreground.y = -((foreground.height - stage.height) / 2);
    }

///

这段代码的重点是创建一个滚动背景。然而,我有点复杂,因为我有一个 X 和一个 Y 变量,但除了我的前景之外,我还有一个减慢的背景。我现在 link 完整的代码,http://pastebin.com/WHg9DGsB 我对代码所做的每一次更改都是有原因的,即使它是一个愚蠢的...所以请不要被我确定存在的其他错误分散了注意力...现在只是定义我的图像。

有许多问题会阻止您的代码编译。

  1. 当您的 class 加载时,舞台不可用。当应用程序初始化时(甚至在屏幕上看到任何内容之前),任何不在函数内部的代码都将 运行。你的错误是因为这些行:

    stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
    stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandHandler);
    stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
    

    当阶段尚不存在时,这些行在您的 class 声明中浮动。

    您要做的是将该代码(以及任何不是变量或函数定义的代码)移动到函数中。如果您希望它立即 运行,请将其放入您的构造函数中(该函数的名称与您的 class 相同)。然而,该阶段在您的构造函数中并不总是可用,因此为了安全起见,您应该执行以下操作:

    function BetterScrolling() {
        if(!stage){
            this.addEventListener(Event.ADDED_TO_STAGE, stageReady);
        }else{
            stageReady();
        }
    }
    
    function stageReady(e:Event = null):void {
        stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
        stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandHandler);
        stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
    
        //any other code that needs the stage and should run as soon as possible
    }
    
  2. 您有一堆似乎不属于任何地方的括号和代码。第 45 - 71 行将无法正确编译。很可能,您也希望在 constructor/stage 就绪方法中使用该代码,因此将其添加进去,您将得到如下内容:

    function BetterScrolling() {
        if(!stage){
            this.addEventListener(Event.ADDED_TO_STAGE, stageReady);
        }else{
            stageReady();
        }
    }
    
    function stageReady(e:Event = null):void {
        stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
        stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandHandler);
        stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
    
        foreground.x = -((foreground.width - stage.width) / 2);
        foreground.y = -((foreground.height - stage.height) / 2);
    
        background.x = -((background.width - stage.width) / 2);
        background.y = -((background.height - stage.height) / 2);
    
        cloud.x = -((cloud.width - stage.width) / 2);
        cloud.y = -((cloud.height - stage.height) / 2);
    
        character.x = 370
        character.y = 320
    
        rightInnerBoundary = (stage.stageWidth / 2) + (stage.stageWidth / 4)
        leftInnerBoundary = (stage.stageWidth / 2) + (stage.stageWidth / 4)
        topInnerBoundary = (stage.stageHeight / 2) + (stage.stageHeight / 4)
        bottomInnerBoundary = (stage.stageHeight / 2) + (stage.stageHeight / 4)
    }
    
  3. 您有空白的变量 class,然后您尝试实例化它们

    var BackgroundImage: Class;
    var backgroundImage: DisplayObject = BackgroundImage();
    

    这将导致 运行 时间错误,因为 BackgroundImage 是 null/undefined。很可能,您想将 FlashPro 中的库对象导出为 class?为此,right/alt 单击库中的相关对象,然后转到其属性。勾选 'export for actionscript' 并给它一个 class 名称。在这种情况下,将其称为 BackgroundImage。然后你将上面的代码替换为:

    var backgroundImage:BackgroundImage = new BackgroundImage();
    

    顺便说一句,只声明引用其他 objects/classes 的 class 变量并在构造函数中实例化它们会更安全。要像这样更改它,请将上面的行更改为:

    var backgroundImage:BackgroundImage;
    

    然后在你的构造函数中,执行:

    backgroundImage = new BackgroundImage();
    

首先,DisplayObject.stage 属性 仅在相关 DisplayObject 附加到显示列表时 定义。作为一般政策,从不 尝试访问构造函数中的阶段。你需要订阅一个特定的事件,它会告诉你什么时候舞台真的可用。

public function IWannaStage()
{
    // WRONG
    x = stage.stageWidth >> 1;
    y = stage.stageHeight >> 1;

    // RIGHT
    if (stage) onStage();
    else addEventListener(Event.ADDED_TO_STAGE, onStage);
}

private function onStage(e:Event = null):void
{
    removeEventListener(Event.ADDED_TO_STAGE, onStage);

    // Stage is really available from this point on.
    x = stage.stageWidth >> 1;
    y = stage.stageHeight >> 1;
}

其次,我认为您试图错误地创建实例。如果 ForegroundImage 是 class,则:

A = ForegroundImage; // Wrong, you assign the reference to the class.
B = ForegroundImage(); // Wrong, this actually is type casting.
C = new ForegroundImage(); // Correct way to create a new instance of a class.
D = new ForegroundImage; // If constructor does not need any arguments you can omit brackets.