Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Using Anime Class to Create Animations in XNA, WPXNA(11)

0.00/5 (No votes)
1 Jul 2013 1  
Using Anime class to create animations in XNA, WPXNA (11)

Introduction/Catalog

I have developed some games on Windows Phone. Here, I'll share my experiences and gradually upload some classes, no good name, I just call it WPXNA. (Some example code may not be stringent enough.)

  • Anime
  • AnimeAction
  • AnimeMovementAction
  • ToFrameCount, FrameRate
  • Example

Anime

Anime class inherits from the Movie class, the only difference is that Anime class contains actions, you can use the Anime to create white clouds on the page. Field actions mean all actions of the Anime. AnimeAction is a base class, we will talk about it later.

private readonly List<AnimeAction> actions = new List<AnimeAction> ( );

internal Anime ( string name, string resourceName, Vector2 location, int width, 
  int height, int rate, string defaultSequenceName, 
  MovieSequence[] sequences, params AnimeAction[] actions )
 : base ( name, resourceName, location, width, height, rate,
 0f,
 defaultSequenceName, sequences )
{

 if ( null != actions )
  foreach ( AnimeAction action in actions )
   if ( null != action )
   {
    action.Anime = this;
    this.actions.Add ( action );
   }
}

In the constructor of the Anime, we save action in parameter actions to field actions. The remaining parameters are similar to the parameters that are used by the Movie.

internal void Update ( GameTime time )
{
 foreach ( AnimeAction action in this.actions )
  action.Update ( time );

 Movie.NextFrame ( this );
}

In the Update method of Anime, we call the Update method for each AnimeAction that is able to control the state of Anime, such as location, speed, and so on. In addition, we also need to call the NextFrame method, so that the animation can be played.

internal static void Draw ( Anime anime, GameTime time, SpriteBatch batch )
{ Movie.Draw ( anime, time, batch ); }

In the Draw method of Anime, we simply call the Draw method of Movie to draw the animation.

AnimeAction

AnimeAction is the base class for all animation behavior, it is very simple, as follows:

internal abstract class AnimeAction
{
 internal Anime Anime; 

 protected AnimeAction ( )
 { }

 internal abstract void Update ( GameTime time );

}

Field Anime is used to control the Anime, such as moving the location of Anime. We set it in the Anime constructor.

All classes that inherit from the Anime must implement the Update method, in this method, we will use Anime field to adjust the status of the Anime.

AnimeMovementAction

AnimeMovementAction is a class that inherits from AnimeAction, it used to control the position of the Anime.

private readonly Rectangle area;

private float xSpeed;
private float ySpeed;

private readonly long xTurnFrameCount;
private readonly long yTurnFrameCount;

private long xTurnFrameIndex;
private long yTurnFrameIndex;

Fields area represents an area used to restrict the movement of Anime, such as: If Anime has moved to the right, it will appear on the left of the area.

Field xSpeed, ySpeed represents the speed of x, y axis. Field xTurnFrameCount, yTurnFrameCount, xTurnFrameIndex, yTurnFrameIndex is used to record the appropriate speed of the Anime will be reversed.

In the constructor of AnimeMovementAction, we have set these fields, which also use the World's ToFrameCount method.

internal AnimeMovementAction ( float xSpeed, float ySpeed, float xTurnSecond, 
float yTurnSecond, float xCurrentSecond, float yCurrentSecond, Rectangle area )
 : base ( )
{
 this.xTurnFrameCount = World.ToFrameCount ( xTurnSecond );
 this.yTurnFrameCount = World.ToFrameCount ( yTurnSecond );
 this.xSpeed = xSpeed;
 this.ySpeed = ySpeed;

 this.xTurnFrameIndex = World.ToFrameCount ( xCurrentSecond );
 this.yTurnFrameIndex = World.ToFrameCount ( yCurrentSecond );

 this.area = area;
}

internal override void Update ( GameTime time )
{
 if ( this.xTurnFrameCount > 0 && this.xTurnFrameIndex++ > this.xTurnFrameCount )
 {
  this.xTurnFrameIndex = 0;
  this.xSpeed = -this.xSpeed;
 }

 if ( this.yTurnFrameCount > 0 && this.yTurnFrameIndex++ > this.yTurnFrameCount )
 {
  this.yTurnFrameIndex = 0;
  this.ySpeed = -this.ySpeed;
 }

 this.Anime.Location += new Vector2 ( this.xSpeed, this.ySpeed );

 if ( !this.area.IsEmpty )
 {
  Vector2 location = this.Anime.Location;

  if ( this.xSpeed > 0 )
  {
   if ( location.X - this.Anime.Width > this.area.Right )
    this.Anime.Location = new Vector2 ( this.area.Left, location.Y );
  }
  else if ( this.xSpeed <0 )
   if ( location.X <this.area.Left )
    this.Anime.Location = new Vector2 ( this.area.Right + this.Anime.Width, location.Y );

  if ( this.ySpeed > 0 )
  {
   if ( location.Y > this.area.Bottom )
    this.Anime.Location = new Vector2 ( location.X, this.area.Top - this.Anime.Height );
  }
  else if ( this.ySpeed < 0 )
   if ( location.Y + this.Anime.Height < this.area.Top )
    this.Anime.Location = new Vector2 ( location.X, this.area.Bottom );
 }
}

ToFrameCount, FrameRate

The FrameRate property of World represents the number of frames per second in the game, ToFrameCount can return the count of frames with a time.

private static int frameRate = 30;
internal static int FrameRate
{
 get { return frameRate; }
 set { frameRate = value <= 0 ? 30 : value; }
}
  
internal static long ToFrameCount ( double second )
{ return ( long ) ( second * World.FrameRate ); }
internal static long ToFrameCount ( float second )
{ return ( long ) ( second * World.FrameRate ); }

Example

SceneT12 contains two bird's animation of the scene, bird1 can fly from the left to the right and repeat, bird2 can move vertically.

In drawing method, we need to call the Draw method to draw the birds. In Updating method, we need to call the Update method to update the location of the Anime.

internal sealed class SceneT12
 : Scene
{
 private readonly Anime bird1;
 private readonly Anime bird2;

 internal SceneT12 ( )
  : base ( Vector2.Zero, GestureType.None,
  new Resource[] {
   new Resource ( "bird2.image", ResourceType.Image, @"image\bird2" ),
  },
  new Making[] {
   new Anime ( "b1", "bird2.image", new Vector2 ( 100, 100 ), 80, 80, 5, "a",
    new MovieSequence[] { new MovieSequence ( "a", true, new Point ( 1, 1 ), new Point ( 2, 1 ) ) },
    new AnimeMovementAction ( 4, 0, new Rectangle ( -80, 0, 480, 0 ) )
    ),
   new Anime ( "b2", "bird2.image", new Vector2 ( 300, 300 ), 80, 80, 5, "a",
    new MovieSequence[] { new MovieSequence ( "a", true, new Point ( 2, 1 ), new Point ( 3, 1 ) ) },
    new AnimeMovementAction ( 0, 2, 0, 2 )
    ),
  }
  )
 {
  this.bird1 = this.makings[ "b1" ] as Anime;
  this.bird2 = this.makings[ "b2" ] as Anime;
 }

 protected override void drawing ( GameTime time, SpriteBatch batch )
 {
  base.drawing ( time, batch );

  Anime.Draw ( this.bird1, time, batch );
  Anime.Draw ( this.bird2, time, batch );
 }

 protected override void updating ( GameTime time )
 {
  this.bird1.Update ( time );
  this.bird2.Update ( time );

  base.updating ( time );
 }
}

In the OnNavigatedTo method of the World, we have added a new SceneT12.

protected override void OnNavigatedTo ( NavigationEventArgs e )
{
 // ...

 this.appendScene ( new Scene[] { new mygame.test.SceneT12 ( ) } );

 base.OnNavigatedTo ( e );
}

Get the code from here, for more contents, please visit WPXNA.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here