我需要帮助解决这个问题。我已经获取了一个代码示例 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);
}
我尝试创建一个边界框,但我似乎无法将框系在水箱上并在左键单击表面时移动它。