0

我需要帮助解决这个问题。我已经获取了一个代码示例 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);


    }

我尝试创建一个边界框,但我似乎无法将框系在水箱上并在左键单击表面时移动它。

4

0 回答 0