0

プレーヤーがブロックに当たったときに完全に停止するようにしようとしていますが、特定のキーを押すと動かなくなることがあります。例: プレイヤーがダウン中にブロックにぶつかった。彼は停止しますが、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;
                }
            }
        }

現在、プレーヤーがブロックのいずれかの側面に触れ、ブロックが停止するまで動き続けると、プレーヤーは不規則な方向に移動し、ブロックで停止しません。何か案は?

4

1 に答える 1

1

編集

Okここに写真があります。

プレイヤーはブロックに向かって走っているので、次のフレームで左側を攻撃します。次の条件が真になるようにします。

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();

ここで、プレイヤーがボット/トップ エッジまたは左/右エッジ、または両方をヒットしたかどうかを確認する必要があります。彼が倒れていて、前に右に走っていたとしましょう。so Player.Velocity.X > 0andPlayer.Velocity.Y > 0 これは関数mayHitLeft();を意味し、mayHitTop(); 呼び出されます。collisionWithSprite関数の仕組みがわかりません。しかし、いつものように、青がブロックでオレンジがプレーヤーのような最悪のケースを取り上げます。これはヒットする前のフレームで、今のところ衝突は検出されていません。したがって、次のフレームでは両方の関数が衝突を検出しますが、どちらが正しいものです。ご覧のとおり、トップと衝突しています。では、正しいものを検出するにはどうすればよいでしょうか。したがって、距離を使用するか、どの方向にどれだけオーバーラップしているかを言いましょう。したがって、オーバーラップが少ないことが適切です。

したがって、両方の関数は 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);
    }

xDistanceandを設定したのでyDistance、上または左にヒットすることがわかっています。

今、すべてを比較する必要があります

// 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)  
于 2012-09-04T05:46:12.513 に答える