我需要帮助解决这个问题。我已经采用了代码示例TankOnAHeightmap,现在我在鼠标光标所在的位置创建了一个选择框,但是我无法选择坦克。 这是代码。
`
GraphicsDeviceManager graphics;
SpriteBatch mSpriteBatch;
Texture2D mDottedLine;
Rectangle mSelectionBox;
MouseState mPreviousMouseState;
Model terrain;
Tank tank;
Matrix projectionMatrix;
Matrix viewMatrix;
HeightMapInfo heightMapInfo;
public TanksOnAHeightmapGame()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
tank = new Tank();
}
protected override void Initialize()
{
// now that the GraphicsDevice has been created, we can create the projection matrix.
projectionMatrix = Matrix.CreatePerspectiveFieldOfView(
MathHelper.ToRadians(45.0f), GraphicsDevice.Viewport.AspectRatio, 1f, 10000);
this.IsMouseVisible = true;
//Initialize the Selection box's rectangle. Currently no selection box is drawn
//so set it's x and y position to -1 and it's height and width to 0
mSelectionBox = new Rectangle(-1, -1, 0, 0);
//Initialize the previous mouse state. This stores the current state of the mouse
mPreviousMouseState = Mouse.GetState();
base.Initialize();
}
/// <summary>
/// Load your graphics content.
/// </summary>
protected override void LoadContent()
{
mSpriteBatch = new SpriteBatch(GraphicsDevice);
terrain = Content.Load<Model>("terrain");
mDottedLine = Content.Load<Texture2D>("DottedLine");
heightMapInfo = terrain.Tag as HeightMapInfo;
if (heightMapInfo == null)
{
string message = "The terrain model did not have a HeightMapInfo " +
"object attached. Are you sure you are using the " +
"TerrainProcessor?";
throw new InvalidOperationException(message);
}
tank.LoadContent(Content);
}
/// <summary>
/// Allows the game to run logic.
/// </summary>
protected override void Update(GameTime gameTime)
{
HandleInput();
UpdateCamera();
base.Update(gameTime);
}
/// <summary>
/// this function will calculate the camera's position and the position of
/// its target. From those, we'll update the viewMatrix.
/// </summary>
private void UpdateCamera()
{
// once we've transformed the camera's position offset vector, it's easy to
// figure out where we think the camera should be.
Vector3 cameraPosition = Position;
// We don't want the camera to go beneath the heightmap, so if the camera is
// over the terrain, we'll move it up.
// next, we need to calculate the point that the camera is aiming it. That's
// simple enough - the camera is aiming at the tank, and has to take the
// targetOffset into account.
Vector3 cameraTarget = Target;
// with those values, we'll calculate the viewMatrix.
viewMatrix = Matrix.CreateLookAt(cameraPosition,
cameraTarget,
Vector3.Up);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice device = graphics.GraphicsDevice;
GraphicsDevice.Clear(Color.Black);
GraphicsDevice.BlendState = BlendState.Opaque;
GraphicsDevice.DepthStencilState = DepthStencilState.Default;
GraphicsDevice.SamplerStates[0] = SamplerState.LinearWrap;
device.Clear(Color.Black);
DrawModel(terrain);
tank.Draw(viewMatrix, projectionMatrix);
mSpriteBatch.Begin();
//Draw the horizontal portions of the selection box
DrawHorizontalLine(mSelectionBox.Y);
DrawHorizontalLine(mSelectionBox.Y + mSelectionBox.Height);
//Draw the vertical portions of the selection box
DrawVerticalLine(mSelectionBox.X);
DrawVerticalLine(mSelectionBox.X + mSelectionBox.Width);
//End the drawing with the batch
mSpriteBatch.End();
// If there was any alpha blended translucent geometry in
// the scene, that would be drawn here.
base.Draw(gameTime);
}
/// <summary>
/// Helper for drawing the terrain model.
/// </summary>
void DrawModel(Model model)
{
Matrix[] boneTransforms = new Matrix[model.Bones.Count];
model.CopyAbsoluteBoneTransformsTo(boneTransforms);
foreach (ModelMesh mesh in model.Meshes)
{
foreach (BasicEffect effect in mesh.Effects)
{
effect.World = boneTransforms[mesh.ParentBone.Index];
effect.View = viewMatrix;
effect.Projection = projectionMatrix;
effect.EnableDefaultLighting();
effect.PreferPerPixelLighting = true;
// Set the fog to match the black background color
effect.FogEnabled = true;
effect.FogColor = Vector3.Zero;
effect.FogStart = 1000;
effect.FogEnd = 3200;
}
mesh.Draw();
}
}
#endregion
private void DrawVerticalLine(int thePositionX)
{
//When the height is greater than 0, the user is selecting an area below the starting point
if (mSelectionBox.Height > 0)
{
//Draw the line starting at the starting location and moving down
for (int aCounter = -2; aCounter <= mSelectionBox.Height; aCounter += 10)
{
if (mSelectionBox.Height - aCounter >= 0)
{
mSpriteBatch.Draw(mDottedLine, new Rectangle(thePositionX,
mSelectionBox.Y + aCounter, 10, 5),
new Rectangle(0, 0, mDottedLine.Width, mDottedLine.Height),
Color.White, MathHelper.ToRadians(90), new Vector2(0, 0), SpriteEffects.None, 0);
}
}
}
//When the height is less than 0, the user is selecting an area above the starting point
else if (mSelectionBox.Height < 0)
{
//Draw the line starting at the start location and moving up
for (int aCounter = 0; aCounter >= mSelectionBox.Height; aCounter -= 10)
{
if (mSelectionBox.Height - aCounter <= 0)
{
mSpriteBatch.Draw(mDottedLine, new Rectangle(thePositionX - 10, mSelectionBox.Y + aCounter, 10, 5), Color.White);
}
}
}
}
private void DrawHorizontalLine(int thePositionY)
{
//When the width is greater than 0, the user is selecting an area to the right of the starting point
if (mSelectionBox.Width > 0)
{
//Draw the line starting at the starting location and moving to the right
for (int aCounter = 0; aCounter <= mSelectionBox.Width - 10; aCounter += 10)
{
if (mSelectionBox.Width - aCounter >= 0)
{
mSpriteBatch.Draw(mDottedLine, new Rectangle(mSelectionBox.X + aCounter, thePositionY, 10, 5), Color.White);
}
}
}
//When the width is less than 0, the user is selecting an area to the left of the starting point
else if (mSelectionBox.Width < 0)
{
//Draw the line starting at the starting location and moving to the left
for (int aCounter = -10; aCounter >= mSelectionBox.Width; aCounter -= 10)
{
if (mSelectionBox.Width - aCounter <= 0)
{
mSpriteBatch.Draw(mDottedLine, new Rectangle(mSelectionBox.X + aCounter, thePositionY, 10, 5), Color.White);
}
}
}
}
#region Handle Input
/// <summary>
/// Handles input for quitting the game.
/// </summary>
private void HandleInput()
{
MouseState aMouse = Mouse.GetState();
//If the user has just clicked the Left mouse button, then set the start location for the Selection box
if (aMouse.LeftButton == ButtonState.Pressed && mPreviousMouseState.LeftButton == ButtonState.Released)
{
//Set the starting location for the selection box to the current location
//where the Left button was initially clicked.
mSelectionBox = new Rectangle(aMouse.X, aMouse.Y, 0, 0);
}
//If the user is still holding the Left button down, then continue to re-size the
//selection square based on where the mouse has currently been moved to.
if (aMouse.LeftButton == ButtonState.Pressed)
{
//The starting location for the selection box remains the same, but increase (or decrease)
//the size of the Width and Height but taking the current location of the mouse minus the
//original starting location.
mSelectionBox = new Rectangle(mSelectionBox.X, mSelectionBox.Y, aMouse.X - mSelectionBox.X, aMouse.Y - mSelectionBox.Y);
}
//If the user has released the left mouse button, then reset the selection square
if (aMouse.LeftButton == ButtonState.Released)
{
//Reset the selection square to no position with no height and width
mSelectionBox = new Rectangle(-1, -1, 0, 0);
}
//Store the previous mouse state
mPreviousMouseState = aMouse;
KeyboardState currentKeyboardState = Keyboard.GetState();
GamePadState currentGamePadState = GamePad.GetState(PlayerIndex.One);
// Check for exit.
if (currentKeyboardState.IsKeyDown(Keys.Escape) ||
currentGamePadState.Buttons.Back == ButtonState.Pressed)
{
Exit();
}
tank.HandleInput(currentGamePadState, currentKeyboardState, heightMapInfo);
}
我尝试创建一个边界框但是我似乎无法将盒子绑在坦克上并在左键单击表面时移动它。