0

私の衝突検出は機能しているようですが、検出されている衝突のいくつかは奇妙ですが、そうでないときに衝突がプラットフォームの底にあったと言うようです。しかし、それは主な問題ではありません。

プレイヤーがプラットフォームに衝突すると、プラットフォームの表面に移動するのではなく、プラットフォームの上に移動し、私の重力が適所にあるため、常にバウンドしているように見えます。理由がわかりません。

あなたたちが助けてくれれば、それは大歓迎です。私は XNA と C# を初めて使用するので、見逃している非常に単純なものである可能性があります。

以下に、私の Game1、Player、および Platform クラスをリストします。(私の衝突検出はプレーヤークラスにあります)

ありがとう

ゲーム1クラス

public class Game1 : Microsoft.Xna.Framework.Game
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    Texture2D background;
    Movement character;
    Platform[] platforms;
    //private Vector2 SnapePosition = Vector2.Zero;

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
        graphics.PreferredBackBufferHeight = 440;
        graphics.PreferredBackBufferWidth = 782;

    }

    /// <summary>
    /// Allows the game to perform any initialization it needs to before starting to run.
    /// This is where it can query for any required services and load any non-graphic
    /// related content.  Calling base.Initialize will enumerate through any components
    /// and initialize them as well.
    /// </summary>
    protected override void Initialize()
    {
        // TODO: Add your initialization logic here
        platforms = new Platform[15];


        base.Initialize();
    }

    /// <summary>
    /// LoadContent will be called once per game and is the place to load
    /// all of your content.
    /// </summary>
    protected override void LoadContent()
    {
        // Create a new SpriteBatch, which can be used to draw textures.
        spriteBatch = new SpriteBatch(GraphicsDevice);


        for (int i = 0; i < platforms.Length; i++)
        {
            platforms[i] = new Platform(
                Content.Load<Texture2D>("Platforms/lvl2_platform"), new Rectangle(i*100, 410, 100, 30));
        }
        character = new Movement(Content.Load<Texture2D>("snape"), new Rectangle(0, 360, 50, 50), platforms);

        // TODO: use this.Content to load your game content here
        background = Content.Load<Texture2D>("Backgrounds/lvl2_background");
    }

    /// <summary>
    /// UnloadContent will be called once per game and is the place to unload
    /// all content.
    /// </summary>
    protected override void UnloadContent()
    {
        // TODO: Unload any non ContentManager content here
    }

    /// <summary>
    /// Allows the game to run logic such as updating the world,
    /// checking for collisions, gathering input, and playing audio.
    /// </summary>
    /// <param name="gameTime">Provides a snapshot of timing values.</param>
    protected override void Update(GameTime gameTime)
    {
        // Allows the game to exit
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();

        //Allows the player to move
        character.Update();

        // TODO: Add your update logic here


        base.Update(gameTime);
    }

    /// <summary>
    /// This is called when the game should draw itself.
    /// </summary>
    /// <param name="gameTime">Provides a snapshot of timing values.</param>
    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.CornflowerBlue);

        // TODO: Add your drawing code here

        spriteBatch.Begin();
        spriteBatch.Draw(background, Vector2.Zero, Color.White);
        character.Draw(spriteBatch);

        foreach (Platform platform in platforms)
        {
            platform.Draw(spriteBatch);
        }
        spriteBatch.End();

        base.Draw(gameTime);
    }
}

プレイヤークラス

class Player
{
    public Texture2D Snape;
    public Rectangle SnapePosition;

    public enum CollisionPosition { None, Top, Bottom, Left, Right };
    public CollisionPosition collisionType;
    public bool inCollision;
    public int collisionDepth;
    public Platform[] plat;
    public int num;

    public virtual void Update()
    {

    }

    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(Snape, SnapePosition, Color.White);
    }
}

class Movement : Player
{
        public Movement(Texture2D newSnape, Rectangle newSnapePosition, Platform[] a)
    {
        Snape = newSnape;
        SnapePosition = newSnapePosition;
        plat = a; 
    }

        public override void Update()
        {
            // Check for collision
            Collisions();

            // Determine collision type
            //DetermineCollisionType();

            // Separate snape
            //SeparateSnape();

            KeyboardState keyBoard = Keyboard.GetState();

            if (keyBoard.IsKeyDown(Keys.A))
            {
                SnapePosition.X -= 5;
            }
            if (keyBoard.IsKeyDown(Keys.D))
            {
                SnapePosition.X += 5;
            }
            if (keyBoard.IsKeyDown(Keys.W))
            {
                SnapePosition.Y -= 5;
            }
            //if (keyBoard.IsKeyDown(Keys.S))
            //{
                SnapePosition.Y += 5;
           // }



          //  if (SnapePosition.X < 0)
          //      SnapePosition.X = 0;
          //  if (SnapePosition.Y < 0)
          //      SnapePosition.Y = 0;
          //  if (SnapePosition.X > GraphicsDevice.Viewport.Width - Snape.Width)
          //      SnapePosition.X = GraphicsDevice.Viewport.Width - Snape.Width;
          //  if (SnapePosition.Y > GraphicsDevice.Viewport.Height - Snape.Height)
          //      SnapePosition.Y = GraphicsDevice.Viewport.Height - Snape.Height;

        }


        public void Collisions()
        {
            for (int i = 0; i < plat.Length; i++)
            {
                if (plat[i].rectangle.Intersects(SnapePosition))
                {
                    inCollision = true;
                    num = i;
                    DetermineCollisionType();
                }

            }

        }

        public void DetermineCollisionType()
        {
            if (inCollision == false)
            {
                collisionType = CollisionPosition.None;
                collisionDepth = 0;
            }
            else
            {
                // Determine the side of *least intersection* for snape
                int minColDepth = int.MaxValue;

                // Check the top side                    
                int tColDepth = (plat[num].rectangle.Y + plat[num].texture.Height / 2) - (SnapePosition.Y - Snape.Height / 2);

                if (tColDepth > 0 && tColDepth < minColDepth)
                {
                    collisionType = CollisionPosition.Top;
                    minColDepth = tColDepth;
                }

                // Check the bottom side            
                int bColDepth = (SnapePosition.Y + Snape.Height / 2) - (plat[num].rectangle.Y - plat[num].texture.Height / 2);

                if (bColDepth > 0 && bColDepth < minColDepth)
                {
                    collisionType = CollisionPosition.Bottom;
                    minColDepth = bColDepth;
                }

                // Check the right overlap
                int rColDepth = (SnapePosition.X + Snape.Width / 2) - (plat[num].rectangle.X - plat[num].texture.Width / 2);

                if (rColDepth > 0 && rColDepth < minColDepth)
                {
                    collisionType = CollisionPosition.Right;
                    minColDepth = rColDepth;
                }

                // Check the left overlap
                int lColDepth = (plat[num].rectangle.X + plat[num].texture.Width / 2) - (SnapePosition.X - Snape.Width / 2);

                if (lColDepth > 0 && lColDepth < minColDepth)
                {
                    collisionType = CollisionPosition.Left;
                    minColDepth = lColDepth;
                }

                // Update the collision depth
                collisionDepth = minColDepth;
                SeparateSnape();
            }
        }



        public void SeparateSnape()
        {
            switch (collisionType)
            {
                case CollisionPosition.None:
                    break;

                case CollisionPosition.Top:
                    SnapePosition.Y += (collisionDepth);
                    break;

                case CollisionPosition.Bottom:
                    SnapePosition.Y -= collisionDepth;
                    break;

                case CollisionPosition.Right:
                    SnapePosition.X -= collisionDepth;
                    break;

                case CollisionPosition.Left:
                    SnapePosition.X += collisionDepth;
                    break;
            }
        }
}

プラットフォーム クラス

class Platform
{
    public Texture2D texture;
    public Rectangle rectangle;

    public Platform(Texture2D newTexture, Rectangle newRectangle)
    {
        texture = newTexture;
        rectangle = newRectangle;
    }

    public void Update()
    {

    }

    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(texture, rectangle, Color.White);
    }


}
4

1 に答える 1

0

私はあなたの衝突を修正しました。

深さの計算はすべて正しくありませんでした。エンティティ (プレーヤー/プラットフォーム) の中心に基づいてそれらを実行し、長方形のサイズではなくテクスチャ サイズを使用していました。

すべてが真ん中から描画されると思っていたかもしれませんが、デフォルトでは XNA では左上から描画されます。

「DetermineCollisionType()」関数の下の「Movement」クラスにある新しい深度計算は次のとおりです。

上部の深さは、プラットフォームの上部 (Y) とスネイプの下部 (Y + 高さ) で機能する必要があります。

int tColDepth = 
    (SnapePosition.Y + SnapePosition.Height) - (plat[num].rectangle.Y);

底の深さは、プレイフォームの下部 (Y + 高さ) とスネイプの上部 (Y) で機能する必要があります。

int bColDepth = 
    (plat[num].rectangle.Y + plat[num].rectangle.Height) - (SnapePosition.Y);

適切な深さは、プラットフォームの左側 (X) とスネイプの右側 (X + 幅) で機能する必要があります。

int rColDepth = 
    (SnapePosition.X + SnapePosition.Width) - (plat[num].rectangle.X);

左の深さは、プラットフォームの右側 (X + 幅) とスネイプの左側 (X) で機能する必要があります。

int lColDepth = 
    (plat[num].rectangle.X + plat[num].rectangle.Width) - (SnapePosition.X);

これは今後機能します。ただし、プラットフォームにリストを使用することをお勧めします。「15 のプラットフォームが必要です」と言う必要がないため、レベル エディターを使用する場合は、リストの方が簡単です。

于 2012-10-21T12:37:07.327 に答える