在我们的游戏项目中,我们确实有一个定时器循环设置为每秒触发约20次(与应用程序帧速率相同)。我们用它来移动一些精灵。 我想知道这是否会导致问题,我们应该使用EnterFrame事件处理程序进行更新? 我得到的印象是,定时器循环运行速度比应用程序帧速率快可能会导致问题......是这样的吗?
作为更新,尝试在EnterFrame上执行此操作会导致非常奇怪的问题。而不是每75毫秒一帧,突然它跳到25毫秒。请注意,不仅仅是我们的计算声称帧率是不同的,突然间动画加速了疯狂的速度。
答案 0 :(得分:4)
我会选择Enter框架,在某些特殊情况下,有两个“循环”一个用于逻辑,一个用于视觉效果,但是对于大多数游戏我都坚持使用Enter框架事件监听器。有一个单独的计时器来移动你的东西是有点不必要的,因为它设置为任何东西,除了帧率将使运动不稳定或只是不可见(因为帧不重绘)。
然而,要考虑的一件事是将逻辑与帧速率分离,这最容易通过使用getTimer(在as2和as3中都可用)来计算自上一帧以来已经过期的时间并调整运动或其他因此。
计时器不比输入帧事件更可靠,闪存将尝试跟上您设置的任何速率,但如果您正在进行繁重的处理或复杂的图形,它将减慢,包括计时器和帧速率。
答案 1 :(得分:4)
以下是Flash如何处理帧率以及为什么您看到内容播放速度更快的概述。
在最深层次上,无论运行Flash的主机应用程序(通常是浏览器)都会以某种间隔轮询闪存。该间隔可能在一个浏览器中每隔10ms,在另一个浏览器中为50ms。每次轮询发生时,Flash都会执行以下操作:
ENTER_FRAME
活动但是,某些类型的外部事件(例如按键,鼠标事件和计时器事件)与上述过程异步处理。因此,如果您在按下某个键时触发了事件处理程序,则该处理程序中的代码可能会在帧更新之间执行多次。除非您使用updateAfterEvent()
方法(AS2中的全局,附加到AS3中的事件),否则屏幕仍将仅在每次帧更新时重绘一次。
请注意,这些事件的异步行为不会影响帧更新的时间。即使您使用计时器事件,例如,每秒重绘屏幕50次,帧动画仍将以发布的帧速率发生,如果脚本动画由enterFrame事件驱动,则脚本动画将不会执行得更快(而不是计时器)。
答案 2 :(得分:2)
使用输入帧事件的好处是,您的处理将以与渲染相同的速度降级,并且您将在代码块完成后立即获得屏幕更新。
不保证在特定时间间隔内发生任何一种方法。所以你的事件处理程序应该确定它自上次执行以来已经存在了多长时间,并从中做出决定而不是纯粹运行它的次数。
答案 3 :(得分:0)
我认为timerEvent和Enter Frame都是不错的选择,我在游戏中使用了它们。 (你的意思是定时器循环是指timerEvent吗?)
PS:请注意,在慢速机器中,计时器可能无法快速刷新,因此您可能需要调整代码以使游戏在慢速机器中“更快”地工作。
答案 4 :(得分:0)
我建议使用像TweenLite(http://blog.greensock.com/tweenliteas3/)这样的类,它在3kb左右是轻量级的,或者如果你需要更多的功率,你可以使用TweenMax,我相信它是11kb。这里有很多优点。首先,这个“引擎”已经过彻底的测试和基准测试,众所周知,它是一种资源最友好的方式,可以动画很少甚至很多东西。我已经看到了一个基准测试,在AS3中,1,500个精灵正在使用TweenLite进行动画处理,它拥有强大的20 fps,因为像Tweener这样的竞争对手会陷入9 fps http://blog.greensock.com/tweening-speed-test/。下一个优点是易用性,我将在下面演示。
//Make sure you have a class path pointed at a folder that contains the following. import gs.TweenLite; import gs.easing.*; var ball_mc:MovieClip = new MovieClip(); var g:Graphics = ball_mc.graphics; g.beginFill(0xFF0000,1); g.drawCircle(0,0,10); g.endFill(); //Now we animate ball_mc //Example: TweenLite.to(displayObjectName, totalTweeningTime, {someProperty:someValue,anotherProperty:anotherValue,onComplete:aFunctionCalledWhenComplete}); TweenLite.to(ball_mc, 1,{x:400,alpha:0.5});
因此,这需要ball_mc并将其从x轴上的当前位置移动到400,并且在相同的Tween期间,它会将alpha从其当前值减小或增加到0.5。
在导入所需的类之后,实际上只有一行代码来动画每个对象,这非常好。我们也可以影响轻松,我相信默认情况下是Expo.easeOut(Strong easeOut)。如果您希望它弹跳或弹性,只需通过向对象添加属性即可获得此类效果,如下所示。
TweenLite.to(ball_mc, 1,{x:400,alpha:0.5,ease:Bounce.easeOut}); TweenLite.to(ball_mc, 1,{x:400,alpha:0.5,ease:Elastic.easeOut});
缓和都来自gs.easing。* import,我相信是通过TweenLite使用Penner的缓动方程式。
最后我们没有用于管理诸如Timer的轮询(Open循环),我们有非常易读的代码,可以轻松修改或删除。
同样重要的是要注意TweenLite和TweenMax提供的内容远远超过我在这里显示的内容,可以肯定地说我在每个项目中都使用了这两个类中的一个。动画是自定义的,它们附加了功能(onComplete:functionCall),同样,它们是最佳的,资源友好的。