Actionscript 3.0 补间错误

发布于 2024-08-21 22:25:50 字数 2145 浏览 10 评论 0原文

我正在尝试(到目前为止未成功)以编程方式增加和减少舞台上物体的比例。有一个“增长”按钮 (grow_btn) 和一个“收缩”按钮 (shrink_btn),它们随着时间的推移增加和减少选定对象(redObject、greenObject 或 blueObject)的scaleX 和scaleY 属性。

我遇到的问题似乎是随机的,有时只有一个属性(scaleX或scaleY)会改变,而另一个则不会。此外,补间函数的目标尺寸和原始尺寸无法正确调整。例如:1.0 几乎是舞台上物体的两倍大。

//Imports
import fl.transitions.Tween;
import fl.transitions.easing.*;

//Constants And Variables
const starRotationAngle:Number = 0.5;
const starSpeed:Number = 2;

var moveForward:Boolean = true;
var selectedObject:MovieClip;

//Event Listeners & Functions
star_mc.addEventListener(MouseEvent.CLICK, rotateStar);
function rotateStar(e:MouseEvent):void
    {
    star_mc.rotation += 5;
    }

addEventListener(Event.ENTER_FRAME, starMove);
function starMove(e:Event):void
    {
    if (star_mc.x >= stage.stageWidth + star_mc.width)
        {moveForward = false;}
    else if (star_mc.x <= stage.x - star_mc.width)
        {moveForward = true;}

    if (moveForward == true)
        {
        star_mc.x += starSpeed;
        star_mc.rotation += starRotationAngle;
        }       
        else
        {
        star_mc.x -= starSpeed;
        star_mc.rotation -= starRotationAngle;
        }   
    }

redObject.addEventListener(MouseEvent.CLICK, changeSelectedObjectVariable);
greenObject.addEventListener(MouseEvent.CLICK, changeSelectedObjectVariable);
blueObject.addEventListener(MouseEvent.CLICK, changeSelectedObjectVariable);
function changeSelectedObjectVariable(e:MouseEvent):void
    {
    selectedObject = e.currentTarget as MovieClip;
    }

grow_btn.addEventListener(MouseEvent.CLICK, grow);
function grow(e:MouseEvent):void
    {
    var tweenGrowX:Tween = new Tween(selectedObject, "scaleX", None.easeIn, 1.0, 2.0, 3.0, true);
    var tweenGrowY:Tween = new Tween(selectedObject, "scaleY", None.easeIn, 1.0, 2.0, 3.0, true);
    }

shrink_btn.addEventListener(MouseEvent.CLICK, shrink);
function shrink(e:MouseEvent):void
    {
    var tweenShrinkX:Tween = new Tween(selectedObject, "scaleX", None.easeIn, 2.0, 1.0, 3.0, true);
    var tweenShrinkY:Tween = new Tween(selectedObject, "scaleY", None.easeIn, 2.0, 1.0, 3.0, true);
    }

i'm attempting (so far unsuccessfully) to programatically increase and decrease the scale of an object on stage. there is a Grow button (grow_btn) and a Shrink button (shrink_btn), which increase and decrease the scaleX and scaleY properties of a selected object (either redObject, greenObject or blueObject) over time.

the problem i'm encountering seems random, where sometimes only one of the properties (either scaleX or scaleY) will change while the other does not. additionally, the target and original sizes for the tween functions don't adjust correctly. For example: 1.0 is nearly twice as large as the object onstage.

//Imports
import fl.transitions.Tween;
import fl.transitions.easing.*;

//Constants And Variables
const starRotationAngle:Number = 0.5;
const starSpeed:Number = 2;

var moveForward:Boolean = true;
var selectedObject:MovieClip;

//Event Listeners & Functions
star_mc.addEventListener(MouseEvent.CLICK, rotateStar);
function rotateStar(e:MouseEvent):void
    {
    star_mc.rotation += 5;
    }

addEventListener(Event.ENTER_FRAME, starMove);
function starMove(e:Event):void
    {
    if (star_mc.x >= stage.stageWidth + star_mc.width)
        {moveForward = false;}
    else if (star_mc.x <= stage.x - star_mc.width)
        {moveForward = true;}

    if (moveForward == true)
        {
        star_mc.x += starSpeed;
        star_mc.rotation += starRotationAngle;
        }       
        else
        {
        star_mc.x -= starSpeed;
        star_mc.rotation -= starRotationAngle;
        }   
    }

redObject.addEventListener(MouseEvent.CLICK, changeSelectedObjectVariable);
greenObject.addEventListener(MouseEvent.CLICK, changeSelectedObjectVariable);
blueObject.addEventListener(MouseEvent.CLICK, changeSelectedObjectVariable);
function changeSelectedObjectVariable(e:MouseEvent):void
    {
    selectedObject = e.currentTarget as MovieClip;
    }

grow_btn.addEventListener(MouseEvent.CLICK, grow);
function grow(e:MouseEvent):void
    {
    var tweenGrowX:Tween = new Tween(selectedObject, "scaleX", None.easeIn, 1.0, 2.0, 3.0, true);
    var tweenGrowY:Tween = new Tween(selectedObject, "scaleY", None.easeIn, 1.0, 2.0, 3.0, true);
    }

shrink_btn.addEventListener(MouseEvent.CLICK, shrink);
function shrink(e:MouseEvent):void
    {
    var tweenShrinkX:Tween = new Tween(selectedObject, "scaleX", None.easeIn, 2.0, 1.0, 3.0, true);
    var tweenShrinkY:Tween = new Tween(selectedObject, "scaleY", None.easeIn, 2.0, 1.0, 3.0, true);
    }

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

策马西风 2024-08-28 22:25:50

将补间对象移到侦听器函数之外,并且不要对grow() 和shrink() 使用不同的补间对象。我认为你的问题是你在应用新的补间之前没有销毁以前的补间,所以它们会互相踩踏。

var tweenScaleX:Tween;
var tweenScaleY:Tween;

您的grow()和shrink()方法应该都使用这两个补间变量,而不是在方法中创建补间变量(这使得它们在函数完成时可用于垃圾回收即使补间尚未完成)。当您调用grow()时,tweenScaleX和tweenScaleY都被分配了新的补间对象。如果在grow()完成之前单击收缩按钮,则shrink()方法将开始,并且在grow()期间分配的补间实质上将被“销毁”,以便为新的收缩补间腾出空间。

此外,您的问题可能与 AS3 的垃圾收集有关。提供的第一个答案表示代码工作正常,但由于性能和内存可用性的原因,垃圾收集因计算机而异。内存密集型 Flash 应用程序将更频繁地执行垃圾收集,但在具有大量内存和性能的机器上,它可能根本不会发生。正如我上面提到的,由于您是在grow()和shrink()函数内创建补间变量,因此它们的作用域仅在该函数内。当函数完成时,函数内部创建的变量就可以进行垃圾回收。如果发生垃圾回收,即使这些补间尚未完成其补间(并且“完成”事件永远不会触发),您的补间对象也将被销毁。通过将补间变量移到示例中的函数之外(或将它们设为类中的类成员),您可以将作用域移至父对象,以便只要父对象存在,补间就会存在。垃圾收集的变化是从 AS2 到 AS3 最重要但可能最不被理解的变化之一。作为开发人员,您可能拥有大量 RAM,因此垃圾收集并不频繁(或者只要有足够的内存来容纳所有内容,就不存在),但在生产中,您的用户可能会遇到奇怪的行为,因为项目被垃圾收集以释放RAM,但这些项目在其他地方被引用,因为您认为它们仍然存在并且代码适合您。这是 AS3 开发人员经常看到的一个抱怨,他们指责 Adob​​e 做出的更改导致 Flash 不再独立于平台,但这是一项需要添加的重要功能,以使 Flash 更加强大。

Move the tween objects outside of the listener functions, and don't use different tween objects for both grow() and shrink(). I think your problem is that you are not destroying a previous tween before applying a new tween so they are stepping on each other.

var tweenScaleX:Tween;
var tweenScaleY:Tween;

Your grow() and shrink() methods should both use these two tween variables instead of creating tween variables within the method (which makes them available for garbage collection when the function has completed even if the tween has not completed). When you call grow(), tweenScaleX and tweenScaleY are both assigned new tween objects. If the shrink button is clicked before grow() is finished, the shrink() method will begin and the tweens assigned during grow() will essentially be "destroyed" to make way for the new shrink tweens.

Furthermore, your problem might be related to AS3's garbage collection. The first answer provided said that the code works fine, but garbage collection is different from computer to computer due to performance and memory availability. A memory intensive Flash app will perform garbage collection more frequently, but on a box with lots of memory and performance it may not happen at all. As I mentioned above, since you are creating the tween variables inside the grow() and shrink() functions, their scope is only within that function. When the function completes, the variables created inside the function become eligible for garbage collection. Your tween objects will be destroyed if garbage collection occurs even if those tweens have not finished their tweens (and the "complete" event will never fire). By moving the tween variables outside of the functions in your example (or making them class members in a class), you are moving the scope to the parent object so the tween will exist as long as that parent exists. The changes to garbage collection are one of the most important but probably least understood changes from AS2 to AS3. As a developer, you might have a lot of RAM so garbage collection is not frequent (or non-existent as long as there's enough memory to hold everything), but in production your users might experience strange behavior as items are garbage collected to free up RAM but those items are referenced elsewhere since you thought they still existed and the code works fine for you. This is one complaint you see from AS3 developers a lot where they blame Adobe for making changes that cause Flash to no longer be platform independent, but it's an important feature that needed to be added to make Flash more robust.

帅冕 2024-08-28 22:25:50

你的代码是正确的。正常工作。在 ide 中检查变换面板中影片剪辑的比例,它们应设置为 100 100。

your code is correct. Works as it should. Check in the ide the scale of your movieclips in the transform panel, they should be set to 100 100.

书信已泛黄 2024-08-28 22:25:50

不要在函数内声明补间对象,它们会在补间结束之前被 CG 清除。
在全球范围内声明它们。

错误:

function grow(e:MouseEvent):void
{
    var tweenGrowX:Tween = new Tween(selectedObject, "scaleX", None.easeIn, 1.0, 2.0, 3.0, true);
    var tweenGrowY:Tween = new Tween(selectedObject, "scaleY", None.easeIn, 1.0, 2.0, 3.0, true);
}

正确:

var tweenGrowX:Tween;
var tweenGrowY:Tween;
function grow(e:MouseEvent):void
{
    tweenGrowX = new Tween(selectedObject, "scaleX", None.easeIn, 1.0, 2.0, 3.0, true);
    tweenGrowY = new Tween(selectedObject, "scaleY", None.easeIn, 1.0, 2.0, 3.0, true);
}

Do not declare the tween objects inside the functions, they get cleaned by CG before the end of tweening.
Declare them globally.

INCORRECT:

function grow(e:MouseEvent):void
{
    var tweenGrowX:Tween = new Tween(selectedObject, "scaleX", None.easeIn, 1.0, 2.0, 3.0, true);
    var tweenGrowY:Tween = new Tween(selectedObject, "scaleY", None.easeIn, 1.0, 2.0, 3.0, true);
}

CORRECT:

var tweenGrowX:Tween;
var tweenGrowY:Tween;
function grow(e:MouseEvent):void
{
    tweenGrowX = new Tween(selectedObject, "scaleX", None.easeIn, 1.0, 2.0, 3.0, true);
    tweenGrowY = new Tween(selectedObject, "scaleY", None.easeIn, 1.0, 2.0, 3.0, true);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文