C# XNA SpriteBatch绘图扩展方法引发ArrayTypeMismatchException
我正在为XNA上一堂动画课。我决定尝试使用SpriteBatch的扩展方法来添加可以绘制动画精灵的绘制方法 AnimatedSprite包含精灵对象列表,并且精灵对象具有纹理2D图像。 我创建了一个静态扩展类,其中包含Draw方法的不同重载 这里有一个这样的方法(我假设所有函数的问题都类似): 当我运行我的项目时,我得到一个C# XNA SpriteBatch绘图扩展方法引发ArrayTypeMismatchException,c#,xna,extension-methods,C#,Xna,Extension Methods,我正在为XNA上一堂动画课。我决定尝试使用SpriteBatch的扩展方法来添加可以绘制动画精灵的绘制方法 AnimatedSprite包含精灵对象列表,并且精灵对象具有纹理2D图像。 我创建了一个静态扩展类,其中包含Draw方法的不同重载 这里有一个这样的方法(我假设所有函数的问题都类似): 当我运行我的项目时,我得到一个ArrayTypeMismatchException。我不确定是什么原因导致了它,因为sprite.CurrentSprite.Image是一个纹理2D 希望有人能帮助我理解
ArrayTypeMismatchException
。我不确定是什么原因导致了它,因为sprite.CurrentSprite.Image
是一个纹理2D
希望有人能帮助我理解是什么导致了这个问题和一个潜在的解决方案
谢谢
更新:动画精灵类
public class AnimatedSprite
{
List<Sprite> frames;
double elapsedSeconds;
int currentIndex;
/// <summary>
/// CurrentSprite is the current frame the animation is on
/// Use CurrentSprite.Image to get the underlying Texture2D
/// </summary>
public Sprite CurrentSprite { set; get; }
/// <summary>
/// FrameRate is the frame rate of the animation, measured
/// in frames per second
/// </summary>
public int FrameRate { set; get; }
bool shouldAnimate;
/// <summary>
/// Constructor for AnimatedSprite
/// </summary>
/// <param name="sprites">A list of sprites, cannot be left null</param>
/// <param name="frameRate">The framerate in frames per second</param>
/// <exception cref="ArgumentException">Thrown if sprites is null</Sprite></exception>
public AnimatedSprite(List<Sprite> sprites, int frameRate)
{
if (sprites == null) throw new ArgumentException("Please provide a non-null List<Sprite>");
this.frames = sprites;
this.currentIndex = 0;
if(this.frames.Count != 0) this.CurrentSprite = frames[currentIndex];
this.FrameRate = frameRate;
this.elapsedSeconds = 0;
}
/// <summary>
/// Add a frame to the animation. It will be added to the end.
/// </summary>
/// <param name="frame">The Sprite you would like to add</param>
public void AddFrame(Sprite frame)
{
frames.Add(frame);
if (frames.Count == 1) this.CurrentSprite = frames[0];
}
/// <summary>
/// Call this function in any Update method to continue the animation
/// </summary>
/// <param name="gameTime">The gameTime object keeping track of time</param>
public void Update(GameTime gameTime)
{
elapsedSeconds += gameTime.ElapsedGameTime.TotalSeconds;
if (elapsedSeconds > (1.0 / FrameRate) && shouldAnimate)
{
NextFrame();
elapsedSeconds = 0;
}
}
#region Animation Controls
/// <summary>
/// Starts the animation. This MUST be called to start the animation
/// </summary>
public void Start()
{
shouldAnimate = true;
}
/// <summary>
/// Stops the animation. Call Start() to start again
/// </summary>
public void Stop()
{
shouldAnimate = false;
}
/// <summary>
/// Advances the animation to the next cell
/// </summary>
public void NextFrame()
{
if (frames.Count == 0) return;
currentIndex++;
if (currentIndex >= frames.Count) currentIndex = 0;
this.CurrentSprite = frames[currentIndex];
}
/// <summary>
/// Advances the animation to the previous cell
/// </summary>
public void PreviousFrame()
{
if (frames.Count == 0) return;
currentIndex--;
if (currentIndex < 0) currentIndex = frames.Count - 1;
this.CurrentSprite = frames[currentIndex];
}
#endregion Animation Controls
公共类动画精灵
{
列出框架;
双延时秒;
int-currentIndex;
///
///CurrentSprite是动画所在的当前帧
///使用CurrentSprite.Image获取底层纹理2D
///
公共精灵CurrentSprite{set;get;}
///
///FrameRate是动画的帧速率,已测量
///每秒帧数
///
公共整数帧率{set;get;}
布尔应该有活力;
///
///动画精灵的构造函数
///
///精灵列表不能为空
///帧速率,以每秒帧数为单位
///如果精灵为空,则引发
公共动画精灵(列表精灵,整数帧率)
{
如果(sprites==null)抛出新的ArgumentException(“请提供非null列表”);
this.frames=精灵;
此.currentIndex=0;
如果(this.frames.Count!=0)this.CurrentSprite=frames[currentIndex];
this.FrameRate=帧速率;
此.elapsedSeconds=0;
}
///
///向动画中添加帧。它将添加到结尾。
///
///您要添加的雪碧
公共无效添加帧(精灵帧)
{
框架。添加(框架);
如果(frames.Count==1)this.CurrentSprite=frames[0];
}
///
///在任何更新方法中调用此函数以继续动画
///
///跟踪时间的游戏时间对象
公开作废更新(游戏时间游戏时间)
{
elapsedSeconds+=gameTime.ElapsedGameTime.TotalSeconds;
if(elapsedSeconds>(1.0/帧速率)和shouldAnimate(&shouldAnimate)
{
NextFrame();
elapsedSeconds=0;
}
}
#区域动画控件
///
///启动动画。必须调用此选项才能启动动画
///
公开作废开始()
{
shouldAnimate=true;
}
///
///停止动画。调用Start()重新开始
///
公共停车场()
{
shouldAnimate=false;
}
///
///将动画前进到下一个单元格
///
public void NextFrame()
{
如果(frames.Count==0)返回;
currentIndex++;
如果(currentIndex>=frames.Count)currentIndex=0;
this.CurrentSprite=帧[currentIndex];
}
///
///将动画前进到上一个单元格
///
public void PreviousFrame()
{
如果(frames.Count==0)返回;
当前索引--;
如果(currentIndex<0)currentIndex=frames.Count-1;
this.CurrentSprite=帧[currentIndex];
}
#endregion动画控件
使用的唯一数组是sprite.CurrentSprite使用存储在AnimatedSprite类中的内部索引返回sprite数组中该索引处的sprite。由于这是您使用数组的唯一位置,这是您的问题。由于您尚未发布AnimatedSprite类代码,我只能建议您查看AnimatedSprite类中的属性CurrentImage,看看它是否正确访问精灵[]。请发布AnimatedSprite类,以便我能为您提供更多帮助
另外,在我个人看来,你不应该在AnimatedSprite中存储sprite类的实例,你应该只存储一个纹理数组。存储一个sprite数组意味着每个sprite都是独立的实体,它们不是;它们是同一个动画sprite的一部分。你能发布AnimatedSprite类吗东南方?
public class AnimatedSprite
{
List<Sprite> frames;
double elapsedSeconds;
int currentIndex;
/// <summary>
/// CurrentSprite is the current frame the animation is on
/// Use CurrentSprite.Image to get the underlying Texture2D
/// </summary>
public Sprite CurrentSprite { set; get; }
/// <summary>
/// FrameRate is the frame rate of the animation, measured
/// in frames per second
/// </summary>
public int FrameRate { set; get; }
bool shouldAnimate;
/// <summary>
/// Constructor for AnimatedSprite
/// </summary>
/// <param name="sprites">A list of sprites, cannot be left null</param>
/// <param name="frameRate">The framerate in frames per second</param>
/// <exception cref="ArgumentException">Thrown if sprites is null</Sprite></exception>
public AnimatedSprite(List<Sprite> sprites, int frameRate)
{
if (sprites == null) throw new ArgumentException("Please provide a non-null List<Sprite>");
this.frames = sprites;
this.currentIndex = 0;
if(this.frames.Count != 0) this.CurrentSprite = frames[currentIndex];
this.FrameRate = frameRate;
this.elapsedSeconds = 0;
}
/// <summary>
/// Add a frame to the animation. It will be added to the end.
/// </summary>
/// <param name="frame">The Sprite you would like to add</param>
public void AddFrame(Sprite frame)
{
frames.Add(frame);
if (frames.Count == 1) this.CurrentSprite = frames[0];
}
/// <summary>
/// Call this function in any Update method to continue the animation
/// </summary>
/// <param name="gameTime">The gameTime object keeping track of time</param>
public void Update(GameTime gameTime)
{
elapsedSeconds += gameTime.ElapsedGameTime.TotalSeconds;
if (elapsedSeconds > (1.0 / FrameRate) && shouldAnimate)
{
NextFrame();
elapsedSeconds = 0;
}
}
#region Animation Controls
/// <summary>
/// Starts the animation. This MUST be called to start the animation
/// </summary>
public void Start()
{
shouldAnimate = true;
}
/// <summary>
/// Stops the animation. Call Start() to start again
/// </summary>
public void Stop()
{
shouldAnimate = false;
}
/// <summary>
/// Advances the animation to the next cell
/// </summary>
public void NextFrame()
{
if (frames.Count == 0) return;
currentIndex++;
if (currentIndex >= frames.Count) currentIndex = 0;
this.CurrentSprite = frames[currentIndex];
}
/// <summary>
/// Advances the animation to the previous cell
/// </summary>
public void PreviousFrame()
{
if (frames.Count == 0) return;
currentIndex--;
if (currentIndex < 0) currentIndex = frames.Count - 1;
this.CurrentSprite = frames[currentIndex];
}
#endregion Animation Controls