不知道如何修复此StackOverflowexception是未处理的错误

第一次在这里发帖,我知道我可能会对我的编码感到沮丧,但我是12年级的学生并且为我的软件专业自学这门语言,我今天才开始理解课程,所以我试着重新做游戏中的这种游戏还远没有完成。 抱歉很长的代码,但我真的无法弄清楚什么是错的,在game1.cs只是player.LoadContent(内容),player.Update(gameTime)和player.Draw(spriteBatch),玩家是对象对于Player_Main类。

namespace HonourInBlood { public class Player_Main //This class deals with updating all other classes { public Player_Sprite psprite = new Player_Sprite(); public Player_Movement pmove = new Player_Movement(); public Player_Stats pstats = new Player_Stats(); public Player_Abilities pabilities = new Player_Abilities(); public Player_Controls pcontrols = new Player_Controls(); public Player_Main() { } public void Update(GameTime gameTime) { psprite.Update(gameTime); pmove.Update(gameTime); pstats.Update(gameTime); pabilities.Update(gameTime); } public void LoadContent(ContentManager Content) { psprite.LoadContent(Content); } public void Draw(SpriteBatch spriteBatch) { psprite.Draw(spriteBatch); } } public class Player_Sprite //This class deals with drawing the players sprite and animations { public Rectangle player; public Texture2D playerAttack, playerWalk; //PLAYER TEXTURES public Player_Main pmain = new Player_Main(); public Player_Sprite() { } public void Update(GameTime gameTime) { } public void LoadContent(ContentManager Content) { player = new Rectangle(0, 0, 64, 64); playerAttack = Content.Load("player_attack_large"); playerWalk = Content.Load("player_move_large"); } public void Draw(SpriteBatch spriteBatch) { spriteBatch.Draw(playerWalk, pmain.pmove.position, new Rectangle(0, 0, 64, 64), Color.White); } } public class Player_Movement //This class deals with all movement relating to the player ie sprinting { public Vector2 position, velocity, velocity_base, sprint; public Player_Main pmain = new Player_Main(); Game1 gamecore = new Game1(); public Player_Movement() { } public void Update(GameTime gameTime) { KeyboardState KS = Keyboard.GetState(); //Player movement using arrow keys if (KS.IsKeyDown(Keys.Up)) position.Y -= velocity.Y; if (KS.IsKeyDown(Keys.Down)) position.Y += velocity.Y; if (KS.IsKeyDown(Keys.Right)) position.X += velocity.X; if (KS.IsKeyDown(Keys.Left)) position.X -= velocity.X; //Making edge of screen stop player movement to prevent going off-screen if (position.X < 0) position.X = 0; if (position.Y  gamecore.GraphicsDevice.Viewport.Width) position.X = gamecore.GraphicsDevice.Viewport.Width - pmain.psprite.player.Width; if (position.Y + pmain.psprite.player.Height > gamecore.GraphicsDevice.Viewport.Height) position.Y = gamecore.GraphicsDevice.Viewport.Height - pmain.psprite.player.Height; // //SPRINTING if (KS.IsKeyDown(pmain.pcontrols.sprintKey)) { if (KS.IsKeyDown(Keys.Up) || KS.IsKeyDown(Keys.Down) || KS.IsKeyDown(Keys.Right) || KS.IsKeyDown(Keys.Left)) //You're only sprinting when you're moving, right? { if (pmain.pstats.currentStamina > 0) //Only when you have stamina can you run { velocity.X += sprint.X; velocity.Y += sprint.X; pmain.pstats.currentStamina -= pmain.pstats.stamina; //Decreases stamina } } } // // //SPRINTING if (pmain.pstats.currentStamina > 0) { if (velocity.X > velocity_base.X) //When current velocity becomes greater than base velocity check whether space bar is released { if (KS.IsKeyUp(pmain.pcontrols.sprintKey)) velocity.X = velocity_base.X; //If it is, set current velocity back to base } if (velocity.Y > velocity_base.Y) { if (KS.IsKeyUp(pmain.pcontrols.sprintKey)) velocity.Y = velocity_base.Y; } if (velocity.X > velocity_base.X + sprint.X) velocity.X = velocity_base.X + sprint.X; if (velocity.Y > velocity_base.Y + sprint.Y) velocity.Y = velocity_base.Y + sprint.Y; // } if (pmain.pstats.currentStamina  maxStamina) //Cant have more stamina than the max now, can we? currentStamina = maxStamina; if (currentMana > maxMana) currentMana = maxMana; } public void LoadContent(ContentManager Content) { } public void Draw(SpriteBatch spriteBatch) { } } public class Player_Abilities //This class deals with all abilities the player has { public double spellCD1, spell1Cost, spellDisplay1; Player_Controls pcontrols = new Player_Controls(); Player_Stats pstats = new Player_Stats(); Player_Movement pmove = new Player_Movement(); HUD HUDmain = new HUD(); public Player_Abilities() { spellCD1 = 150; spell1Cost = 120; } public void Update(GameTime gameTime) { KeyboardState KS = Keyboard.GetState(); //MANA AND SPELL STUFF/////////////////////////////// if (KS.IsKeyDown(pcontrols.spellKey1)) { if (pstats.currentMana >= spell1Cost) { if (spellCD1 <= 0) { if (KS.IsKeyDown(Keys.Up)) pmove.position.Y -= 300; if (KS.IsKeyDown(Keys.Down)) pmove.position.Y += 300; if (KS.IsKeyDown(Keys.Right)) pmove.position.X += 300; if (KS.IsKeyDown(Keys.Left)) pmove.position.X -= 300; pstats.mana = spell1Cost; pstats.currentMana -= pstats.mana; spellCD1 = 150; } } } spellCD1--; spellDisplay1 = spellCD1 / 60; spellDisplay1 = Math.Round(spellDisplay1, 1); if (spellCD1 <= 0) spellCD1 = 0; } public void LoadContent(ContentManager Content) { } public void Draw(SpriteBatch spriteBatch) { spriteBatch.DrawString(HUDmain.HUDFont, "Ability: Cooldown", new Vector2(20, 40), Color.White); spriteBatch.DrawString(HUDmain.HUDFont, "Teleport: " + spellDisplay1 + "s", new Vector2(20, 60), Color.White); } } public class Player_Controls //This class deals with the controls { public Keys sprintKey, spellKey1; public Player_Controls() { sprintKey = Keys.LeftShift; spellKey1 = Keys.D1; } public void Update(GameTime gameTime) { } public void LoadContent(ContentManager Content) { } } } 

这是调用堆栈:

HonourInBlood.exe!HonourInBlood.Player_Sprite.Player_Sprite()第45行+ 0xffffffe6字节C#HonourInBlood.exe!HonourInBlood.Player_Main.Player_Main()第14行+ 0x15字节C#HonourInBlood.exe!HonourInBlood.Player_Sprite.Player_Sprite()第45行+ 0x15字节C#HonourInBlood.exe!HonourInBlood.Player_Main.Player_Main()第14行+ 0x15字节C#HonourInBlood.exe!HonourInBlood.Player_Sprite.Player_Sprite()第45行+ 0x15字节C#HonourInBlood.exe!HonourInBlood.Player_Main.Player_Main()第14行+ 0x15 bytes C#HonourInBlood.exe!HonourInBlood.Player_Sprite.Player_Sprite()第45行+ 0x15字节C#

它以这种方式重复,直到:

 The maximum number of stack frames supported by Visual Studio has been exceeded. 

这是一个新问题(对于Chris Ballard):

在我改变了所有地方的代码之后,我比以前更加困惑,我有一个HUD.cs文件,它引用Player.cs文件中的Player_Stats类来获取变量,但我不能,因为:

 'HonourInBlood.Player_Stats' does not contain a constructor that takes 0 arguments 

如果您浏览代码,查看每个类的开头,您可以看到只有一个引用网络现在导致问题,因为我将其更改为您向我展示的方式。

好的 – 我看到了问题。

每次创建Player_Main – 它都有一个创建新Player_Sprite的字段

Player_Sprite本身有一个字段,可以创建另一个新的Player_Main

这反过来会永久地创建一个新的Player_Sprite等(或者至少在你的堆栈溢出之前)

编辑

我猜你想要一个Player_Main ,它保留对Player_Sprite的引用,而Player_Sprite需要记住创建它的Player_Main (不创建一个新的)。 就像是:

 public class Player_Main { public Player_Sprite psprite; public Player_Main() { psprite = new Player_Sprite(this); } } public class Player_Sprite { public Player_Main _pmain; public Player_Sprite(Player_Main pmain) { _pmain = pmain; } } 

关于第二个问题。 我怀疑你已经更新了Player_Stats类以在构造函数中接受Player_Main

对于Player_Stats这不是必需的。 这是因为Player_Stats中的所有代码Player_Stats 需要访问Player_Stats方法或属性。 Player_ControlsPlayer_AbilitiesPlayer_Movements也是如此

它只在Player_Sprite需要,因为Draw方法访问pmain.pmove.position

在我写这篇文章时,我想到也许更好的实现只是将位置传递给Draw方法,因此:

 public class Player_Sprite //This class deals with drawing the players sprite and animations { public Rectangle player; public Texture2D playerAttack, playerWalk; //PLAYER TEXTURES public Player_Sprite() { } // .. methods removed for brevity public void Draw(SpriteBatch spriteBatch, Player_Movement pmove) { spriteBatch.Draw(playerWalk, pmove.position, new Rectangle(0, 0, 64, 64), Color.White); } } 

因此, Player_Main.Draw变为:

 public void Draw(SpriteBatch spriteBatch) { psprite.Draw(spriteBatch, pmove); } 

而且你不再需要将它传递给Player_Sprite构造函数。

编辑修改了Player_Movement

 public class Player_Movement //This class deals with all movement relating to the player ie sprinting { public Vector2 position, velocity, velocity_base, sprint; public Player_Main pmain = null; Game1 gamecore = new Game1(); public Player_Movement(Player_Main pmain) { this.pmain = pmain; } public void Update(GameTime gameTime) { KeyboardState KS = Keyboard.GetState(); //Player movement using arrow keys if (KS.IsKeyDown(Keys.Up)) position.Y -= velocity.Y; if (KS.IsKeyDown(Keys.Down)) position.Y += velocity.Y; if (KS.IsKeyDown(Keys.Right)) position.X += velocity.X; if (KS.IsKeyDown(Keys.Left)) position.X -= velocity.X; //Making edge of screen stop player movement to prevent going off-screen if (position.X < 0) position.X = 0; if (position.Y < 0) position.Y = 0; if (position.X + pmain.psprite.player.Width > gamecore.GraphicsDevice.Viewport.Width) position.X = gamecore.GraphicsDevice.Viewport.Width - pmain.psprite.player.Width; if (position.Y + pmain.psprite.player.Height > gamecore.GraphicsDevice.Viewport.Height) position.Y = gamecore.GraphicsDevice.Viewport.Height - pmain.psprite.player.Height; // //SPRINTING if (KS.IsKeyDown(pmain.pcontrols.sprintKey)) { if (KS.IsKeyDown(Keys.Up) || KS.IsKeyDown(Keys.Down) || KS.IsKeyDown(Keys.Right) || KS.IsKeyDown(Keys.Left)) //You're only sprinting when you're moving, right? { if (pmain.pstats.currentStamina > 0) //Only when you have stamina can you run { velocity.X += sprint.X; velocity.Y += sprint.X; pmain.pstats.currentStamina -= pmain.pstats.stamina; //Decreases stamina } } } // // //SPRINTING if (pmain.pstats.currentStamina > 0) { if (velocity.X > velocity_base.X) //When current velocity becomes greater than base velocity check whether space bar is released { if (KS.IsKeyUp(pmain.pcontrols.sprintKey)) velocity.X = velocity_base.X; //If it is, set current velocity back to base } if (velocity.Y > velocity_base.Y) { if (KS.IsKeyUp(pmain.pcontrols.sprintKey)) velocity.Y = velocity_base.Y; } if (velocity.X > velocity_base.X + sprint.X) velocity.X = velocity_base.X + sprint.X; if (velocity.Y > velocity_base.Y + sprint.Y) velocity.Y = velocity_base.Y + sprint.Y; // } if (pmain.pstats.currentStamina <= 0) //When you run out of stamina, set speed to normal { velocity.X = velocity_base.X; velocity.Y = velocity_base.Y; pmain.pstats.currentStamina = 0; } } public void LoadContent(ContentManager Content) { position = new Vector2(400, 300); velocity = new Vector2(4, 4); //Current velocity velocity_base = new Vector2(4, 4); //Base velocity sprint = new Vector2(6, 6); //Added velocity when sprinting } public void Draw(SpriteBatch spriteBatch) { } } 

在您的Player_Main构造函数中,执行以下操作:

 public class Player_Main //This class deals with updating all other classes { public Player_Sprite psprite = new Player_Sprite(); public Player_Movement pmove = null; public Player_Stats pstats = new Player_Stats(); public Player_Abilities pabilities = new Player_Abilities(); public Player_Controls pcontrols = new Player_Controls(); public Player_Main() { pmove = new Player_Movement(this); } // ... rest removed for brevity }