petros
petros

Reputation: 715

Windows Phone XNA animation

I have VS2012 and try to make a simple xna app for Windows Phone 7/8. I have something like this:

public partial class GamePage : PhoneApplicationPage
{
    ContentManager contentManager;
    GameTimer timer;
    SpriteBatch spriteBatch;
    public Texture2D firstSprite { get; set; }
    public Vector2 transition = new Vector2(0, 0);
    public GamePage()
    {
        InitializeComponent();
        contentManager = (Application.Current as App).Content;

        timer = new GameTimer();
        timer.UpdateInterval = TimeSpan.FromTicks(333333);
        timer.Update += OnUpdate;
        timer.Draw += OnDraw;
    }

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(true);
        spriteBatch = new SpriteBatch(SharedGraphicsDeviceManager.Current.GraphicsDevice);
        firstSprite = this.contentManager.Load<Texture2D>("ikona");
        timer.Start();
        base.OnNavigatedTo(e);
    }

    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        timer.Stop();
        SharedGraphicsDeviceManager.Current.GraphicsDevice.SetSharingMode(false);
        base.OnNavigatedFrom(e);
    }
    float d = 0;
    private void OnUpdate(object sender, GameTimerEventArgs e)
    {
        TouchCollection touchCollection = TouchPanel.GetState();
        foreach (TouchLocation tl in touchCollection)
        {
            if (tl.State == TouchLocationState.Pressed && tl.Position.X < 240)
            {
                d = -10;
            }
            if (tl.State == TouchLocationState.Pressed && tl.Position.X > 240)
            {
                d = 10;
            }
            if (tl.State == TouchLocationState.Released)
                d = 0;
        }
        transition += new Vector2(d, 0);
    }
    private void OnDraw(object sender, GameTimerEventArgs e)
    {
        SharedGraphicsDeviceManager.Current.GraphicsDevice.Clear(Color.CornflowerBlue);
        spriteBatch.Begin();
        spriteBatch.Draw(firstSprite, transition, null, Color.White, 0, new Vector2(0, 0), 1f, SpriteEffects.None, 0);
        spriteBatch.End();
    }
}

Is it a good way do animate sprite? Will it be animated same way on every device? When I was testing it on lumia920 it wasn't very smooth, so I think I do it badly.

And second thing. I want to move picture left when I press left half of the screen and move right when I press right side. It partly works but when I press left (it moves left), then at the same time press right (it moves right), and then release right, picture stops. I thought it would move again left. How can I achieve this?

/edit/ And what about touch handling?

Upvotes: 0

Views: 218

Answers (1)

Pontus Magnusson
Pontus Magnusson

Reputation: 651

I'm not sure how it's animated as I'm not familiar with TouchCollection.
But using XNA to animate works like this for most of the solutions out there:
You have your texture which is a spritesheet I assume containing all the frames for your animated sprite.
You use a Rectangle which will hold Position and size on the screen.
You also use something called a source rectangle, which is a rectangle that represents an area inside your sprite, which will stretch in your position rectangle. Here is an image:
Rectangle A is your position + size rectangle, and rectangle B is your source rectangle. enter image description here

To create an animation you say the following ( pseudo code ):

int timer = 0;
Rectangle position = new Rectangle(100, 100, 80, 80); // position 100x, 100y, and size is 80 width and height.
Rectangle source = new Rectangle(0, 0, 80, 80); // Position on the spritesheet is 0, 0 which should be first frame, and the frames are all 80*80 pixels in size.

private void OnUpdate(object sender, GameTimerEventArgs e)
{
    timer += e.ElapsedTime.TotalMilliseconds;
    if(timer > 30) // If it has been 0.03 seconds = 33 frames per second
    {
        timer = 0; // reset timer
        source.X += 80; // Move x value to next frame
        if(source.X > widthOfYourSpriteSheet) source.X = 0; // Reset the animation to the beginning when we are at the end
    }
}

Your draw function will look pretty much the same, except for the sourcerectangle argument you will put in it.

Upvotes: 1

Related Questions