AS3 - 如何使用 hitTestObject 正确停止玩家并根据碰撞区域限制玩家的移动?
AS3 - How to properly stop player with hitTestObject and restrict player's movement based on colliding area?
我有两个关于碰撞的问题,当玩家多次按下移动键时,玩家可能会穿过物体,并且玩家的 x
和 y
移动都会在接触物体的任何一侧时停止目的。它应该只停止 x
或 y
取决于它接触的哪一侧。
虽然它接触到边界框的 left/right 边,但它应该仍然可以上下移动。当它接触边界框的 top/bottom 边时,它应该能够左右移动。
我在播放器中的移动代码class ENTER_FRAME
:
private function onEnterFrame(event:Event):void
{
_vx = 0;
_vy = 0;
if (isRight)
{
_vx = 5;
}
if (isLeft)
{
_vx = -5;
}
if (isUp)
{
_vy = -5;
}
if (isDown)
{
_vy = 5;
}
x += _vx;
y += _vy;
}
我在 CollisionBase class ENTER_FRAME
中的 hitTestObject 代码(Base Class for MovieClips
):
private function onEnterFrame(event:Event):void
{
if (MovieClip(parent).player.collisionArea.hitTestObject(this))
{
if (MovieClip(parent).player.isLeft)
{
MovieClip(parent).player.x -= MovieClip(parent).player._vx;
}
if (MovieClip(parent).player.isRight)
{
MovieClip(parent).player.x -= MovieClip(parent).player._vx;
}
if (MovieClip(parent).player.isUp)
{
MovieClip(parent).player.y -= MovieClip(parent).player._vy;
}
if (MovieClip(parent).player.isDown)
{
MovieClip(parent).player.y -= MovieClip(parent).player._vy;
}
}
}
FLA
文件:https://www.dropbox.com/s/k5dlxrsnvbrmtke/Subject.zip?dl=0
FLA
文件包含一个播放器和一个碰撞床。
您的游戏设计结构不合理。您应该有一个 ENTER_FRAME
用于游戏逻辑。取而代之的是,玩家有一个 ENTER_FRAME
,一个 ENTER_FRAME
可以交换 children,每个障碍物都有一个 ENTER_FRAME
。这种设计不仅让您头疼,而且会让您的游戏性能大打折扣。
要解决 hitTest
的问题,请执行以下操作:
将此代码放在 CollisionBase
Class
:
private function onEnterFrame(event:Event):void
{
var player:MovieClip = MovieClip(this.parent).player;
if (player.collisionArea.hitTestObject(this)) player.collision = true;
}
将此 属性 添加到 Player
Class
:
private var _collision:Boolean = false;
public function set collision(value:Boolean):void{
_collision = value;
}
接下来,在 onEnterFrame
函数的开头添加这些行:
private function onEnterFrame(event:Event):void
{
if(_collision){
x -= _vx;
y -= _vy;
_collision = false;
return;
}
_vx = 0;
_vy = 0;
if (isRight)
{
....
问题已解决,但现在您的播放器在碰到障碍物时会闪烁。发生这种情况是因为玩家 ENTER_FRAME
移动玩家,然后其他 ENTER_FRAME
检查碰撞(在 CollisionBase.class
中)并且在玩家 ENTER_FRAME
的下一个循环中玩家做了一个退后。如果你只有一个ENTER_FRAME
,这样的事情就不会发生。
我建议你其他选择。看看这个例子,看看它是如何制作的,也许它会给你一些想法;)
我有两个关于碰撞的问题,当玩家多次按下移动键时,玩家可能会穿过物体,并且玩家的 x
和 y
移动都会在接触物体的任何一侧时停止目的。它应该只停止 x
或 y
取决于它接触的哪一侧。
虽然它接触到边界框的 left/right 边,但它应该仍然可以上下移动。当它接触边界框的 top/bottom 边时,它应该能够左右移动。
我在播放器中的移动代码class ENTER_FRAME
:
private function onEnterFrame(event:Event):void
{
_vx = 0;
_vy = 0;
if (isRight)
{
_vx = 5;
}
if (isLeft)
{
_vx = -5;
}
if (isUp)
{
_vy = -5;
}
if (isDown)
{
_vy = 5;
}
x += _vx;
y += _vy;
}
我在 CollisionBase class ENTER_FRAME
中的 hitTestObject 代码(Base Class for MovieClips
):
private function onEnterFrame(event:Event):void
{
if (MovieClip(parent).player.collisionArea.hitTestObject(this))
{
if (MovieClip(parent).player.isLeft)
{
MovieClip(parent).player.x -= MovieClip(parent).player._vx;
}
if (MovieClip(parent).player.isRight)
{
MovieClip(parent).player.x -= MovieClip(parent).player._vx;
}
if (MovieClip(parent).player.isUp)
{
MovieClip(parent).player.y -= MovieClip(parent).player._vy;
}
if (MovieClip(parent).player.isDown)
{
MovieClip(parent).player.y -= MovieClip(parent).player._vy;
}
}
}
FLA
文件:https://www.dropbox.com/s/k5dlxrsnvbrmtke/Subject.zip?dl=0
FLA
文件包含一个播放器和一个碰撞床。
您的游戏设计结构不合理。您应该有一个 ENTER_FRAME
用于游戏逻辑。取而代之的是,玩家有一个 ENTER_FRAME
,一个 ENTER_FRAME
可以交换 children,每个障碍物都有一个 ENTER_FRAME
。这种设计不仅让您头疼,而且会让您的游戏性能大打折扣。
要解决 hitTest
的问题,请执行以下操作:
将此代码放在 CollisionBase
Class
:
private function onEnterFrame(event:Event):void
{
var player:MovieClip = MovieClip(this.parent).player;
if (player.collisionArea.hitTestObject(this)) player.collision = true;
}
将此 属性 添加到 Player
Class
:
private var _collision:Boolean = false;
public function set collision(value:Boolean):void{
_collision = value;
}
接下来,在 onEnterFrame
函数的开头添加这些行:
private function onEnterFrame(event:Event):void
{
if(_collision){
x -= _vx;
y -= _vy;
_collision = false;
return;
}
_vx = 0;
_vy = 0;
if (isRight)
{
....
问题已解决,但现在您的播放器在碰到障碍物时会闪烁。发生这种情况是因为玩家 ENTER_FRAME
移动玩家,然后其他 ENTER_FRAME
检查碰撞(在 CollisionBase.class
中)并且在玩家 ENTER_FRAME
的下一个循环中玩家做了一个退后。如果你只有一个ENTER_FRAME
,这样的事情就不会发生。
我建议你其他选择。看看这个例子,看看它是如何制作的,也许它会给你一些想法;)