如何在WP7上用XNA写2D游戏(五)
第 4 章XNA里的2D动画
4.1 播放游戏精灵动画
第二章里我们提到了如何把2D的纹理用SpriteBatch显示。对于游戏而言,一个精灵(sprite,在游戏编程里指一个对象的原型,比如一个战士,一个怪物)不可能不做动作,就拿简单的走动来说,手脚一定会是要动的,那么如何真实得展现一个人物在屏幕上走动呢?在2D游戏编程里,我们通常就是把人物的动作拆成一帧帧图片,通过连续播放来欺骗人眼产生动画的效果,其实胶片电影也是这个原理。
如下图4-1,是一个小兵的行走动画,可以看到是由12张图片组成,那么如何能连续循环播放呢
图4-1
一想到循环,我们就很容易想到for循环,如果我们把这12张图片的纹理放到一个Texture2D[] 数组里那么,通过for循环不就可以实现了么?
for(int i=0;i<SoldierTextures.Count;i++) //伪代码
{
spriteBatch.Draw(SoldierTextures[i]);
}
当然,这个循环只能循环一遍,如果做到从头到尾不停的循环呢?
前面我们提到XNA里的Update函数,它就是不停执行的一个函数,执行的时间间隔是一个固定值.我们就可以把这个函数当做是一个特殊的for循环.
我们需要用上一个全局的计数器FrameCount.
int FrameCount=0;
void Update() //在update函数里改变计数器
{
FrameCount++;
if(FrameCount>SoilderTextures.Length-1)//如果播完最后一帧
{
FrameCount=0; //就回到第一帧
}
}
void Draw() //在Draw函数里绘制出纹理
{
spriteBatch.Draw(SoilderTextures[FrameCount]);
}
以上代码都是伪代码,便于大家理解,实际编程中的代码比这里要复杂点。
1.在GameMainScreen类里写上构造函数:
Texture2D[] soilderTextures;
public GameMainScreen()
{
soilderTextures=new Texture2D[12];//初始化士兵纹理数组
}
2.把12张士兵跑动图片放到Content项目下的一个Enemy文件夹的子文件夹Run中,如果4-2:
3.用for循环加载这12张图片纹理,如下:
public override void LoadContent()
{
base.LoadContent();
playerTexture = ScreenManager.Game.Content.Load<Texture2D>("Player/1");
for (int i = 0; i < 12;i++ )
{
soilderTextures[i] =ScreenManager.Game.Content.Load<Texture2D>("Enemy/Run/"+(i+1));
}
}
4.在Draw里绘制出当前帧:
public override void Draw(GameTime gameTime)
{
ScreenManager.SpriteBatch.Begin();
ScreenManager.SpriteBatch.Draw(soilderTextures[FrameCount],new Vector2(100,200), Color.White);
ScreenManager.SpriteBatch.End();
}
图4-2
5.在Update里更新当前帧的位置,依次向后播放:
public override void Update(GameTime gameTime, bool otherScreenHasFocus, bool coveredByOtherScreen)
{
base.Update(gameTime, otherScreenHasFocus,coveredByOtherScreen);
float elapsedTime = (float)gameTime.ElapsedGameTime.TotalSeconds;
FrameCount++;
if(FrameCount > soilderTextures.Length - 1)//如果播完最后一帧
{
FrameCount = 0; //就回到第一帧
}
}
6.在模拟器最后运行效果如图4-3:
我们执行上面写好的代码后,就在模拟器里发现人物就循环播放动画了,不过出现了新问题:士兵的跑动动作频率不够合理,像一个超人一样飞速得在奔跑。
- 更多wap疑问解答:
- 新人求助QPainter
- 为什么程序都退出了还可以收到推送?如果大多设备都可以推送那运营商怎么办?
- qt 4.7 sqlserver2000 存储过程调用
- 关于ANDROID4.0.1编译问题!
- Android FrameBuffer读屏幕30秒后mmap失败
- 联通粗定位用java程序如何来请求和接受数据
- 为什么QT运行Android平台的程序时,mouseMoveEvent事件响应的间隔时间很长??????????
- android与PC蓝牙通讯
- 指定大小的label 内容可变,如果内容超出label的宽度,将未能显示的部分显示在另一个label上
- Android调试
- android如何通过wifi连接无线打印机
- 运行程序,release目录下产生一个乱码文件夹
- 分享个某机构最新安卓资料,自己验证了
- service启动不起来,掉不了service connection
- 求助:QT5.0 没有QPrinter吗