gpt4 book ai didi

javascript - 预加载器中的 OpenFL 动画总是第一次卡顿

转载 作者:行者123 更新时间:2023-11-30 15:03:50 25 4
gpt4 key购买 nike

我使用内置的 NMEPReloader 作为我在 openfl 中预加载器的基类。

我正在做的是逐帧播放动画

class AttractAnimation extends Sprite
{
var currentFrame:Int;
var previousFrame:Int;
var bitmapFrames:Array<Bitmap>;
var loadScreenTimer:Timer;

public function new()
{
super();
currentFrame = 0;
previousFrame = -1;
bitmapFrames = new Array<Bitmap>();
}

public function assignBitmapData(bitmapData : Array<BitmapData>){
for(bmap in bitmapData){
var frame = new Bitmap( null, flash.display.PixelSnapping.AUTO, true );
frame.bitmapData = bmap;
pushFramesAsBitmap(frame);
}
}
public function pushFramesAsBitmap(frameAsBitmap:Bitmap) {
bitmapFrames.push(frameAsBitmap);

frameAsBitmap.visible = false;
addChild(frameAsBitmap);
}

public function startAnimation(fps:Int) {
var milliseconds:Float = 1000 / fps;
loadScreenTimer = new Timer(milliseconds, 10);
loadScreenTimer.addEventListener(TimerEvent.TIMER, updateAnimation);
loadScreenTimer.start();
}

private function updateAnimation(e : TimerEvent):Void {
if (currentFrame > bitmapFrames.length -1) { currentFrame = 0; }
if (previousFrame != -1) {
bitmapFrames[previousFrame].visible = bitmapFrames[previousFrame].__combinedVisible = false;
}
bitmapFrames[currentFrame].visible = bitmapFrames[currentFrame].__combinedVisible = true;
previousFrame = currentFrame;
currentFrame++;
}

}

当我调用 playAnimation 时,我看到它卡顿得很厉害,下次我播放动画时它播放得很流畅。

我曾尝试将 alpha 设置为 0 来播放动画,然后将其设置回 1 并播放,但在这种情况下它第二次会卡顿。

同样,如果我将它移到另一个显示对象后面播放动画,然后将它移到绘制顺序的前面,它会第二次卡顿。

有没有办法让我播放这个动画时不卡顿?

最佳答案

由于您的实现非常简单并且不依赖于太多外部 API,因此计时器可能是一个原因。请记住,预加载器实际上会优先加载所有内容,因此延迟是可以预料的,除非您采取措施隐藏或阻止它。由于滞后,定时器事件很可能会连续多次触发。这会导致视觉错误和卡顿。

首先,首先尝试使用 enterFrame 事件监听器而不是计时器,这在大多数情况下(如果不是所有的话)都是一个糟糕的设计选择。

//Using this event listener
addEventListener(Event.ENTER_FRAME, OnUpdateAnimation);

//which would call this function every frame
function OnUpdateAnimation(e:Event):Void
{
//calculate delay since last frame
//play next frame
}

其次,不使用位图数组,而是使用单个位图和位图数据数组。虽然对于不应有太大变化的小动画来说,这是一种更好的做法并且可以帮助提高性能(例如,在预加载器中)。

这是一个扩展 Sprite 的动画类的新实现。它尚未经过测试,但应该像宣传的那样工作。请注意,通常,为每个对象使用一个 EnterFrame 监听器并不是一个好的做法;你通常会有一个主更新函数,它会遍历所有可更新的对象。但如果是这种情况,它就足够了。

class Animation extends Sprite 
{

private var mBitmapDataList:Array<BitmapData>; //a list of bitmapdata
private var mBitmap:Bitmap; //the bitmap that will contain all bitmapdata
private var mCurrentIndex:Int; //the currently displayed bitmapdata
private var mFrameLength:Float; //the duration of a frame in miliseconds
private var mDeltaTime:Float = 0; //the current delta time for time-based updates

private var mTime:Float; //a variable containing the current time since the last frame change
public function new(aFrameLength:Float)
{
super();
mFrameLength = aFrameLength;
mBitmapDataList = new Array<BitmapData>();
mBitmap = new Bitmap();
addChild(mBitmap); //add the bitmap to the scene
//(it will display nothing as no bitmapdata is set)
mCurrentIndex = 0;
}

//add a bitmapdata instead of a complete bitmap object
public function addBitmapData(aBD:BitmapData):Void
{
mBitmapDataList.push(aBD);
}

public function play():Void
{
addEventListener(Event.ENTER_FRAME, onEnterFrame, false, 0, true);
}

private function onEnterFrame(e:Event):Void
{
var currentTime = Lib.getTimer(); //get the current time
var elapsed:Float = (currentTime - mDeltaTime); //calculate the time since the last update
mDeltaTime = currentTime;

mTime += elapsed; //add the elapeed time to mTime
if (mTime >= mFrameLength) //if it is time to change frame...
{
mTime = 0;
mCurrentIndex++;
if (mCurrentIndex == mBitmapDataList.length) mCurrentIndex = 0;
mBitmap.bitmapData = mBitmapDataList[mCurrentIndex]; //change it
}
}
}

这样,即使在卡顿的极端情况下,也只会跳过第一帧。另请注意,在某些目标上,您将无法显示图像,因为它们尚未加载。另一种解决方案是不嵌入 Assets <assets path="assets" embed="false"/>并使用 OpenFL 的 Assets 类加载它们(因此完全放弃预加载器,在我看来这是一个花哨的东西)

PS:请原谅我在变量上加了 m 和 a 前缀。 m 用于成员变量,a 用于参数。

关于javascript - 预加载器中的 OpenFL 动画总是第一次卡顿,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46101134/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com