AS3 hitTestPoint准确度延迟一帧

时间:2012-06-28 02:28:59

标签: actionscript-3 flash hittest

当我正在做我当前的项目时,我发现当我移动对象时,hitTestPoint的准确度是一帧延迟。因此,如果将对象A移动到一个全新且遥远的位置,则对该对象执行的hitTestPoint将返回false。为了说明这一点,我使用最基本的逻辑进行了快速实验:

import flash.display.Sprite;
import flash.display.Graphics;
import flash.events.Event;

var me:Sprite = new Sprite();
var g:Graphics = me.graphics;
g.beginFill( 0xFF0000 );
g.drawRect( -10, -10, 20, 20 );
g.endFill();
addChild( me );

trace( "Hit test at (0,0) while object is at (" + me.x + "," + me.y + ") = " + me.hitTestPoint( 0, 0, true ) );

me.x = 300;
me.y = 300;

trace( "\n>>>>>>>>>> WHERE DID THE OBJECT GO? >>>>>>>>>>" );
trace( "Hit test at (0,0) while object is at (" + me.x + "," + me.y + ") = " + me.hitTestPoint( 0, 0, true ) );
trace( "Hit test at (150,150) while object is at (" + me.x + "," + me.y + ") = " + me.hitTestPoint( 150, 150, true ) );
trace( "Hit test at (300,300) while object is at (" + me.x + "," + me.y + ") = " + me.hitTestPoint( 300, 300, true ) );
trace( ">>>>>>>>>> WHERE DID THE OBJECT GO? >>>>>>>>>>\n" );

removeChild( me );
addChild( me );

trace( "After remove/addChild, hit test at (300,300) while object is at (" + me.x + "," + me.y + ") = " + me.hitTestPoint( 300, 300, true ) );

结果如下:

Hit test at (0,0) while object is at (0,0) = true

>>>>>>>>>> WHERE DID THE OBJECT GO? >>>>>>>>>>
Hit test at (0,0) while object is at (300,300) = false
Hit test at (150,150) while object is at (300,300) = false
Hit test at (300,300) while object is at (300,300) = false
>>>>>>>>>> WHERE DID THE OBJECT GO? >>>>>>>>>>

After remove/addChild, hit test at (300,300) while object is at (300,300) = true

我发现在删除并将子项添加回舞台后,hitTestPoint再次起作用。但是hitTestPoint也适用于下一帧。

到目前为止,任何人都遇到过同样的事情吗?

2 个答案:

答案 0 :(得分:0)

我认为这个问题正在发生,因为flash处理显示对象的方式。 我的猜测就是你打电话的那一刻

addChild(me);

“addChild”强制flash绘制'我'。 但当你使用x和y参数移动'我'时,flash会在重绘图形之前等待帧完成。

如果您想强制执行Flash以立即重绘,我猜测

import flash.display.Sprite;
import flash.display.Graphics;
import flash.events.Event;

var me:Sprite = new Sprite();
var g:Graphics = me.graphics;
var myIndex:int;
g.beginFill( 0xFF0000 );
g.drawRect( -10, -10, 20, 20 );
g.endFill();
addChild( me );

me.x = 300;
me.y = 300;

addChild(me);

除非无法绕过它,否则不要使用此hack,因为它会降低您的应用程序速度。 再一次,我无法检查我是否正确,因为我的电脑上没有闪光灯。

答案 1 :(得分:0)

我可以确认关于flash更新对象在舞台上的位置的时间的内容,但是可以更正和扩展说明。 Flash确实具有固定的帧速率,并且显示更新遵循此时间线。但游戏逻辑可以比渲染速度更快或更慢。如果您拨打addChild(me),它将不会立即更新位置,也会在下一帧开始时更新。

因此,您必须选择固定时间步或可变时间步。与您所做的选择无关,最好使用OnEnterFame之类的事件来管理时间步,而不是依靠Flash播放器来更新逻辑。

我在an answer上写了一个类似的问题gamedev.stackexchange.com,该帖子也有一些有用的链接:

这是另一个与语言无关的有用线程:Fixed time step vs Variable time step