XNA瞄准示例中的StackOverflowException

时间:2011-08-18 16:43:17

标签: c# xna stack-overflow

基本上,我收到此错误“Sortie.exe中发生了'System.StackOverflowException'类型的未处理异常。” 我理解错误的原因,我得到一个方法来调用另一个方法,然后调用第一个方法(或类似的方法),这样就创建了一个无限循环。

以下是触发错误的具体行:

            float desiredAngle = (float)Math.Atan2(y, x);

最奇怪的部分是,所有这些都是直接从AppHub aiming sample复制的。据我所知,除了变量名之外,我没有改变任何东西。

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 Sortie
{
/// <summary>
/// Sniper drones.  
/// </summary>
class Deadeye 
{
    //Vector2 m_DeadeyeSpeed; 
    Vector2 m_DeadeyePosition;
    Vector2 m_DeadeyeOrigin; 
    Texture2D m_DeadeyeTexture;
    double m_DeadeyeRotation; 

    #region Constants 
    const float Speed = 11.0f; 
    const float Lifespan = 600; 
    const float TurnSpeed = 0.04f; 
    #endregion

    #region Constructor
    public Deadeye(Texture2D texture, Vector2 position)
    {
        m_DeadeyeTexture = texture; 
        m_DeadeyePosition = position;
        m_DeadeyeOrigin.X = texture.Width / 2;
        m_DeadeyeOrigin.Y = texture.Height / 2; 
    }
    #endregion 

    public void Update(GameTime gameTime)
    {
        // use the TurnToFace function to update the spotlightAngle to face
        // towards the cat.
        m_DeadeyeRotation = TurnToFace(m_DeadeyePosition, Game1.m_Player.PlayerPosition /*Game1.playerPositionMirror*/, (float)m_DeadeyeRotation,
            TurnSpeed); 

        Update(gameTime); 
    }

    /// <summary>
    /// Calculates the angle that an object should face, given its position, its
    /// target's position, its current angle, and its maximum turning speed.
    /// </summary>
    private static float TurnToFace(Vector2 position, Vector2 faceThis,
        float currentAngle, float turnSpeed)
    {
        // consider this diagram:
        //         C 
        //        /|
        //      /  |
        //    /    | y
        //  / o    |
        // S--------
        //     x
        // 
        // where S is the position of the spot light, C is the position of the cat,
        // and "o" is the angle that the spot light should be facing in order to 
        // point at the cat. we need to know what o is. using trig, we know that
        //      tan(theta)       = opposite / adjacent
        //      tan(o)           = y / x
        // if we take the arctan of both sides of this equation...
        //      arctan( tan(o) ) = arctan( y / x )
        //      o                = arctan( y / x )
        // so, we can use x and y to find o, our "desiredAngle."
        // x and y are just the differences in position between the two objects.
        float x = faceThis.X - position.X;
        float y = faceThis.Y - position.Y;

        // we'll use the Atan2 function. Atan will calculates the arc tangent of 
        // y / x for us, and has the added benefit that it will use the signs of x
        // and y to determine what cartesian quadrant to put the result in.
        // http://msdn2.microsoft.com/en-us/library/system.math.atan2.aspx
        float desiredAngle = (float)Math.Atan2(y, x);

        // so now we know where we WANT to be facing, and where we ARE facing...
        // if we weren't constrained by turnSpeed, this would be easy: we'd just 
        // return desiredAngle.
        // instead, we have to calculate how much we WANT to turn, and then make
        // sure that's not more than turnSpeed.

        // first, figure out how much we want to turn, using WrapAngle to get our
        // result from -Pi to Pi ( -180 degrees to 180 degrees )
        float difference = WrapAngle(desiredAngle - currentAngle);

        // clamp that between -turnSpeed and turnSpeed.
        difference = MathHelper.Clamp(difference, -turnSpeed, turnSpeed);

        // so, the closest we can get to our target is currentAngle + difference.
        // return that, using WrapAngle again.
        return WrapAngle(currentAngle + difference);
    }

    /// <summary>
    /// Returns the angle expressed in radians between -Pi and Pi.
    /// </summary>
    private static float WrapAngle(float radians)
    {
        while (radians < -MathHelper.Pi)
        {
            radians += MathHelper.TwoPi;
        }
        while (radians > MathHelper.Pi)
        {
            radians -= MathHelper.TwoPi;
        }
        return radians;
    }

    public void Draw(SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(m_DeadeyeTexture, m_DeadeyePosition, null, Color.White, (float)m_DeadeyeRotation, m_DeadeyeOrigin, 1.0f, SpriteEffects.None, 0f); 
    }
}
}
  1. 列表项

1 个答案:

答案 0 :(得分:4)

您似乎在Update内部调用Update(游戏时间)。这将几乎完全无情地递归到堆栈已满。