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

时间:2014-02-09 23:07:48

标签: c# windows-phone-8 xna

我对编程比较陌生(这是一个爱好),特别是C#,我正在尝试在XNA 4.0 for Windows Phone 8中开发一个简单的蛇游戏克隆。

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

当我尝试在蛇与食物碰撞时添加一个单位时会出现错误。我已尝试在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)));
    }

}

}

判断错误的行是

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

项目中包含的其他文件(相当基本,只有构造函数)

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
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
{
abstract class units
{
    Texture2D textureImage;
    int collisionOffset;
    int timeSinceLastFrame = 0;
    int millisecondsPerFrame;
    protected const int defaultMillisecondsPerFrame = 16;
    public Vector2 speed;
    public Vector2 position;

    public units(Texture2D textureImage,
                    Vector2 position,
                    int collisionOffset,
                    Vector2 speed)
        : this(textureImage, position, collisionOffset, speed, defaultMillisecondsPerFrame)
    {
    }

    public units(Texture2D textureImage,
                    Vector2 position,
                    int collisionOffset,
                    Vector2 speed,
                    int millisecondsPerFrame)
    {
        this.textureImage = textureImage;
        this.position = position;
        this.collisionOffset = collisionOffset;
        this.speed = speed;
        this.millisecondsPerFrame = millisecondsPerFrame;
    }

    public virtual void Update(GameTime gameTime, Rectangle clientBounds)
    {
    }

    public virtual void Draw(GameTime gameTime, SpriteBatch spriteBatch)
    {
        spriteBatch.Draw(textureImage, position, Color.White);
    }

    public abstract Vector2 direction
    {
        get;
    }

    public Rectangle collisonRect()
    {
        return new Rectangle((int)position.X, (int)position.Y, collisionOffset, collisionOffset);
    }

}
}

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 foodunits : units
{
    public foodunits(Texture2D textureImage,
      Vector2 position,
      int collisionOffset,
      Vector2 speed)
        : base(textureImage, position, collisionOffset, speed)
    {
    }

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

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


}
}

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; }
    }




}
}

非常感谢任何帮助。谢谢。

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

编辑2:

虽然解决了,但并未完全解决。

添加了布尔标志,而不是尝试在头部的if循环内添加snakeunit。然后使用布尔值在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;
                }

        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);

1 个答案:

答案 0 :(得分:0)

尝试在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)))
}

在你的情况下,如果所有的蛇部分都带有对相同纹理的引用,那就不重要了。

编辑:刚刚意识到崩溃的原因,因为你在迭代它时将东西放入列表中。

foreach (units unit in snake)
{
     snake.Add(new snakeunits(snaketexture, new Vector2(100, 100), 10, new Vector2(0, 10)))
}

这是将snake.add移动到函数底部时解决问题的原因。您可以通过创建临时列表来解决此问题,然后在完成迭代蛇列表后,将临时列表附加到蛇列表中。

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);