每次按空间我都需要拍摄精灵。我很确定我已经创建了纹理并绘制它(在我的播放器类中),但每次读取bulletTexture.width
时它总是返回null。我希望some1可以帮助我。
以下是我的代码的完整概述:
Player.cs
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.Content;
using Microsoft.Xna.Framework.Input;
namespace SpaceShooter_Beta.Animation.PlayerCollection
{
public class Player : SpriteManager
{
#region Field Region
public bool isAnimating = false, isDirectional = false;
private float loadTime = 0.05f, shootDelay, bulletDelay, timeElapsed;
public float speed;
public List<CommonBullet> commonBulletList;
public int bulletCap = 20;
KeyboardState kbs;
#endregion
#region Property Region
public int fps
{
set { loadTime = (1f / value); }
}
#endregion
#region Constructor Region
public Player(Texture2D texture, int frame, int animations) :
base(texture, frame, animations)
{
speed = 2f;
shootDelay = 5f;
this.AddAnimation("down", 1);
this.AddAnimation("up", 2);
this.AddAnimation("right", 3);
this.AddAnimation("left", 4);
this.AddAnimation("upright", 5);
this.AddAnimation("upleft", 6);
this.AddAnimation("downright", 7);
this.AddAnimation("downleft", 8);
commonBulletList = new List<CommonBullet>();
bulletDelay = 5f;
}
public void Update(GameTime gt)
{
timeElapsed += (float)gt.ElapsedGameTime.TotalSeconds;
if (!this.isAnimating)
{
if (timeElapsed > loadTime)
{
timeElapsed -= loadTime;
if (frameIndex == rects.Length - 1) this.isAnimating = false;
else frameIndex++;
}
}
kbs = Keyboard.GetState();
GetMovement();
if (kbs.IsKeyDown(Keys.Space)) Attack();
UpdateBullet();
}
#endregion
#region Method Region
private void GetMovement()
{
if (kbs.IsKeyDown(Keys.W))
{
this.pos.Y -= speed;
this.animation = "up";
if (kbs.IsKeyDown(Keys.D))
{
if (!isDirectional)
{
frameIndex = 0;
isDirectional = true;
}
this.pos.X += speed;
this.animation = "upright";
}
else if (kbs.IsKeyDown(Keys.A))
{
if (!isDirectional)
{
frameIndex = 0;
isDirectional = true;
}
this.pos.X -= speed;
this.animation = "upleft";
}
if (!this.isAnimating) this.isAnimating = true;
else this.isAnimating = false;
}
else if (kbs.IsKeyDown(Keys.S))
{
this.pos.Y += speed;
this.animation = "down";
if (kbs.IsKeyDown(Keys.D))
{
if (!isDirectional)
{
frameIndex = 0;
isDirectional = true;
}
this.pos.X += speed;
this.animation = "downright";
}
else if (kbs.IsKeyDown(Keys.A))
{
if (!isDirectional)
{
frameIndex = 0;
isDirectional = true;
}
this.pos.X -= speed;
this.animation = "downleft";
}
if (!this.isAnimating) this.isAnimating = true;
else this.isAnimating = false;
}
else if (kbs.IsKeyDown(Keys.A))
{
this.pos.X -= speed;
this.animation = "left";
if (!this.isAnimating) this.isAnimating = true;
else this.isAnimating = false;
}
else if (kbs.IsKeyDown(Keys.D))
{
this.pos.X += speed;
this.animation = "right";
if (!this.isAnimating) this.isAnimating = true;
else this.isAnimating = false;
}
else
{
this.isAnimating = false;
this.isDirectional = false;
frameIndex = 0;
}
if (this.pos.X <= 0) this.pos.X = 0;
if (this.pos.X >= (800 - this.width)) this.pos.X = 800 - this.width;
if (this.pos.Y <= 0) this.pos.Y = 0;
if (this.pos.Y >= (600 - this.height)) this.pos.Y = 600 - this.height;
}
private void Attack()
{
if (bulletDelay > 0) bulletDelay--;
if (bulletDelay <= 0)
{
CommonBullet cb = new CommonBullet();
if(cb.bulletTexture.Width > 0)
{
Console.WriteLine("this");
return;
}
cb.pos = new Vector2(this.pos.X - cb.bulletTexture.Width / 2, this.pos.Y + 15);
cb.hasFired = true;
if (commonBulletList.Count < bulletCap) commonBulletList.Add(cb);
bulletDelay = 0;
}
if (bulletDelay == 0) bulletDelay = shootDelay;
}
private void UpdateBullet()
{
foreach (CommonBullet cb in commonBulletList)
{
cb.box = new Rectangle((int)cb.pos.X, (int)cb.pos.Y, cb.bulletTexture.Width, cb.bulletTexture.Height);
cb.pos.Y -= cb.bulletSpeed;
if (cb.pos.Y < 0) cb.hasFired = false;
}
for (int i = 0; i < commonBulletList.Count; i++)
{
if (!commonBulletList[i].hasFired)
{
commonBulletList.RemoveAt(i);
i--;
}
}
}
public void Draw(SpriteBatch sb)
{
sb.Draw(texture, pos, animations[animation][frameIndex], Color.White, rot, ori, s, se, 0f);
foreach (CommonBullet cb in commonBulletList)
{
cb.Draw(sb);
}
}
#endregion
}
}
继承自SpriteManager(对于它的动画),这里是SpriteManager类:
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.Content;
namespace SpaceShooter_Beta
{
public class SpriteManager
{
#region Field Region
protected Texture2D texture;
protected Rectangle[] rects;
protected int frameIndex = 0, frames;
protected Dictionary<string, Rectangle[]> animations = new Dictionary<string, Rectangle[]>();
public Vector2 pos, ori;
public float rot = 0f, s= 1f;
public SpriteEffects se;
public string animation;
public int width, height;
#endregion
#region Property Region
#endregion
#region Constructor Region
public SpriteManager(Texture2D texture, int frame, int animation)
{
this.texture = texture;
this.frames = frame;
rects = new Rectangle[frame];
for (int i = 0; i < frame; i++)
{
rects[i] = new Rectangle(i * width, 0, width, texture.Height);
}
width = texture.Width / frame;
height = texture.Height / animation;
}
#endregion
#region Method Region
public void AddAnimation(string name, int row)
{
Rectangle[] rects = new Rectangle[frames];
for (int i = 0; i < frames; i++)
{
rects[i] = new Rectangle(i * width, (row - 1) * height, width, height);
}
animations.Add(name, rects);
}
#endregion
}
}
每次在Attack()函数中调用player.cs时,我都会“绘制”我的子弹纹理。这是我的子弹课程:
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.Content;
namespace SpaceShooter_Beta.Animation.PlayerCollection
{
public class CommonBullet
{
#region Field Region
public float bulletSpeed = 5f;
public double bulletDamage;
public Texture2D bulletTexture;
public Vector2 pos, ori;
public bool hasFired;
public Rectangle box;
#endregion
#region Property Region
#endregion
#region Constructor Region
public CommonBullet()
{
hasFired = false;
}
#endregion
#region Method Region
public void Draw(SpriteBatch sb)
{
sb.Draw(bulletTexture, pos, Color.White);
}
public void LoadContent(ContentManager Content)
{
bulletTexture = Content.Load<Texture2D>(@"playerbullet");
}
#endregion
}
}
错误每次都在player.cs,cb.pos = new Vector2(this.pos.X - cb.bulletTexture.Width / 2, this.pos.Y + 15);
处抛出。从调试器,我很确定cb.bulletTexture是非null,但它的宽度返回null。
我希望有人可以帮助我,谢谢。
答案 0 :(得分:1)
您正在每CommonBullet
初始化一个新Attack()
但是,您没有调用LoadContent()
方法来加载图片。
可以通过添加LoadContent
调用
CommonBullet cb = new CommonBullet();
cb.LoadContent(your content manager)
然而,一直加载新图像通常不是一个好主意,特别是如果它是游戏图像,没有意义。
您应该在static
CommonBullet
变量
static Texture2D BulletTexture;
您还应该使用LoadContent
方法static
,而不是上面的方法(称之为每次攻击),您应该进入主Game
文件,并找到它的LoadContent方法,并添加以下行:
CommonBullet.LoadContent(this.ContentManager);
或者您可以CommonBullet.BulletTexture = Content.Load<Texture2D>("Blah");