所以,我目前正在 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 的菜鸟,我不知道是否有更有效的方法...
我真的尝试过优化这段代码,但每次我这样做时,宠物都会卡在单个动画中,或者变得疯狂并快速改变动画。
请记住,我的 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.