【问题标题】:MovieClip timeline animations wont play across classes - Flash GameMovieClip 时间线动画不会跨类播放 - Flash 游戏
【发布时间】:2013-09-15 20:43:25
【问题描述】:

第一个问题。请温柔一点。

我正在制作一个简单的(我希望是)键盘控制的游戏角色动画剪辑。 Movieclip 有五个帧,每个帧内部都有一个简单的动画,用于播放玩家按下箭头键、向上、向下、稳定等时的动画。

我在主应用程序类文件中制作了一个简单的原型,它运行良好。我还跟踪了 currentFrame 和 totalFrames,这也是正确的。按下键时,它会播放正确的帧,并显示总帧数为 5。太好了!

但是我想制作一个多关卡游戏,所以将应用程序类用作关卡切换器,每个关卡和对象都是它自己的类。在此迁移期间,MovieClip 停止工作。它可以很好地添加到舞台上,并且可以使用箭头键移动,但不会播放单个动画。它只是在五个关键帧中的每一个中闪烁。 另外,当我跟踪它时,它说 currentFrame 是 0 (?) 而 totalFrames 是 1 (?)

它也不会被 .stop 或 .gotoAndPlay 控制。

请帮忙!

这是运行良好的单类版本。

package
{
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;

[SWF(width="650", height="450",backgroundColor="#FFFFFF", frameRate="60")]

public class CharacterMovieclip extends MovieClip
{
    //Create and initialize the vx and vy variables
    public var vx:int = 0;
    public var vy:int = 0;                  


    [Embed(source="../swfs/characterRes.swf", symbol="Character")]
    public var Character:Class;
    public var character:MovieClip = new Character();


    public function CharacterMovieclip()
    {

        //Add Character
        stage.addChild(character);
        character.x = 200;
        character.y = 100;
        character.gotoAndStop(1);

        //Add the event listeners
        stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
        stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler);     
        stage.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
    }
    public function keyDownHandler(event:KeyboardEvent):void
    {
        if (event.keyCode == Keyboard.LEFT)
        {
            vx = -5;
            character.gotoAndStop(4);
        }
        else if (event.keyCode == Keyboard.RIGHT)
        {
            vx = 5;
            character.gotoAndStop(5);
        }
        else if (event.keyCode == Keyboard.UP)
        {
            vy = -5;
            character.gotoAndStop(2);
        }
        else if (event.keyCode == Keyboard.DOWN)
        {
            vy = 5;
            character.gotoAndStop(3);
        }
    }
    public function keyUpHandler(event:KeyboardEvent):void
    {
        if (event.keyCode == Keyboard.LEFT 
            || event.keyCode == Keyboard.RIGHT)
        {
            vx = 0;
            character.gotoAndStop(1);
        } 
        else if (event.keyCode == Keyboard.DOWN 
            || event.keyCode == Keyboard.UP)
        {
            vy = 0;
            character.gotoAndStop(1);
        } 
    }
    public function enterFrameHandler(event:Event):void
    {   
        //Move the player 
        character.x += vx 
        character.y += vy;
        trace(character.currentFrame);
        trace(character.totalFrames);
        trace(character.x);

    }   

 }
}

但是,一旦我尝试了几节课,这一切都变得糟糕透顶。这是字符类。

package
{
import flash.display.DisplayObject;
import flash.display.MovieClip;

public class Character extends MovieClip
{
    [Embed(source="../swfs/characterRes.swf", symbol="Character")]
    private var CharacterImage:Class;

    //Private properties
    private var _characterImage:DisplayObject = new CharacterImage();
    private var _character:MovieClip = new MovieClip();

    //Public properties
    public var vx:int = 0;
    public var vy:int = 0;

    public function Character()
    {
        _character.addChild(_characterImage);
        this.addChild(_character);  
    }
 }
}

然后将角色对象添加到 LevelOne 类中

package
{
import flash.display.Sprite;
import flash.display.DisplayObject;
import flash.display.MovieClip;
import flash.events.Event;
import flash.events.KeyboardEvent;
import flash.ui.Keyboard;

public class LevelOne extends Sprite
{
    //Declare the variables to hold
    //the game objects
    private var _character:Character;
    private var _background:Background;

    //A variable to store the reference
    //to the stage from the application class
    private var _stage:Object;

    public function LevelOne(stage:Object)
    {
        _stage = stage; 
        this.addEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
    }
    private function addedToStageHandler(event:Event):void
    {
        startGame();
        this.removeEventListener(Event.ADDED_TO_STAGE, addedToStageHandler);
    }
    private function startGame():void
    {
        //Create Game Objects
        _character = new Character();
        _background = new Background();

        //Add them to stage
        this.addChild(_background);
        _background.x = 0;
        _background.y = 0;

        this.addChild(_character);
        _character.x = 300;
        _character.y = 50;
        _character.gotoAndStop(1);


        //Event listeners
        _stage.addEventListener(KeyboardEvent.KEY_DOWN, keyDownHandler);
        _stage.addEventListener(KeyboardEvent.KEY_UP, keyUpHandler); 
        this.addEventListener(Event.ENTER_FRAME, enterFrameHandler);
    }
    private function enterFrameHandler(event:Event):void
    {   
        //Move the game character and check its stage boundaries
        _character.x += _character.vx; 
        _character.y += _character.vy;
        checkStageBoundaries(_character);

                    trace(_character.currentFrame);
        trace(_character.totalFrames);
        trace(_character.x);
    }
    private function checkStageBoundaries(gameObject:MovieClip):void
    {
        if (gameObject.x < 50)
        {
            gameObject.x = 50;
        }
        if (gameObject.y < 50)
        {
            gameObject.y = 50;
        }
        if (gameObject.x + gameObject.width > _stage.stageWidth - 50)
        {
            gameObject.x = _stage.stageWidth - gameObject.width - 50;
        }
        if (gameObject.y + gameObject.height > _stage.stageHeight - 50)
        {
            gameObject.y = _stage.stageHeight - gameObject.height - 50;
        }
    }
    private function keyDownHandler(event:KeyboardEvent):void
    {
        if (event.keyCode == Keyboard.LEFT)
        {
            _character.vx = -5;
            _character.gotoAndStop(4);
        }
        else if (event.keyCode == Keyboard.RIGHT)
        {
            _character.vx = 5;
            _character.gotoAndStop(5);
        }
        else if (event.keyCode == Keyboard.UP)
        {
            _character.vy = -5;
            _character.gotoAndStop(2);

        }
        else if (event.keyCode == Keyboard.DOWN)
        {
            _character.vy = 5;
            _character.gotoAndStop(3);
        }
    }
    private function keyUpHandler(event:KeyboardEvent):void
    {
        if (event.keyCode == Keyboard.LEFT 
            || event.keyCode == Keyboard.RIGHT)
        {
            _character.vx = 0;
            _character.gotoAndStop(1);
        } 
        else if (event.keyCode == Keyboard.DOWN 
            || event.keyCode == Keyboard.UP)
        {
            _character.vy = 0;
            _character.gotoAndStop(1);
        }
    }

}
}

而levelOne被Main应用类添加到stage中。

package
{
import flash.display.Sprite;
import flash.events.Event;
import flash.display.MovieClip;

[SWF(width="650", height="450", 
backgroundColor="#FFFFFF", frameRate="60")]

public class Main extends Sprite
{
    private var _levelOne:LevelOne;

    public function Main()
    {
    _levelOne = new LevelOne(stage);
        stage.addChild(_levelOne);  
    }

}
}

在这一切的某个地方,我的 MovieClip 停止播放单个动画。它在舞台上,可以用箭头键移动,但不会播放关键帧动画。 (而且trace似乎认为它的播放帧是0,它也只有1帧。)

任何帮助将不胜感激。我的头好痛。

【问题讨论】:

    标签: actionscript-3 flash oop model-view-controller movieclip


    【解决方案1】:

    问题出在您的新 Character 类中。

    让我们看看第一个完美运行的类,您从characterRes.swf 文件中嵌入了symbol="Character",它是您的5 帧影片剪辑。

    现在看第二个类,它被破坏了:你做同样的嵌入,现在你的 5 帧影片剪辑是_characterImage,而不是你创建的 Character 类。从 OOP 的角度来看,在同一个 API 中隐藏实现(库或自定义类中的直接 MovieClip)是正确的决定(在这两种情况下,Character 都在简单的 MovicClip 之外),并且可以有两种解决方案:

    首先 - 尝试为孔类嵌入符号并删除您当前不需要的代码:

    [Embed(source="../swfs/characterRes.swf", symbol="Character")]
    public class Character extends MovieClip
    {
        //Public properties
        public var vx:int = 0;
        public var vy:int = 0;
    
        public function Character()
        {
        }
    }
    

    第二:为 swf 中的 Character 制作 Character 类包装器 - 将其中的所有 MovieClip API 传递给 _character MovieClip:

    package
    {
    import flash.display.DisplayObject;
    import flash.display.MovieClip;
    
    public class Character extends MovieClip
    {
        [Embed(source="../swfs/characterRes.swf", symbol="Character")]
        private var _characterClass:Class;
    
        //Private properties
        private var _character:MovieClip = new _characterClass();
    
        //Public properties
        public var vx:int = 0;
        public var vy:int = 0;
    
        public function Character()
        {
            addChild(_character)
        }
    
        override public function gotoAndPlay(frame:Object, scene:String=null):void
        {
            _character.gotoAndPlay(frame, scene);
        }
        override public function gotoAndStop(frame:Object, scene:String=null):void
        {
            _character.gotoAndStop(frame, scene);
        }
        override public function play():void
        {
            _character.play();
        }
        override public function stop():void
        {
            _character.stop();
        }
    
        //and other methods and getters for currentFrame, totalFrames
     }
    }
    

    第一种方法更简单,第二种方法更灵活,因为它是独立的图形和逻辑 - 所以你将来可以在Character构造函数中传递这个链接并动态加载资产或使用@987654331 @ 类作为加载的 swfs 中不同 MovieClips 的动画控制器。

    【讨论】:

    • 你的救星!!!第一种方法效果很好,动画开始时我几乎哭了。但是第二种方法会在 gotoAndStop 和 gotoAndPlay 覆盖处调用错误。 (1023:不兼容的覆盖。)播放和停止覆盖很好。您知道可能存在什么问题吗?
    • 我在“记事本”中写了这段代码,没有错误检查,错过了scene参数,我修复了它。如果有帮助,请访问答案。
    • 非常感谢!你太棒了。它工作得很好。再次感谢您的宝贵时间。
    猜你喜欢
    • 2014-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-03-29
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多