Arm*_*ium 2 c# xna animation sprite xna-3.0
我正在使用XNA 3.0并尝试创建一个精灵类,但我不确定如何处理它.我是否在精灵类中执行动画?我的代码也一直收到错误
Game1.cs
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
Sprite.Draw(spriteBatch);
base.Draw(gameTime);
}
Run Code Online (Sandbox Code Playgroud)
Sprite.cs
private static Texture2D rings;
Point rings_frameSize = new Point(75, 75);
Point rings_currentFrame = new Point(0, 0);
Point rings_sheetSize = new Point(6, 8);
int ms_elapsedRings = 0;
public static void setup_sprites(ContentManager Content)
{
rings = Content.Load<Texture2D>("Images/threerings");
}
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(rings,
new Vector2(0,0),
new Rectangle(rings_currentFrame.X * rings_frameSize.X, //X component of where to begin
rings_currentFrame.Y * rings_frameSize.Y, //Y component of where to begin
rings_frameSize.X, //cell width
rings_frameSize.Y), //cell height
Color.White,
0,
Vector2.Zero,
1,
SpriteEffects.None,
0);
}
Run Code Online (Sandbox Code Playgroud)
返回
错误1非静态字段,方法或属性'WindowsGame1.Sprite.Draw(Microsoft.Xna.Framework.Graphics.SpriteBatch)'C:\ Users\XXXXXX\Documents\Visual Studio 2008\Projects需要对象引用\ WindowsGame1\WindowsGame1\Game1.cs 107 13 WindowsGame1
首先,您的第二个错误: " 非静态字段,方法或属性需要对象引用 ".
在面向对象的编程中,程序具有结构的好处,通过类和继承等概念,而不是历史命令式编程,其中"程序"由一系列基本指令组成,一个接一个.在面向对象的编程中,类表示一些抽象实体.这些实体可以是动物,汽车,电视.在这种情况下,你可以写一个class Car
并"创造"许多Car
物体的"实例"是有道理的,其中一个可能叫做本田,另一个叫宝马,另一个叫劳斯莱斯.但有时,创建类的实例没有意义.如果你的班级不是汽车怎么办 - 如果它是"数学"怎么办?拥有一个"Math"类是完全有效的 - 事实上,.NET框架有一个Math类.但在这种情况下,拥有数学的"实例"是没有意义的.数学是数学.这是一项研究 - 而且只有一项研究.
因此,非静态方法的访问方式如下:
Car honda = new Car();
honda.Drive();
Run Code Online (Sandbox Code Playgroud)
说Car.Drive()是没有意义的,因为你指的是哪辆车?Car,作为一个类,只是一个通用蓝图 - 你想调用new Car()
从该类蓝图中制作一些具体的对象.
另一方面,访问静态方法,如下所示:
Math.Add();
Run Code Online (Sandbox Code Playgroud)
说这就没有意义Math myMath = new Math();
,这就是为什么Math是它自己的静态类.
现在,你已经制定了方法setup_sprites()
static
.您可能认为此设置方法应该是静态的,因为无论创建了多少个精灵,每个创建的精灵都将在设置期间访问相同的纹理.如果你想以这种方式制作精灵类,那很好 - 但是你必须使你的整个精灵类静态,因为静态方法和变量不能访问非静态方法和变量.
通常,Sprite类不是静态的.您可以在此处阅读有关静态与非静态的更多信息:http://msdn.microsoft.com/en-us/library/79b3xss3%28v=vs.80%29.aspx.
现在,你的第一个问题.如何将动画集成到代码中完全取决于您.看起来您在Draw()方法中嵌入了动画代码.这没有错,但可能有更好的解决方案.
面向对象编程有一些原则可以保持复杂性简单,其中之一就是单一责任原则,简单来说,它建议程序员只给一个班级一个职责.您的Sprite类应该只是加载其资源,绘制自己并卸载其资源.这都是精灵应该做的.
但是动画呢?这就是面向对象编程的用武之地 - 分担责任; 你不必把所有东西都粘在Sprite类中.你有两个选择:你可以扩展你Sprite
在的表单功能AnimatedSprite
从继承类Sprite
类,也可以扩展你Sprite
在的表单功能Animatable
接口.这里的设计问题是:按类或接口扩展?
你可以在这里阅读更多有关辩论的内容:http://www.codeproject.com/Articles/11155/Abstract-Class-versus-Interface
我从该文章中真正喜欢的是以下定义:抽象类定义核心功能,而接口描述外围属性.
你的精灵不仅可以动画,还可以移动.这听起来更像是属性而不是核心功能.它具有动画的能力.它有移动的能力.有些人认为接口具有" has-a "关系,而类被认为具有" is-a "关系.你的类本质上不是动画 - 它首先是一个精灵.然后它具有动画的能力.
所以我认为你应该Sprite
通过添加一个Animatable
接口来扩展你的课程.您实际上想要调用它IAnimatable
,以保留命名标准.
所以你最终会得到类似的东西(伪代码):
public class Sprite : IAnimatable
{
private Texture2D rings;
public void LoadContent(ContentManager Content)
{
// Call this method from Game.LoadContent()
rings = Content.Load<Texture2D>("Images/threerings");
}
public void Draw(SpriteBatch spriteBatch)
{
if (IsAnimating)
{
// Incorporate IAnimatable variables here to draw your animation
}
}
}
public interface IAnimatable
{
public bool IsAnimating {get; set;}
public int CurrentFrameIndex {get; set;}
public Point FrameSize {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
在将来,您甚至可能拥有:
public interface IMovable
{
public bool IsMoving {get; set;}
public Point CurrentLocation {get; set;}
public Point DestinationLocation {get; set;}
}
Run Code Online (Sandbox Code Playgroud)
并将所有这些整合到:
public class NpcSprite : Sprite, IMovable, IAnimatable
{
}
Run Code Online (Sandbox Code Playgroud)
确实,即使使用接口,你仍然最终在Sprite类中编写接口代码,但至少你已经建立了精灵,可动画精灵和可移动精灵之间的明确契约.稍后编辑和扩展会更容易.
归档时间: |
|
查看次数: |
3453 次 |
最近记录: |