I'm just getting started with XNA and game development in general. I followed these instructions to create a basic game, then this article to get sprite animations working.
Now, I'm trying to abstract my design, in particular the stuff with sprite animations. Before I get much deeper, I want to make sure I have a good foundation to work with.
First, I have a Sprite
class:
public class Sprite
{
public Sprite()
{
// Default values for public members
Position = Vector2.Zero;
Scale = 1f;
LayerDepth = 0f;
}
public IAnimation Animation { get; set; }
public IMovement Movement { get; set; }
public string AssetName { get; set; }
public Texture2D Texture { get; set; }
public Vector2 Position { get; set; }
public Rectangle Frame { get; set; }
public float Scale { get; set; }
public float LayerDepth { get; set; }
public void Update( GameTime gameTime )
{
if ( Animation != null )
{
Frame = Animation.GetNextFrame( gameTime, Frame );
}
if ( Movement != null )
{
Position = Movement.GetNextPosition( gameTime, Position );
}
}
public void Draw( SpriteBatch spriteBatch )
{
spriteBatch.Draw( Texture, Position, Frame, Color.White, 0f, Vector2.Zero, Scale, SpriteEffects.None, LayerDepth );
}
}
I have a SpriteGroup
class for keeping groups of sprites organized and making them easy to use:
public class SpriteGroup
{
public IList<Sprite> Sprites { get; set; }
public void Update( GameTime gameTime )
{
foreach ( var sprite in Sprites )
{
sprite.Update( gameTime );
}
}
public void Draw( SpriteBatch spriteBatch )
{
foreach ( var sprite in Sprites )
{
sprite.Draw( spriteBatch );
}
}
}
This is inherited by the Character
class (nothing special there), of which I have several static instances:
public static class Characters
{
public static Character Tycho = new Character
{
Sprites = new List<Sprite>
{
new Sprite
{
Animation = new Animation
{
FirstFrame = 2,
LastFrame = 9
},
AssetName = "characters/walkcycle/BODY_male",
Position = new Vector2( 100, 100 ),
Frame = new Rectangle( 64, 64, 64, 64 ),
LayerDepth = 1f
},
new Sprite
{
Animation = new Animation
{
FirstFrame = 2,
LastFrame = 9
},
AssetName = "characters/walkcycle/LEGS_pants_greenish",
Position = new Vector2( 100, 100 ),
Frame = new Rectangle( 64, 64, 64, 64 ),
LayerDepth = 0f
}
}
};
// Several more static Characters...
}
I plan to have other static objects that inherit from SpriteGroup
as well such as scenery, buildings, etc.
Here are the relevant bits of my Game
class (or rather the class that inherits the Game
class from the XNA library):
private IList<Sprite> sprites { get; set; }
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch( GraphicsDevice );
sprites = new List<Sprite>();
var characters = new List<Character>
{
Characters.Aradesh,
Characters.Ian,
Characters.Tycho
};
foreach ( var character in characters )
{
foreach ( var sprite in character.Sprites )
{
sprite.Texture = Content.Load<Texture2D>( sprite.AssetName );
sprites.Add( sprite );
}
}
}
protected override void Update( GameTime gameTime )
{
foreach ( var sprite in sprites )
{
sprite.Update( gameTime );
}
// Other uninteresting stuff...
}
protected override void Draw( GameTime gameTime )
{
spriteBatch.Begin( SpriteSortMode.BackToFront, BlendState.AlphaBlend );
foreach ( var sprite in sprites )
{
sprite.Draw( spriteBatch );
}
spriteBatch.End();
// Etc...
}
Is this a good foundation for an XNA project? Are there any glaring flaws or design traps I'm likely to run into with what I have so far? Replace XNA with MonoGame where applicable. Either way, I'm just looking for general design advice. I haven't decided if I will make the switch to MonoGame or something else yet.
Ideally, I'd like to build up a reusable base class library for other projects moving forward, or for others to use or fork or whatever.
In case it helps, you can browse the code on GitHub.