C# XNA 2D矩形精灵键合盒

C# XNA 2D矩形精灵键合盒,c#,xna,collision-detection,bounding-box,C#,Xna,Collision Detection,Bounding Box,所以我试图找出XNA中的边界框,我遇到了一点小麻烦。下面是我的代码。该程序只是由一个矩形对象组成,你可以用UDLR方式移动(我刚刚使用了超级马里奥游戏中的一个Thwomp精灵)和一个随机生成的框列表,这些框在屏幕上跳跃(我使用了问号框精灵,同样来自马里奥)。我已经有了代码,可以知道盒子在什么地方反弹,而不是顶部和底部(它只是穿过精灵)。因此,现在边界框不是一个长方体,而是一个左右墙。我可以对我的代码做些什么来让盒子从Thwomp的顶部和底部反弹 谢谢 游戏类: using System; usi

所以我试图找出XNA中的边界框,我遇到了一点小麻烦。下面是我的代码。该程序只是由一个矩形对象组成,你可以用UDLR方式移动(我刚刚使用了超级马里奥游戏中的一个Thwomp精灵)和一个随机生成的框列表,这些框在屏幕上跳跃(我使用了问号框精灵,同样来自马里奥)。我已经有了代码,可以知道盒子在什么地方反弹,而不是顶部和底部(它只是穿过精灵)。因此,现在边界框不是一个长方体,而是一个左右墙。我可以对我的代码做些什么来让盒子从Thwomp的顶部和底部反弹

谢谢

游戏类:

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace BoundingBoxCollision
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{


    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;

    Sprite playerOne;

    static public int height;
    static public int width;

    static Random rand = new Random();

    KeyboardState keyboardState;

    List<Sprite> ballList = new List<Sprite>();
    int ballCount = 10;

    private void CheckPaddleWallCollision()
    {

    }


    private void CheckBallCollision(Sprite ball)
    {

        int MaxX =
            graphics.GraphicsDevice.Viewport.Width - ball.BoundingBox.Width;
        int MinX = 0;
        int MaxY =
            graphics.GraphicsDevice.Viewport.Height - ball.BoundingBox.Height;
        int MinY = 0;



        if (ball.BoundingBox.Intersects(playerOne.BoundingBox))
        {
            ball.Velocity.X *= -1;
            ball.Position += ball.Velocity;
        }

        if (ball.BoundingBox.Y > MaxY)
        {
            ball.Velocity.Y *= -1;
            ball.Position += ball.Velocity;
        }

        if (ball.BoundingBox.Y < MinY)
        {
            ball.Velocity.Y *= -1;
            ball.Position += ball.Velocity;
        }

        if (ball.BoundingBox.X < MinX)
        {
            ball.Velocity.X *= -1;
            ball.Position += ball.Velocity;
        }

        if (ball.BoundingBox.X > MaxX)
        {
            ball.Velocity.X *= -1;
            ball.Position += ball.Velocity;
        }
        /*if ((ball.Position.X < -ball.BoundingBox.Width)
            || (ball.Position.X > Window.ClientBounds.Width))
            SetInStartPostion(); */
    }

    /*private void SetInStartPostion()
    {
        playerOne.Position.Y = (
            Window.ClientBounds.Height -
            playerOne.BoundingBox.Height) / 2;


        ball.Position.X = playerOne.BoundingBox.Right + 1;

        ball.Position.Y = (
            Window.ClientBounds.Height -
            ball.BoundingBox.Height) / 2;

        ball.Velocity = new Vector2(8f, -8f);
    } */

    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        Content.RootDirectory = "Content";
    }

    /// <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

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

        height = GraphicsDevice.Viewport.Height;
        width = GraphicsDevice.Viewport.Width;

        Texture2D paddleTexture = Content.Load<Texture2D>("Thwomp");
        Vector2 position;

        position = new Vector2(
            100,
            (Window.ClientBounds.Height - paddleTexture.Height) / 2);
        playerOne = new Sprite(paddleTexture, position);

        position = new Vector2(
            (Window.ClientBounds.Width - paddleTexture.Width),
            (Window.ClientBounds.Height - paddleTexture.Height) / 2);

        Texture2D ballTexture = Content.Load<Texture2D>("QuestionMarkBlock");

        position = new Vector2(
                 playerOne.BoundingBox.Right + 1,
                 (Window.ClientBounds.Height - ballTexture.Height) / 2);

        for (int i = 0; i < ballCount; i++)
        {
            position = new Vector2(rand.Next(Game1.width), rand.Next(Game1.height));
            Sprite ball = new Sprite(
                     ballTexture,
                    position,
                     new Vector2(4f, -4f));
            ballList.Add(ball);
        }
    }


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



        keyboardState = Keyboard.GetState();

        if (keyboardState.IsKeyDown(Keys.Up))
            playerOne.Position.Y -= 4f;

        if (keyboardState.IsKeyDown(Keys.Down))
            playerOne.Position.Y += 4f;

        if (keyboardState.IsKeyDown(Keys.Left))
            playerOne.Position.X -= 4f;

        if (keyboardState.IsKeyDown(Keys.Right))
            playerOne.Position.X += 4f;



        foreach (Sprite block in ballList)
        {
            block.Position += block.Velocity;
            CheckBallCollision(block);

        }

        CheckPaddleWallCollision();



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

        spriteBatch.Begin();

        playerOne.Draw(spriteBatch);

        foreach (Sprite block in ballList)
        {
            block.Draw(spriteBatch);
        }

        spriteBatch.End();

        base.Draw(gameTime);
    }


    public static int vGameWidth { get; set; }
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;

namespace BoundingBoxCollision
{
public class Sprite
{



    Texture2D texture;
    public Vector2 Position;
    public Vector2 Velocity;


    public Rectangle BoundingBox
    {
        get
        {
            return new Rectangle(
                (int)Position.X,
                (int)Position.Y,
                texture.Width,
                texture.Height);
        }
    }

    public Sprite(Texture2D texture, Vector2 position)
    {
        this.texture = texture;
        this.Position = position;
    }

    public Sprite(Texture2D texture, Vector2 position, Vector2 velocity)
    {
        this.texture = texture;
        this.Position = position;
        this.Velocity = velocity;
    }



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

}
}

最简单的方法是:

if (ball.BoundingBox.Intersects(playerOne.BoundingBox))
        {
            ball.Velocity.X *= -1;
            ball.Velocity.Y *= -1;
            ball.Position += ball.Velocity;
        }
这将是一个完整的反映。如果您打算采用更现实的方式,您希望执行以下操作(伪代码):

  • 检查球和球员是否相撞
  • 确定它是在上/下、左/右还是在确切的拐角处碰撞
  • 左/右:
    ball.Velocity.X*=-1
  • 顶部/底部:
    ball.Velocity.Y*=-1
  • 角点:
    ball.Velocity.X*=-1&&
    ball.Velocity.Y*=-1
  • 我希望这有点帮助

    问候


    floAr

    最简单的方法是:

    if (ball.BoundingBox.Intersects(playerOne.BoundingBox))
            {
                ball.Velocity.X *= -1;
                ball.Velocity.Y *= -1;
                ball.Position += ball.Velocity;
            }
    
    这将是一个完整的反映。如果您打算采用更现实的方式,您希望执行以下操作(伪代码):

  • 检查球和球员是否相撞
  • 确定它是在上/下、左/右还是在确切的拐角处碰撞
  • 左/右:
    ball.Velocity.X*=-1
  • 顶部/底部:
    ball.Velocity.Y*=-1
  • 角点:
    ball.Velocity.X*=-1&&
    ball.Velocity.Y*=-1
  • 我希望这有点帮助

    问候

    floAr

    对于2号(顶部/底部),您可以使用

    player.BoundingBox.Top

    player.BoundingBox.Bottom

    .Top和.Bottom应返回矩形顶部或矩形底部的Y坐标。

    对于数字2(顶部/底部),您可以使用

    player.BoundingBox.Top

    player.BoundingBox.Bottom


    .Top和.Bottom应返回矩形顶部或矩形底部的Y坐标。

    谢谢!关于如何确定2号的联系点,有什么建议吗?谢谢!关于如何确定2号的接触点在哪里,有什么建议吗?