梦想成真 XNA (4) – 动画

[索引页]
[源码下载] 

梦想成真 XNA (4) – 动画

作者:webabcd

介绍
XNA: 动画

示例
壹 、让精灵运动起来的 德姆o(按键盘 F 键加载此 德姆o)
Component/Sprite/Animation.cs

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace XNA.Component.Sprite
{
    public class Animation : Microsoft.Xna.Framework.DrawableGameComponent
    {
        // 精灵绘制器
        SpriteBatch _spriteBatch;

        // 精灵对象
        Texture2D _sprite;

        // 描述精灵的位置
        Vector2 _spritePosition = Vector2.Zero;

        // 描述精灵的速度:_spriteSpeed.X 为 X 轴方向上每帧移动的像素数,_spriteSpeed.Y 为 Y 轴方向上每帧移动的像素数
        Vector2 _spriteSpeed = new Vector2(3, 10);

        public Animation(Game game)
            : base(game)
        {

        }

        public override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            _spriteBatch = new SpriteBatch(Game.GraphicsDevice);
            _sprite = Game.Content.Load<Texture2D>("Image/Son");
        }

        public override void Update(GameTime gameTime)
        {
            // 根据速度更新精灵的位置
            _spritePosition.X += _spriteSpeed.X;
            _spritePosition.Y += _spriteSpeed.Y;

            // X 轴方向上,如果精灵碰到了左右边界,则 X 轴速度变为相反的方向
            if (_spritePosition.X > Game.Window.ClientBounds.Width - _sprite.Width || _spritePosition.X < 0)
                _spriteSpeed.X *= -1;

            // Y 轴方向上,如果精灵碰到了上下边界,则 Y 轴速度变为相反的方向
            if (_spritePosition.Y > Game.Window.ClientBounds.Height - _sprite.Height || _spritePosition.Y < 0)
                _spriteSpeed.Y *= -1;

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            Game.GraphicsDevice.Clear(Color.CornflowerBlue);

            // 在指定的位置上绘制精灵
            _spriteBatch.Begin();
            _spriteBatch.Draw(_sprite, _spritePosition, Color.White);
            _spriteBatch.End();

            base.Update(gameTime);
        }
    }
}

贰 、 通过 Pepsi-Cola Sheet 完成天使动画的 德姆o(按键盘 G 键加载此 德姆o)
Component/Sprite/AnimatingSprite.cs

/*
 * 本例使用的 Sprite Sheet 图详见:XNAContent/SpriteSheet/Smurf.png
 */

using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;

namespace XNA.Component.Sprite
{
    public class AnimatingSprite : Microsoft.Xna.Framework.DrawableGameComponent
    {
        // 精灵绘制器
        SpriteBatch _spriteBatch;

        // 精灵对象
        Texture2D _sprite;

        // 在 Sprite Sheet 中每个独立图像的尺寸
        Point _frameSize = new Point(128, 128);

        // 当前独立图像在 Sprite Sheet 中的位置
        Point _currentFrame = new Point(0, 0);

        // Sprite Sheet 的行数和列数
        Point _sheetSize = new Point(4, 4);

        // 精灵动画的帧率
        const int SPRITE_FPS = 10;

        // 精灵动画中,当前时间距离显示上一帧独立图像所经历的时间,单位:毫秒
        int _elapsedTime = 0;

        public AnimatingSprite(Game game)
            : base(game)
        {
            // Game.TargetElapsedTime 的默认值为 new TimeSpan(0, 0, 0, 0, 16),即近似 60 fps(frames per second)

            // 修改帧率的方法如下,其意味着每 100 毫秒 1 帧,即每秒 10 帧
            // game.TargetElapsedTime = new TimeSpan(0, 0, 0, 0, 100);
        }

        public override void Initialize()
        {
            base.Initialize();
        }

        protected override void LoadContent()
        {
            _spriteBatch = new SpriteBatch(Game.GraphicsDevice);
            _sprite = Game.Content.Load<Texture2D>("SpriteSheet/Smurf");
        }

        public override void Update(GameTime gameTime)
        {
            /*
            * GameTime - 游戏的当前时间对象
            *     GameTime.ElapsedGameTime - 当前距离上一次调用 Update() 方法所经历的时间
            *     GameTime.IsRunningSlowly - 是否跳帧,true 则表示 XNA 不能跟上指定的帧率
            *     GameTime.TotalGameTime - 游戏开始后到此时所经历的总共时间
            */

            _elapsedTime += gameTime.ElapsedGameTime.Milliseconds;
            if (_elapsedTime > 1000 / SPRITE_FPS)
            {
                _elapsedTime -= 1000 / SPRITE_FPS;
                ++_currentFrame.X; 
                if (_currentFrame.X >= _sheetSize.X)
                {
                    _currentFrame.X = 0; 
                    ++_currentFrame.Y;
                    if (_currentFrame.Y <= _sheetSize.Y)
                    {
                        _currentFrame.Y = 0;
                    }
                }
            }

            base.Update(gameTime);
        }

        public override void Draw(GameTime gameTime)
        {
            Game.GraphicsDevice.Clear(Color.CornflowerBlue);

            _spriteBatch.Begin();

            _spriteBatch.Draw(
                // 精灵对象
                _sprite,

                // 让精灵的位置在游戏窗口的正中间
                new Vector2((Game.Window.ClientBounds.Width - _frameSize.X) / 2, (Game.Window.ClientBounds.Height - _frameSize.Y) / 2),

                // 显示 Sprite Sheet 中的指定的独立图像
                new Rectangle(
                    _currentFrame.X * _frameSize.X, 
                    _currentFrame.Y * _frameSize.Y,
                    _frameSize.X, 
                    _frameSize.Y
                ), 

                // 不做染色处理
                Color.White
            );

            _spriteBatch.End();

            base.Update(gameTime);
        }
    }
}

OK 
[源码下载]

发表评论

电子邮件地址不会被公开。 必填项已用*标注