在 Actionscript 2 中是否有更简单的方法来制作定时动画?

问题描述 投票:0回答:1

所以,我目前正在 Macromedia Flash 8 中制作电子宠物风格的游戏,我需要当前的宠物根据某些动作更改动画,并保持这种方式一定数量的帧,这是我的想法:

var animSpriteBody = 1;
var animSpriteFace = 1;
var animBegin = true;
var animFrames = 0;
var animLoop = 0;
var animCurrent = "default";
var animName = "default";
var animNext = "default";
//
function animation() {
    if (animBegin) {
        switch (animName) {
        case "default" :
            animSpriteBody = 1;
            animSpriteFace = 1;
            animFrames = 0;
            animNext = "default";
            break;
        case "petHead" :
            animSpriteBody = 1;
            animSpriteFace = 4;
            animFrames = 30;
            animNext = "default";
            break;
        case "petBody" :
            animSpriteBody = 6;
            animSpriteFace = 1;
            animFrames = 90;
            animNext = "default";
            break;
        }
    }
}
//
function animate() {
    if (animBegin) {
        pet.body.gotoAndStop(animSpriteBody);
        pet.face.gotoAndStop(animSpriteFace);
        animLoop = animFrames;
        animCurrent = animName;
        animBegin = false;
    }
    if (animLoop != 0) {
        animLoop--;
        if (animCurrent != animName) {
            animLoop = 0;
            animBegin = true;
            break;
        }
    } else {
        animName = animNext;
        animBegin = true;
        break;
    }
}
//
//
//
function onEnterFrame() {
    animation();
    animate();
}

所以,它的作用是,每一帧都会播放“默认”动画,但如果变量“animName”发生变化,它会播放该动画一段定义的时间,然后播放定义的下一个动画,然后继续直到它变回“默认”。

我想知道的是,这太多了吗?因为我真的是 AS2 的菜鸟,我不知道是否有更有效的方法...

我真的尝试过优化这段代码,但每次我这样做时,宠物都会卡在单个动画中,或者变得疯狂并快速改变动画。

animation flash actionscript-2 macromedia
1个回答
0
投票

请记住,我的 AS2 真的(真的!)生锈了,因为该语言本身已经过时了 15 年以上,并且下面的脚本可能无法按原样工作,但原则应该是可靠的。

因此,您需要使一个动画运行给定的帧数,然后恢复到默认状态。这可能并不那么困难:

var targetClip: MovieClip = pet.face;
var basicFrame: Number = 1;
var framesLeft: Number = 0;

function onEnterFrame(): void
{
    if (targetClip._currentframe == basicFrame)
    {
        return;
    }
    
    framesLeft -= 1;
    
    if (framesLeft < 1)
    {
        animate(basicFrame, 0);
    }
}

function animate(frame: Number, count: Number): void
{
    framesLeft = count;
    targetClip.gotoAndStop(frame);
}

由于我们正在解决单个目标,因此使用它非常简单:

function playAnimation(name: String): void
{
    switch (name)
    {
        case "default":
            animate(1, 0);
            break;
        case "petHead":
            animate(4, 30);
            break;
        case "petBody":
            animate(1, 0);
            break;
    }
}

现在的问题是,有两个身体部位必须执行此操作。它们的行为应该完全相同,但又不同。

最明显、最直接的方法是创建变量和方法的精确副本来控制另一部分,但如果有 5 个怎么办? 10? 100?

将相同的代码复制 100 次似乎并不明智,对吧?如果有一种方法可以将这些变量和方法封装到某种典型的包含中,只需处理一次,然后自己完成其余的事情!

您正在寻找的是 OOP——面向对象编程。它允许将上面的代码转换为一种黑匣子,并且您可以创建与需要控制的身体部位一样多的黑匣子:

class BodyPart
{
    // Encapsulated variables.
    private var targetClip: MovieClip = null;
    private var basicFrame: Number = 1;
    private var framesLeft: Number = 0;
    
    // This is constructor. It is called when you create each black box.
    function BodyPart(target)
    {
        targetClip = target;
        
        // This is (probably) the way to address the black box from the body part.
        targetClip.controller = this;
        
        // Since onEnterFrame handler works in MovieClips only,
        // we are going to use that to make it work.
        targetClip.onEnterFrame = onEnterFrame;
    }
    
    private function onEnterFrame(): void
    {
        // As it is called from the MovieClip, "this" variable points
        // to the MovieClip rather then to the BodyPart instance.
        // But we've left a sign there, right?
        var self: BodyPart = this.controller;
        
        // Call the black box method.
        self.onFrame();
        
        // P.S. I am not really sure. The point is, we need to get back
        // to the BodyPart context to be able to access the variables,
        // because they are not in the MovieClip and not available there.
        // If this does not work, you should figure this out on your own.
    }
    
    private function onFrame(): void
    {
        // We are inside the black box now, and its fields (instance variables)
        // should be normally available just by referencing them.
        if (targetClip._currentframe == basicFrame)
        {
            return;
        }
        
        framesLeft -= 1;
        
        if (framesLeft < 1)
        {
            animate(basicFrame, 0);
        }
    }
    
    // Aaaaand, finally, the interface method.
    public function animate(frame: Number, count: Number): void
    {
        framesLeft = count;
        targetClip.gotoAndStop(frame);
    }
}

这就是班级。这些类与框架脚本不同。您应该弄清楚如何使用它们,但据我记得您要创建一个名为“class_name.as”的文件(在我们的例子中它将是“BodyPart.as”,是的,区分大小写)并且将其放入主 *.fla 文件所在的同一文件夹中。

现在,如何使用它:

// This instructs Flash that we are going to use an external class.
import BodyPart;

// Create black boxes for all the body parts.
var Bo: BodyPart = new BodyPart(pet.body);
var Fa: BodyPart = new BodyPart(pet.face);

// Now for each of the part you have an instance of the BodyPart class,
// and each instance has an independent and encapsulated set of
// variables and methods, that run on their own.

function playAnimation(name: String): void
{
    switch (name)
    {
        case "default":
            Fa.animate(1, 0);
            Bo.animate(1, 0);
            break;
        case "petHead":
            Fa.animate(4, 30);
            Bo.animate(1, 0);
            break;
        case "petBody":
            Fa.animate(1, 0);
            Bo.animate(6, 90);
            break;
    }
}

P.S.我不太确定(记住,15年了,生锈了)但是可能有一种简单的方法可以访问类中的onEnterFrame(...)功能:使其成为子类MovieClip 类的。可能会起作用:

class BodyPart extends MovieClip
{
    // Encapsulated variables.
    // ...
    
    // Constructor
    function BodyPart(target)
    {
        targetClip = target;
    }
    
    // If I am right this will be invoked once per frame just like that.
    private function onEnterFrame(): void
    {
        if (targetClip._currentframe == basicFrame)
        {
            return;
        }
        
        framesLeft -= 1;
        
        if (framesLeft < 1)
        {
            animate(basicFrame, 0);
        }
    }
    
    // The rest of the class.
© www.soinside.com 2019 - 2024. All rights reserved.