【问题标题】:Using Buttons with MovieClips contained inside of a State Loop将按钮与包含在状态循环内的 MovieClip 一起使用
【发布时间】:2014-07-04 05:39:19
【问题描述】:

我根据书中的一些示例实现了一个非常简单的状态循环:Jeff 和 Steve Fulton 的“Flash 游戏基本指南”;在这个状态机中,我有一个循环,通过 Enter_Frame 事件将舞台更新为目标 gameState var。

在我的菜单状态中,我有一个按钮,其中包含处于 OVER 状态的 MovieClip,只要按钮处于 OVER 状态,它通常会无限循环播放,但剪辑甚至不会播放一次;我猜这是因为 Enter_Frame 事件每帧放置一个新实例,我的问题是:有没有更好的方法来更新 State 循环仅当 gameState var 发生变化时,或者这听起来像是对问题的错误猜测?

如果这对细节过于模糊,请告诉我,我不确定发布代码 sn-ps 是否真的有助于解决这个问题...... 感谢您的阅读和任何提前回复! 这是代码! :-)

//imports here  
public class Loop extends MovieClip {
    public static const STATE_MMENU:int = 10;
    public static const STATE_OPTIONS:int = 11;
    public static const STATE_NGAME:int = 20;
    public static const STATE_CHARSELECT:int = 21;
    public static const STATE_BATMAP:int = 22;
    public static const STATE_BATSTORY:int = 23
    public static const STATE_BATTLE:int = 30;
    public static const STATE_DOMDICEPHASE:int = 31;
    public static const STATE_ROLLPROCESS:int = 32;
    public static const STATE_WINLOSSPHASE:int = 33;

    public var gameState:int = 0;

    public function Loop():void {

        addEventListener(Event.ENTER_FRAME, gameLoop);
        gameState = STATE_MMENU;
    }

    public function gameLoop(e:Event):void{
        switch(gameState){
            case STATE_MMENU:        mainMenu();            break;
            case STATE_OPTIONS:      optionsMenu();         break;
            case STATE_NGAME:        newGame();             break;
            case STATE_CHARSELECT:   charaSelect();         break;
            case STATE_BATMAP:       battleMap();           break;
            case STATE_BATSTORY:     battleStory();         break;
            case STATE_BATTLE:       battlePhase();         break;
            case STATE_DOMDICEPHASE: domDicePhase();        break;
            case STATE_ROLLPROCESS:  rollProcessPhase();    break;
            case STATE_WINLOSSPHASE: winLossPhase();        break;
        }
}
        //insert functions for phases/states here lol :-0

        public function mainMenu(){
        var titleText:title_gfx = new title_gfx();
        titleText.x = 520;      titleText.y = 150;
        addChild(titleText);

        var newGameSel:newGame_btn = new newGame_btn();
        newGameSel.x = 512;     newGameSel.y = 300;
        addChild(newGameSel);
        //newGameSel.addEventListener(Mouse.MouseEvent.CLICK, newGameButton);

我在 mainMenu() 函数中插入带有影片剪辑的按钮... 再次感谢!

【问题讨论】:

  • 每帧放置一个新实例有点奇怪。也许您可以在 gameState var 更改时分派一个事件,并在该事件的侦听器中更新按钮。如果您需要更多指针,发布一些代码可能会有所帮助。根据您的问题,我无法弄清楚您在 enter_frame 事件中在做什么。
  • 我贴了一些代码!感谢您的关注! :-D 顺便说一句,如果我把那个按钮放在舞台上,它会按预期工作,几秒钟后就会变得迟钝,所以我不太确定这是我在搞砸 PC。下来或什么大声笑
  • 如何在 mainMenu 中添加按钮?如果它们尚未实例化,您可能应该只实例化它们一次。按钮变得迟缓有点奇怪。按钮中有代码吗?
  • 在代码中我刚刚添加了一个到目前为止主菜单的示例,我只是像正常编辑.x 和.y 一样实例化按钮,将其添加到显示列表中,我是有点想知道我是否不应该仅在没有实例的情况下才发生这种情况?这是否可以通过 for 循环实现,也许我可以让第一次迭代触发 if 语句检查实例是否存在?按钮中没有代码。我尽量不在时间轴上编码。我想这只是我试图真正学习一些东西,而不是只是懒惰大声笑

标签: actionscript-3 flash


【解决方案1】:

您基本上是在每帧添加一个新的 titleText 和 newGameSel。如果您的 FPS 为 24,则每秒为每个按钮添加 24 个动画剪辑。您可以保留一个全局布尔变量,例如 isMainMenuCreated,它最初为 false,并在第一次实例化按钮后将其设置为 true。

 public var gameState:int = 0;
 public var isMainMenuCreated:Boolean = false;

 //rest of your code

 public function mainMenu():void { 
    if(isMainMenuCreated) return;

    //code for button instantiation and placing
    isMainMenuCreated = true;
 }

这是一种方法。另一种方法是删除 mainMenu 函数中的 ENTER_FRAME 事件侦听器,并在单击新游戏按钮后重新添加它。后者的性能会更高,因为您只在需要时才保持游戏状态循环。当播放器什么都不做时,您实际上并不需要每秒 24 次更新主菜单屏幕。

要考虑的另一件事是,您是否真的需要在游戏中使用游戏循环。有些游戏,比如动作游戏,需要实时更新图形(想想平台游戏)需要一个游戏循环。指向和点击游戏不需要游戏循环。

【讨论】:

  • 想一想真的很有趣...但我想确实不是这样,因为所有状态更改都是由用户与按钮的交互触发的,除了少数计时器之外,没有任何事情独立发生。 .. 如果没有游戏循环,我不是必须按程序进行游戏吗?我知道我可以制作我想要在时间轴上制作的带有场景等的游戏,但我试图让这个游戏更多一点......我不知道我猜是否合乎逻辑?我想我需要回到绘图板上,非常感谢您的帮助!
猜你喜欢
  • 2015-01-23
  • 2016-03-07
  • 2022-08-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-07-06
  • 2014-04-11
  • 2012-06-08
相关资源
最近更新 更多