所以我试图找出 XNA 中的边界框,但我遇到了一些麻烦。下面是我的代码。该程序仅由一个可以以 UDLR 方式移动的矩形对象(我只是使用了超级马里奥游戏中的 Thwomp 精灵)和一个随机生成的在屏幕上弹跳的框列表(我使用了问号框精灵,也来自马里奥)。我已经得到了盒子从 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);
}
}
}