StackOverflowException in XNA Aiming Sample
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 开发者_StackOverflow社区
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);
}
}
}
- List item
You seem to be calling Update(gametime) inside of Update itself. this will almost definetly recurse infintely until the stack is full.
精彩评论