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.