当与块碰撞时,玩家不会停止

时间:2012-09-04 05:35:53

标签: c# collision

我正试着这样做,所以当他击中一个区块时我的球员完全停止,但是如果他按下某个键就会变得不稳定。示例:播放器正在关闭并触及一个块。他停下来,但如果按下W,A或D,他可以向上,向左或向右移动。这是我目前的代码。

在这种情况下,sp表示速度,blocksp表示他被阻挡时的速度。 (This.Sprite),在这种情况下,指的是阻止他的块。

        bool Blocked = false;
        float Bottom = -32;
        float Left = -32;
        float Right = This.Sprite.GetWidth() - 32;
        float Top = This.Sprite.GetHeight() - 32;
        int x = 0;
        int y = 0;
        float sp = 1.59f;
        float blocksp = 0.00f;
        Sprite Player = This.Game.FindSprite("GuySprite");
        if (This.Sprite.CollisionWithSprite("GuySprite") != null)
        {

            if (Player.Position.Y > Top)
            {
                Blocked = true;
                Player.Velocity = new Point2D(x, y) * blocksp;
                Player.Animation = 0;
                if (This.Game.IsPressed(InputKey.W) || This.Game.IsPressed(InputKey.A) || This.Game.IsPressed(InputKey.D))
                {
                    Blocked = false;
                    Player.Velocity = new Point2D(x, y) * sp;
                    Player.Position.Y -= 0.85f;
                }
            }
            if (Player.Position.Y < Bottom)
            {
                Blocked = true;
                Player.Velocity = new Point2D(x, y) * blocksp;
                Player.Animation = 0;
                if (This.Game.IsPressed(InputKey.S) || This.Game.IsPressed(InputKey.A) || This.Game.IsPressed(InputKey.D))
                {
                    Blocked = false;
                    Player.Velocity = new Point2D(x, y) * sp;
                    Player.Position.Y += 0.85f;
                }
            }
            if (Player.Position.Y < Right)
            {
                Blocked = true;
                Player.Velocity = new Point2D(x, y) * blocksp;
                Player.Animation = 0;
                if (This.Game.IsPressed(InputKey.S) || This.Game.IsPressed(InputKey.A) || This.Game.IsPressed(InputKey.W))
                {
                    Blocked = false;
                    Player.Velocity = new Point2D(x, y) * sp;
                    Player.Position.Y -= 0.85f;
                }
            }
            if (Player.Position.Y > Left)
            {
                Blocked = true;
                Player.Velocity = new Point2D(x, y) * blocksp;
                Player.Animation = 0;
                if (This.Game.IsPressed(InputKey.S) || This.Game.IsPressed(InputKey.W) || This.Game.IsPressed(InputKey.D))
                {
                    Blocked = false;
                    Player.Velocity = new Point2D(x, y) * sp;
                    Player.Position.X += 0.85f;
                }
            }
        }

目前,如果我的玩家接触到该区块的任何一侧并继续他的移动该区块停止,则该玩家将以不稳定的方向移动并且不会在该区块处停止。有什么想法吗?

1 个答案:

答案 0 :(得分:1)

修改

here is the picture.

玩家朝着街区跑,所以他会在下一帧中击中左侧。 因此,以下条件将成立。

if (This.Sprite.CollisionWithSprite("GuySprite") != null)

现在你必须实现一个方法来找出玩家与哪一方相撞。 实际上你的代码让我很困惑,因为:

Player.Velocity = new Point2D(x, y) * ...; 

将始终为零向量,因为x = y = 0

我会这样做:

float xDistance=0f, yDistance=0f;//this ll be explained later on
If(Player.Velocity.X > 0) //he is running to the right so he can hit the left side
     xDistance=mayHitLeft();
Else If(Player.Velocity.X < 0)
     xDistance=mayHitRight();
If(Player.Velocity.Y > 0) //In my case positive Y means downwards so can hit top
     yDistance=mayHitTop();
Else If(Player.Velocity.Y < 0)
     yDistance=mayHitBot();

现在我们必须找出玩家是击中机器人/上边缘还是左/右边缘或者两者兼而有之。 让我们假设他正在摔倒并且之前正在向右跑。 所以Player.Velocity.X > 0Player.Velocity.Y > 0 这意味着功能mayHitLeft();mayHitTop();  将被召唤。 我不知道collisionWithSprite函数是如何工作的。 但一如既往,我们采取最坏的情况like this one蓝色是块,橙色是玩家。 这是击中之前的帧,现在没有检测到碰撞。所以在下一帧中,两个函数都会检测到碰撞但是哪个是正确的碰撞。正如我们所看到它与顶部相撞。那么如何找到合适的?因此,我们使用距离或者说我们在哪个方向上有多少重叠。所以较少的重叠是正确的。

因此两个函数都返回一个double。我们来看看mayHitTop()函数

private float mayhitTop()
    {
        //remember that the y coordinate goes downwards so we have to add
        float playersBotCoordinate = Player.Position.Y + Player.Sprite.Height;
        //the y position is the top so nothing to change
        float blocksTopCoordinate = Block.Position.Y;
        hitTop=true; //this is a global variable you have 1 for each direction
        return Math.Abs(playersBotCoordinate - blocksTopCoordinate);
    }

所以我们设置了xDistanceyDistance,我们知道它会在顶部或左侧。

现在我们必须比较一切

// this means there could be 2 sides like our case that can be ths possible collision edge
if((hitLeft || hitRight) && (hitTop || hitBot))
{ 
   //we hit the left or right side
   if(xDistance<yDisante)
   {
      Player.Velocity.X = 0;
   }
   //we hit top or bottom
   else
   {         
      Player.Velocity.Y=0;
   }
}
else
{
    if(hitLeft || hitRight)...

}

也许你必须解开玩家。否则我认为可能会有一些问题。

所以我只是在没有任何模板的情况下编写它。不知道是否有任何语法错误。但这只会给你一个概述如何做到这一点'我们可以期待这是伪代码;)

希望它能帮助你至少一点点。

呃,你正在比较球员位置.Y左右 如果我理解代码,这应该是X坐标;)

 if (Player.Position.Y < Right) 

if (Player.Position.Y > Left)