Flash AS3:在 Movieclips 中交换部分

Flash AS3: Swapping Parts within Movieclips

我有一个大约有 10 帧的 Movieclip(级别 1,MC)。每帧都有不同的动画片段(第 2 级、移动跳跃等动画)。在每个 2 级动画片段中,大约有 30 个动画片段符号(3 级、头臂等),每个符号包含大约 100 帧和大约 30-50 个关键帧。每个 3 级符号有大约 10 帧,在每一帧上我都有一个特定的皮肤图形。

我将所有 2 级和 3 级符号实例都命名为(同一 object 跨时间轴的相同标签),并且我有正确的帧停止();并贴上标签。我也明白,每次我不仅在第 1 级而且在第 2 级进入一个新框架,我必须将所有第 3 级符号重置为所需的框架,因为我之前的设置将在离开框架时被破坏。

我通过 level1.gotoAndStop(level2name) ---> level1.level2.level3.gotoAndStop(skintype) 得到它的工作,然后循环一个令人讨厌的令人讨厌的姿势 X body部分。并且此过程需要在 ENTER_FRAME 事件中执行,因为所有内容都将再次重置。不用说,我真的真的不想这样。

其中一种选择是分解图形,并在我的 1 级 MC 动画片段中放置许多 2 级姿势动画片段(法师被战士第 3 次攻击击中,战士被流氓第 4 次攻击击中...)。我以前就是这么做的。但是对于这个项目,一个简单的计算告诉我,我需要那样制作 200+ 个动画,这是不可行的。我也可以摆脱 1 级 MC 并将姿势保存到数组中,但是 body 部分仍然需要每帧刷新。

我希望能有一个相对快速的修复方法来解决我错过的这个问题,因为它看起来是一个基本功能,我相信很多 Flash 游戏都必须通过它(装扮,或任何带有定制+动画的东西)。然而不知何故,我一直在寻找几天,却找不到治愈方法。 author-time 能够简单地换出符号内的图形以替换整个文件中每个动画的每一帧,这也表明必须有一种更通用的方法来进行这些交换。我希望你能证明我是对的!

我确实有两件事不知道是否应该尝试:1) 将 MC 拖到 frame1(我唯一的框架)上,目前我只有代码。 2) 单独声明每个 body 部分并声明 MC,然后将 MC 的部分 link 分配给这些 body 部分。基本上,我只需要一个可行的方法来防止这些 body 部分在每次动画进入新帧时都被重置,我的 Flash 知识不足以告诉我是否有可能拥有这些 "global graphics bank independent of frames" .

是的,我知道我可能没有以最干净的方式来做这件事,但我只是用视觉效果更好地制作动画,所以虽然我可以从形状开始并使用严格的代码为所有东西制作动画,但我真的很想离开从中。艺术风格在这个项目中非常重要。

更新:现在,我选择了丑陋的路线。每次 MC 更改动画时,我都会:

MovieClip(DisplayObjectContainer(MC.getChildByName(MC.move))).Hand.gotoAndStop(MC.skinname);

并对所有 35 body 个部分重复该操作。事实证明,闪光灯取代了 MC.move 中的所有手部帧,这让生活变得更加轻松。另一种方法是轮询每一帧,但直接后果是 fps 慢得多。相反,现在我只需要在移动发生变化时切换图形。

这行得通,但我知道它会大大降低性能。事实上,它可以降低与实际矢量渲染相同幅度的性能。将交换限制为仅移动更改实际上不是可选的,而是强制性的。

请看这个:http://zdg.ru/tmp/animation.swf
源码可以在这里下载:http://zdg.ru/tmp/animation.fla

如果我没听错你的描述,我用同样的方法做了动画。主时间轴有一个带有字符符号的单帧。角色符号中有一个时间轴,其中有两个动画点 "stand" 和 "jump"。字符由符号"head"、"body"、"left_hand"、"right_hand"、"left_leg"、"right_leg"组成。这些符号中的每一个都是独立动画的。角色动画时间线包含关键帧和补间。所有符号在所有框架中的命名都是一致的。

每个角色部分依次有2帧的时间轴,分别对应皮肤1和皮肤2

如您所见,皮肤在动画过程中并没有被破坏,也没有必要在每一帧都进行校正。

主时间线上的代码是:

var char_body_parts:Array = new Array(
    mv_char.body, mv_char.head, mv_char.left_hand, mv_char.right_hand,
    mv_char.left_leg, mv_char.right_leg
);

var skin_num:int = 1;

mv_char.gotoAndStop("stand");
setSkin(char_body_parts, skin_num);

btn_jump.addEventListener(MouseEvent.CLICK, doJump);
btn_skin.addEventListener(MouseEvent.CLICK, doSkin);

function doJump(evt:MouseEvent):void {
    mv_char.gotoAndPlay("jump");
}

function doSkin(evt:MouseEvent):void {
    skin_num++;
    if (skin_num > 2) skin_num = 1;
    setSkin(char_body_parts, skin_num);
}

function setSkin(parts:Array, skin_num:int):void {
    for (var i:int = 0; i < parts.length; i++) {
        (parts[i] as MovieClip).gotoAndStop(skin_num);
    }
}

==================更新====================
这是更新后的动画:http://zdg.ru/tmp/animation3.swf
源码可以在这里下载:http://zdg.ru/tmp/animation3.fla
现在我的设置和你的一样了。
我有一个 2 帧字符,一帧包含 "stand" 动画片段,另一帧包含 "jump" 动画片段。 事实上,当您为任何动画转到 AndStop 时,皮肤就会丢失。但是您不必每帧都更新它们。您只需要在动画的第一帧更新它们,即在 gotoAndStop("animation") 之后。我仍然有一个 body 零件列表来批量分配皮肤,但现在它们是通过名称访问的。所以主要的代码改动是:

var char_body_parts:Array = new Array(
    "body", "head", "left_hand", "right_hand",
    "left_leg", "right_leg"
);

function setSkin(char:MovieClip, parts:Array, skin_num:int):void {
    for (var i:int = 0; i < parts.length; i++) {
        char.mv_animation.getChildByName(parts[i]).gotoAndStop(skin_num);
    }
}

function setAnimation(char:MovieClip, anim_name:String):void {
    char.gotoAndStop(anim_name);
    setSkin(char, char_body_parts, skin_num);
}

还有两个解决方案,我没有编码,但很容易描述。

  1. 在每个皮肤动画片段的第 1 帧中,添加 gotoAndStop((root as MovieClip).skin_num)。它的工作原理如下:每当皮肤被重置时,它从第 1 帧开始。在第 1 帧它会自动 gotoAndStop 到当前皮肤。所以你不需要做任何其他事情。

  2. 不要将您的动画影片片段放在时间轴中,而是放在同一帧中。将每个动画命名为 "stand"、"jump" 等。切换动画不是通过 gotoAndStop,而是通过使选定的动画可见而其他动画不可见。每次更换皮肤都必须设置一次皮肤。