0

私は XNA と C# にまったく慣れていません (2 日前に始めたので、ずさんなプログラミングを許してください)、作成中の単純なゲームで問題が発生しました。どのオンライン チュートリアルでも解決策が見つからないようです。長方形の衝突検出を利用しようとしていますが、正しく機能させることができません。キャラクターは完全に床を突き破り、どの場所にも衝突が記録されていないように見えます。ここで論理エラーを見つけることができません。以下に、衝突検出に関連するコードを少し掲載しました。必要に応じてさらに投稿できます。事前に助けてくれてありがとう!

Level.cs

//The method below is called in the initial LoadContent method in Game1.cs. 'LoadBlocks()' is supposed to read in a text file and setup the level's "blocks" (the floor or platforms in the game). 

public void LoadBlocks(int level){
    if (level == 0)
        {
            fileName = "filepath";
        }

        System.IO.StreamReader file = new System.IO.StreamReader(fileName);
        while ((line = file.ReadLine()) != null)
        {
            for (int i = 0; i < 35; i++)
            {
                rectBlock = new Rectangle((int)positionBlock.X, (int)positionBlock.Y, width / 30, height / 30);

                if (line.Substring(i, 1).Equals(","))
                {
                    positionBlock.X += (width / 100) * 24;
                }
                if (line.Substring(i, 1).Equals("#"))
                {  //block -> (bool isPassable, Texture2D texture, Rectangle rectangle, Vector2 position)
                    block = new Block(false, textureBlock, rectBlock, positionBlock);
                    blocks.Add(block);
                    positionBlock.X += (width / 100) * 24;
                }
            }


            positionBlock.Y += (height / 100) * 8;
            positionBlock.X = 0;
        }
    }

//This method below updates the character 'bob' position and velocity.
 public void UpdatePlayer()
    {
        bob.position += bob.velocity;
        bob.rectangle = new Rectangle((int)bob.position.X, (int)bob.position.Y, width / 30, height / 30);

        float i = 1;
        bob.velocity.Y += 0.15f * i;
        foreach (Block block in blocks)
        {
            if (bob.isOnTopOf(bob.rectangle, block.rectangle))
            {
                bob.velocity.Y = 0f;
                bob.hasJumped = false;
            }
        }
    }

Character.cs

//Here is my whole Character class for 'bob'

public class Character
{
    int height = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Height;
    int width = GraphicsAdapter.DefaultAdapter.CurrentDisplayMode.Width;

    int health;
    String name;
    bool gender;
    Texture2D texture;
    public Vector2 position;
    public Vector2 velocity;
    public bool hasJumped;
    public Rectangle rectangle;

    public Character(int newHealth, String newName, bool newGender, Texture2D newTexture, Vector2 newPosition)
    {
        health = newHealth;
        gender = newGender;
        name = newName;
        texture = newTexture;
        position = newPosition;
        hasJumped = true;
        rectangle = new Rectangle(0,0, width/30,height/30);
        velocity = Vector2.Zero;
    }

    public bool isOnTopOf(Rectangle r1, Rectangle r2)
    {
        const int penetrationMargin = 5;

        return (r1.Bottom >= r2.Top - penetrationMargin &&
           r1.Bottom <= r2.Top &&
           r1.Right >= r2.Left + 5 &&
           r1.Left <= r2.Right - 5);

    }


    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(texture, rectangle,null, Color.White,0,position,SpriteEffects.None,0);
    }

}

これが投稿されたコードが多すぎたり、混乱を招いたりする場合は申し訳ありませんが、どんな助けも大歓迎です! ありがとう!

4

2 に答える 2

3

交差のテスト条件は、少なくとも正しくないようです。コードには他にも問題がある可能性があります (ざっと見てみるだけでもいくつかあります) が、これに焦点を当てましょう。

r1.Bottom >= r2.Top - penetrationMargin &&
r1.Bottom <= r2.Top &&
r1.Right >= r2.Left + 5 &&
r1.Left <= r2.Right - 5;

まず、ライブラリにあるものを自分でコーディングしないでください。Xna Rectangles にはIntersectsメソッドがあるため、そのコードを破棄して代わりに使用してください。

とにかく条件を見てみましょう。

r1's Bottom is below r2's Top minus a margin AND
r1's Bottom is above r2's Top AND (...)

これはすでに不可能です。r1.Bottom を r2.Topの下と上に配置することはできません。

さらに、すべての比較が正しかったとしても、どこでも AND (&&) を使用しているため、4 つすべてが true の場合にのみ条件が true になります。つまり、r1 が完全に r2 内にあることをテストしています。交差テストは、AND (&&) ではなく OR (||) を使用して条件を結合します。

繰り返しますが、教育目的で自分でコーディングしたい場合もありますが、エンジニアリングの観点からの最善の解決策は、ライブラリが提供するもの (ここでは Rectangle.Intersects) を使用することです。

于 2012-06-02T04:20:14.100 に答える
0

私はそれを理解しましたが、なぜこれが実際に機能するのかわかりません。描画方法に問題がありました。私はもともと持っていました:

spriteBatch.Draw(texture, rectangle, null, Color.White, 0, position, SpriteEffects.None, 0); 

私の方法として、しかしそれから私はこれをに変更しました

spriteBatch.Draw(texture, rectangle, Color.White);

そして今、すべてが正常に動作します。

于 2012-06-02T07:19:18.367 に答える