XNA 瞄准示例中的 StackOverflowException

发布于 2024-11-30 04:33:56 字数 4929 浏览 5 评论 0原文

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

这是触发错误的特定行:

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

最奇怪的部分是,所有这些都是直接从 AppHub 瞄准示例。据我所知,除了变量名称之外,我没有更改任何内容。

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. 列表项

Basically, I am getting this error "An unhandled exception of type 'System.StackOverflowException' occurred in Sortie.exe."
I understand the reason for the error, that I'm getting a method to call another method that then calls the first method (or something similar to that) so an infinite loop is created.

Here is the specific line that triggers the error:

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

The weirdest part is, all of this is, all of this copied straight from the AppHub aiming sample. To the best of my knowledge, I haven't changed anything besides the variable names.

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. List item

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

铁憨憨 2024-12-07 04:33:56

您似乎在 Update 本身内部调用 Update(gametime) 。这几乎肯定会无限递归,直到堆栈已满。

You seem to be calling Update(gametime) inside of Update itself. this will almost definetly recurse infintely until the stack is full.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文