设置器/获取器 (AS3)

Setters / Getters (AS3)

我有一个带有一个按钮的菜单页,通过添加和删除子项可以转到另一页。很简单的。从这里我有一个页面,允许点击许多建筑物,打开一个新页面(一个迷你游戏页面)。我已经用 setter 和 getters 完成了这个,如下所示:

Main.as(从 MainPage 中的 getter 获取值)

        public function onEnterFrame(event:Event):void
    {
        //Swaping pages with a getter and setter
        if (mainPage.stage && mainPage.getNextLevel() == 1)
        {
            addChild(miniGameOne);
            removeChild(mainPage);
        }

        if (miniGameOne.stage && miniGameOne.getNextLevel() == 2)
        {
            addChild(mainPage);
            removeChild(miniGameOne);
        }
}

MainPage.as(包括所有建筑物)

public function onAddedToStage(event:Event):void
    {
        doctor.addEventListener(MouseEvent.CLICK, onDoctorClick);
    }

    public function onDoctorClick(event:MouseEvent):void
    {
        setNextLevel(1);
    }

    public function setNextLevel(passLevel:int)
    {
        nextLevel = passLevel;
    }

    public function getNextLevel():int
    {
        return nextLevel;
    }

MiniGameOne.as 这里说的是当小游戏完成后将页面设置为2,即添加MainPage.as并删除MiniGameOne.as

public function onEnterFrame(event:Event):void
    {
        healthbar.meter.scaleY = life/100;

        if (life < 1)
        {
            life = 1;

            //Make sure it isn't visiable
            healthbar.meter.alpha = 0;

            //New Function
            gameComplete();
        }
    }

    public function gameComplete()
    {
        //Level Complete, Set new Level
        setNextLevel(2);
    }

我有一个问题,当我进入一个页面(点击建筑物)然后return到原始页面并点击同一建筑物我无法再次打开同一页面,谁能解释一下这里发生了什么?谢谢

发生这种情况是因为您已经为 MainPageMiniGameOne class 定义并正在检查 nextLevel。当您将 miniGameOne 实例中的级别更改为 2 时,它将是 2 直到您将其更改为其他数字。 从那时起你有:

mainPage.getNextLevel() == 1miniGameOne.getNextLevel() == 2

所以在你的 enterFrame() 中,两个条件都成立,你的 miniGameOne 确实被添加到舞台上,但在同一帧中它被删除,你 mainPage 被再次添加。

作为最快的解决方法,您可以更改行:

if (miniGameOne.stage && miniGameOne.getNextLevel() == 2)

else if (miniGameOne.stage && miniGameOne.getNextLevel() == 2)

但这可能只会让你的小游戏停留到下一帧,所以当你回到 mainPage 时需要重置 nextLevel 值:

if (miniGameOne.stage && miniGameOne.getNextLevel() == 2){
    addChild(mainPage);
    removeChild(miniGameOne);
    miniGameOne.setNextLevel(0);
}

但是你这里的做法很糟糕。

最重要的是,仅更改程序中您实际需要在每一帧上更新的那部分帧事件,否则您真的没有任何其他方法来确定何时应该更新已更新

其次,不要重复存储应用状态的变量。

有很多方法可以解决这个问题,但我将展示一种可能最接近您已有方法的方法:

1 在您的 Main class 中定义关卡状态,将您的关卡存储在 array/vector/whatever 中,将 main 实例传递给您的关卡。

/**Current level**/
private var cl:uint = 0;
/**All levels veiews that could be shown.**/
private var levels:Array = [mainPage, miniGameOne];

public function Main() {
    for each (var l in levels) l.main = this;
}

public function get level():uint { return cl; }
public function set level(l:uint) {
    this.removeChild(levels[cl]);
    this.addChild(levels[cl = l]);
}

2 在关卡 classes 中为主实例定义 setter,您现在可以更改存储在主实例中的当前关卡。

private var m:Main;
public function set main(v:Main):void { m = v; }


public function onDoctorClick(event:MouseEvent):void{
    m.level = 1;
}

public function gameComplete(){
    //Level Complete, Set new Level
    m.level = 0;
}

3 所有其他代码,尤其是关于帧事件的代码,都可以删除。

解决方案可能不理想,但我希望它能给你一些想法。