我对编程比较陌生(这是一个爱好),特别是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);
答案 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);