C# XNA 4.0游戏在运行时添加精灵时崩溃

C# XNA 4.0游戏在运行时添加精灵时崩溃,c#,windows-phone-8,xna,C#,Windows Phone 8,Xna,我对编程比较陌生(这是一种爱好),尤其是C#,我正在尝试为WindowsPhone8开发一个简单的XNA4.0版snake游戏克隆 我遇到了一个相当奇怪的问题,当我运行以下代码时,游戏会在我的设备(以及模拟器)上崩溃,但VS窗口显示它正在运行。这个问题似乎与内存无关,我通过运行profiler工具检查了这个问题 当我试图在蛇与食物相撞时向蛇添加一个单位时,就会出现错误。我曾尝试在Update()中内联使用负责的代码,并将其作为Game1类中的一个单独函数使用,但两者都有相同的问题。非常感谢您的帮

我对编程比较陌生(这是一种爱好),尤其是C#,我正在尝试为WindowsPhone8开发一个简单的XNA4.0版snake游戏克隆

我遇到了一个相当奇怪的问题,当我运行以下代码时,游戏会在我的设备(以及模拟器)上崩溃,但VS窗口显示它正在运行。这个问题似乎与内存无关,我通过运行profiler工具检查了这个问题

当我试图在蛇与食物相撞时向蛇添加一个单位时,就会出现错误。我曾尝试在Update()中内联使用负责的代码,并将其作为Game1类中的一个单独函数使用,但两者都有相同的问题。非常感谢您的帮助

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.Input.Touch;
using Microsoft.Xna.Framework.Media;

namespace aaaSnake_1
{
public class Game1 : Microsoft.Xna.Framework.Game
///////////////////////////////////
{
    GraphicsDeviceManager graphics;
    SpriteBatch spriteBatch;
    SpriteManager spriteManager;

    foodunits food;
    List<snakeunits> snake = new List<snakeunits>();



    public Game1()
    {
        graphics = new GraphicsDeviceManager(this);
        graphics.IsFullScreen = true;
        Content.RootDirectory = "Content";

        // Frame rate is 30 fps by default for Windows Phone.
        TargetElapsedTime = TimeSpan.FromTicks(333333 *2);

        // Extend battery life under lock.
        InactiveSleepTime = TimeSpan.FromSeconds(1);


    }


    protected override void Initialize()
    {
        TouchPanel.EnabledGestures = GestureType.VerticalDrag | GestureType.HorizontalDrag;
        //spriteManager = new SpriteManager(this);
        //Components.Add(spriteManager); // Avoid the goddamn spritemanager like hell
        //grow(snake);

        base.Initialize();
    }


    protected override void LoadContent()
    {
        spriteBatch = new SpriteBatch(GraphicsDevice);
        food = new foodunits(Content.Load<Texture2D>(@"Textures/block"), new Vector2(300, 300), 50, new Vector2(0, 0));
        snake.Add(new snakeunits(Content.Load<Texture2D>(@"Textures/block"), new Vector2(50, 300), 10, new Vector2(10, 0)));
    }



    protected override void UnloadContent()
    {
    }


    protected override void Update(GameTime gameTime)
    {
        if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
            this.Exit();
        // code for the touch part


        Boolean IsHead = true;
        Vector2 PreviousUnitSpeed = new Vector2(0, 0);
        Vector2 PreviousUnitPosition = new Vector2(0, 0);

        //snake update
        foreach (units unit in snake)
        {
            PreviousUnitPosition = unit.position;
            PreviousUnitSpeed = unit.speed;

            //update the head directions
            if (IsHead == true)
            {   // Head = Needs special consideration with respect to direction
                IsHead = false;
                if (TouchPanel.IsGestureAvailable)
                {
                    GestureSample gesture = TouchPanel.ReadGesture();
                    switch (gesture.GestureType)
                    {
                        case GestureType.HorizontalDrag:
                            if (Math.Sign(gesture.Delta.X) != 0)
                            {
                                unit.speed.X = 10f * Math.Sign(gesture.Delta.X);
                                unit.speed.Y = 0f;
                            }
                            break;

                        case GestureType.VerticalDrag:
                            if (Math.Sign(gesture.Delta.Y) != 0)
                            {
                                unit.speed.Y = 10f * Math.Sign(gesture.Delta.Y);
                                unit.speed.X = 0f;
                            }
                            break;

                        default:
                            break;
                    }
                }

                // grow snake if needed
                if (unit.position == food.position)
                {
                    Random X = new Random();
                    Random Y = new Random();
                    food.position.X = (float) Math.Floor(X.Next(0, Window.ClientBounds.Height - 10)/10) * 10;
                    food.position.Y = (float) Math.Floor(Y.Next(0, Window.ClientBounds.Width - 10)/10) * 10;
                    //snake.Add(new snakeunits(
                    //    Content.Load<Texture2D>(@"Textures/block"),
                    //    PreviousUnitPosition, 10, PreviousUnitSpeed));

                    /// debug
                    snake.Add(new snakeunits(Content.Load<Texture2D>(@"Textures/block"), new Vector2(100, 100), 10, new Vector2(0, 10)));
                    //grow(snake);
                    /// debug ends 
                }

            }


            unit.position += unit.speed;
            // temporary hacks to not let the game exit on crash - bounce back for now
            if (unit.position.X > Window.ClientBounds.Height - 10f || unit.position.X < 0)    // 10f is simply the block size in pixels
            {
                unit.speed.X *= -1;
            }
            if (unit.position.Y > Window.ClientBounds.Width - 10f || unit.position.Y < 0)
            {
                unit.speed.Y *= -1;
            }
            // temporrary hacks end


        }


        //direction of head
        // rest follow head
        // ate food ?


        base.Update(gameTime);
    }


    protected override void Draw(GameTime gameTime)
    {
        GraphicsDevice.Clear(Color.Turquoise);
        spriteBatch.Begin();
        food.Draw(gameTime, spriteBatch);
        foreach (units unit in snake)
            unit.Draw(gameTime, spriteBatch);
        spriteBatch.End();
        base.Draw(gameTime);
    }

    private void grow(List<units> snake)
    {
        snake.Add(new snakeunits(Content.Load<Texture2D>(@"Textures/block"), new Vector2(100, 100), 10, new Vector2(0, 10)));
    }

}

}

非常感谢您的帮助。多谢各位

编辑:没有任何类型的明确错误-游戏只是退出设备/模拟器上的HOMSE屏幕,但VS仍显示程序正在运行(暂停、停止按钮处于活动状态)

编辑2:

解决了,但还没有完全解决

添加了一个布尔标志,而不是尝试在头部的
if
循环中添加蛇形单位。然后使用布尔值添加单位,就在
base.update()上方呼叫:-

if (unit.position == food.position)
                {
                    ShouldGrow = true;
                    Random X = new Random();
                    Random Y = new Random();
                    food.position.X = (float)Math.Floor(X.Next(0, Window.ClientBounds.Height - 10) / 10) * 10;
                    food.position.Y = (float)Math.Floor(Y.Next(0, Window.ClientBounds.Width - 10) / 10) * 10;
                }


尝试加载loadcontent中的所有纹理。例如:

Texture2d snaketexture;

protected override void LoadContent()
{
   snaketexture = Content.Load<Texture2D>(@"Textures/block");
}

protected override void Update(GameTime gameTime)
{
   snake.Add(new snakeunits(snaketexture, new Vector2(100, 100), 10, new Vector2(0, 10)))
}
这就是将snake.add移动到函数底部时问题得以解决的原因。您可以通过创建一个临时列表来解决这个问题,然后在迭代完snake列表后,将临时列表附加到snake列表中

List<snakeunits>tmpList = new List<snakeunits>();
foreach (units unit in snake)
{
     tmpList.Add(new snakeunits(snaketexture, new Vector2(100, 100), 10, new Vector2(0, 10)))
}

snake.AddRange(tmpList);
ListtmpList=newlist();
foreach(snake中的单位)
{
tmpList.Add(新蛇单位(蛇纹,新向量2(100100),10,新向量2(0,10)))
}
snake.AddRange(tmpList);

这没有帮助,但肯定是一种更好的编码方式。仍在调试手头的问题…我在这个问题中已经绕过了这个问题,但我不知道为什么/如何。在问题末尾添加了变通方法。我对编程这个词的任何严肃意义都是新手,出于某种原因,VS甚至不允许我在变量中添加手表。所有这些都要归结到使用
System.Diagnostics.Debug.WriteLine()
,但是这会减慢仿真器的速度。非常感谢。从我的角度看,这是相当愚蠢的我也一定会看看关于调试的文章。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;

namespace aaaSnake_1
{
class snakeunits : units
{
    public snakeunits(Texture2D textureImage,
              Vector2 position,
              int collisionOffset,
              Vector2 speed)
        : base(textureImage, position, collisionOffset, speed)
    {
    }

    public snakeunits(Texture2D textureImage,
              Vector2 position,
              int collisionOffset,
              Vector2 speed,
              int millisecondsPerFrame)
        : base(textureImage, position, collisionOffset, speed, millisecondsPerFrame)
    {
    }

    public override Vector2 direction
    {
        get { return speed; }
    }




}
}
if (unit.position == food.position)
                {
                    ShouldGrow = true;
                    Random X = new Random();
                    Random Y = new Random();
                    food.position.X = (float)Math.Floor(X.Next(0, Window.ClientBounds.Height - 10) / 10) * 10;
                    food.position.Y = (float)Math.Floor(Y.Next(0, Window.ClientBounds.Width - 10) / 10) * 10;
                }
        if (ShouldGrow)
        {
            System.Diagnostics.Debug.WriteLine("Entering snake growth");
            snake.Add(new snakeunits(snakeskin, PreviousUnitPosition2, 10, new Vector2 (0f,0f)));
            System.Diagnostics.Debug.WriteLine("Exiting snake growth");
        }
            base.Update(gameTime);
Texture2d snaketexture;

protected override void LoadContent()
{
   snaketexture = Content.Load<Texture2D>(@"Textures/block");
}

protected override void Update(GameTime gameTime)
{
   snake.Add(new snakeunits(snaketexture, new Vector2(100, 100), 10, new Vector2(0, 10)))
}
foreach (units unit in snake)
{
     snake.Add(new snakeunits(snaketexture, new Vector2(100, 100), 10, new Vector2(0, 10)))
}
List<snakeunits>tmpList = new List<snakeunits>();
foreach (units unit in snake)
{
     tmpList.Add(new snakeunits(snaketexture, new Vector2(100, 100), 10, new Vector2(0, 10)))
}

snake.AddRange(tmpList);