摘要:以XNA为基础的游戏可以利用3D模型为游戏加入动画效果,也可以利用简单的程序技巧将2维图片显示成动画。虽然2维动画相对3维动画来说简单一些,但是制作出来的游戏其趣味性和挑战性也绝不逊色。今天我们就一块学习一下在使用XNA Framework开发2D游戏时的一些基础知识和注意事项。

主要内容:

1.2D游戏动画的基本原理

2.动画素材的准备

3.一个简单的2D动画

一、2D游戏动画的基本原理

在XNA中制作2D动画的过程很像翻卡通小人书,首先绘制好各种角色造型,然后以固定的时间间隔来显示不同的图片,当时间间隔小到一定程度时人眼就难以区分,从而形成一种动画效果。如果做过flash或者使用fireworks做过gif的朋友可能更容易理解,它就像flash中的逐帧动画一样,每帧显示一个图片,然后连起来就形成了动画效果。由于在XNA中有SpriteBatch可以绘制图片精灵,这样一来我们只需事先做好不同的角色造型的图片,每次在执行Update方法的时候改变绘制的精灵图片就可以制作出动画效果。

二、动画素材的准备

XNA开发2D动画的原理比较容易理解,我也就不过多的赘余了,现在我们就开始准备游戏素材。XNA的SpriteBatch的绘制方法有点类似于样式表CSS的background属性,可以通过设置参数来显示一个图片的其中一部分,这样一来我们为了方便管理游戏角色就只需要将同一角色的不同造型放到同一张图片中,每次更新时显示图片的不同部分就可以了。例如下面这幅图片就是如此:

在这幅图片中我们将22个不同造型的角色放到同一幅图片中,事先规划好每个小图片的大小,保证各个图片连接起来播放时能够形成一组连贯的动作。当然,为了让整个效果看起来更生动一些我们再来准备一张背景图片:

三、一个简单的2D动画

有了上面的游戏素材,我们就来简单模拟一下植物大战僵尸中的一个场景。在下面的Demo中表现了两种运动:其一就是我们要控制22个小图片之间的切换,以此产生角色行动的动画(在原地);其二就是控制图片切换的同时我们需要移动图片的位置从而形成角色在水平方向上行走动作。具体代码如下:

1 using System;
2  using System.Collections.Generic;
3 using System.Linq;
4 using Microsoft.Xna.Framework;
5 using Microsoft.Xna.Framework.Audio;
6 using Microsoft.Xna.Framework.Content;
7 using Microsoft.Xna.Framework.GamerServices;
8 using Microsoft.Xna.Framework.Graphics;
9 using Microsoft.Xna.Framework.Input;
10 using Microsoft.Xna.Framework.Input.Touch;
11 using Microsoft.Xna.Framework.Media;
12 namespace _2DAnimation
13 {
14 publicclass MyGame : Microsoft.Xna.Framework.Game
15 {
16 GraphicsDeviceManager graphics;
17 SpriteBatch spriteBatch;
18 private Texture2D corpse;//图片资源
19 private Point frameSize;//每个小图片大小
20 private Point sheetSize;//小图片个数
21 private Point currentFrame;//当前小图片位置
22 private Vector2 postion;//角色所在位置
23 privatefloat speed;//角色行走速度
24 private Texture2D background;
25 public MyGame()
26 {
27 graphics =new GraphicsDeviceManager(this);
28 Content.RootDirectory ="Content";
29 graphics.PreferredBackBufferWidth =800;//设置游戏视窗大小
30 graphics.PreferredBackBufferHeight =480;
31 TargetElapsedTime = TimeSpan.FromTicks(333333*2);
32 }
33 protectedoverridevoid Initialize()
34 {
35 frameSize =new Point(100, 125);
36 sheetSize =new Point(11, 2);
37 currentFrame =new Point(0,0);
38 postion =new Vector2(graphics.PreferredBackBufferWidth-100,graphics.PreferredBackBufferHeight -125-150);
39 speed =3;
40 base.Initialize();
41 }
42 protectedoverridevoid LoadContent()
43 {
44 spriteBatch =new SpriteBatch(GraphicsDevice);
45 background =this.Content.Load<Texture2D>("background");//加载游戏背景
46 corpse =this.Content.Load<Texture2D>("transparentCorpse");//加载整张大图片(透明背景)
47 }
48 protectedoverridevoid UnloadContent()
49 {
50 }
51 protectedoverridevoid Update(GameTime gameTime)
52 {
53 if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
54 this.Exit();
55 ++currentFrame.X;
56 if (currentFrame.X >= sheetSize.X)
57 {
58 currentFrame.X =0;
59 ++currentFrame.Y;
60 if (currentFrame.Y >= sheetSize.Y)
61 {
62 currentFrame.Y =0;
63 }
64 }
65 postion.X -= speed;
66 if (postion.X <20)
67 {
68 this.Exit();//角色进入房屋后退出游戏
69 }
70 base.Update(gameTime);
71 }
72 protectedoverridevoid Draw(GameTime gameTime)
73 {
74 GraphicsDevice.Clear(Color.CornflowerBlue);
75 spriteBatch.Begin(SpriteSortMode.BackToFront,BlendState.NonPremultiplied);//所有的绘制工作均在sprite的begin和end中间进行
76 spriteBatch.Draw(
77 corpse,//要绘制的精灵
78 postion,//绘制的位置
79 new Rectangle(currentFrame.X * frameSize.X, currentFrame.Y * frameSize.Y, frameSize.X, frameSize.Y),//绘制精灵的哪一部分
80 Color.White, //颜色
81 0, //旋转角度
82 Vector2.Zero,//旋转参考点
83 1, //缩放倍数
84 SpriteEffects.None, //翻转
85 0//层深
86 );
87 spriteBatch.Draw(background, Vector2.Zero, Color.White);
88 spriteBatch.End();
89 base.Draw(gameTime);
90 }
91 }
92 }

代码总体来说还是比较简单,主要通过在Update方法中动态修改currentFrame来形成图片切换,当然之所以这样是因为Draw方法的第三个参数,通过它我们才能做到一张图片的局部显示(具体来说就是在Rectangle中指定corpse精灵的起始坐标和要显示的图片宽度和高度)。图片的水平移动主要通过在Update中动态修改position变量的值,当然这里需要注意图片超出游戏视窗的情况。下面是运行效果:

截图效果:

动画效果:

值得一提的是,我们这里牵扯到了图片显示的层深问题,如果注意看代码的朋友会发现我们并没有首先绘制游戏背景,而是先绘制了游戏角色(当然我是为了说明层深问题而故意这么做的)。默认情况下载XNA会按照程序调用顺序绘制精灵,这样我们就看不到角色了,因为它被背景图片遮住了。如果说遇到了这种情况(事实上游戏开发中经常遇到)我们就需要设置图片的层深,也就是我们上面代码中Draw方法的最后一个参数。它是float类型,其取值范围是0-1。具体0是代表最先绘制还是最后绘制则完全取决于SpriteBatch的Begin方法中的第一个参数,这个参数是SpriteSortMode,他是一个枚举类型,有五种模式:

取值

描述

Deferred

这是默认模式,此模式下只有在SpriteBatch调用End方法时才会被绘制,如果绘制多个精灵则按照调用次序依次进行。

Texture

同Deferred类似,在绘制之前会按照纹理排序,对于相同深度而不互相重叠的情况下效果较好。

BackToFront

在End方法执行后绘制精灵,绘制精灵的顺序按照层深度由前往后排序(先绘制层深值较小的)。

FrontToBack

在End方法执行后绘制精灵,绘制精灵的顺序按照层深度由后往前排序(先绘制层深值较大的)。

Immediate

调用Begin方法后就会立即绘制精灵(这也是五种模式中唯一在End方法之前就进行绘制的),同一时间只有一个SpriteBatch被使用。

另一点需要注意的是,我们的账单是透明的,在XNA Game开发中如果想要让图片透明有两种方式:第一就是图片本省就是透明,此时当然需要选用能够存储图像alpha的图片格式来保存图片(例如png格式可以将图像的alpha存储到图片信息中,我们上的例子中就是这么做的。事实上GIF也可以,但是在XNA中默认不支持GIF);第二种方式就是将图片需要显示成透明的部分设置为洋红色(RGB:255,0,255),这样XNA会自动将洋红色部分渲染成透明。

XNA游戏开发之2D游戏相关推荐

  1. DirectX游戏开发之2D文字的实现

    DirectX游戏开发之2D文字的实现 文字是承载信息最有效的载体之一,各种游戏程序都离不开文字的显示.对于3D文字来说,2D文字有其渲染的高效性和实现的简洁性. 2D文字的显示无论在写2D游戏还是在 ...

  2. 浅谈游戏开发之2D手游工具

    游戏程序 平台类型: iOS Android  程序设计: 其它  编程语言:   引擎/SDK: 其它          全球手游行业规模将突破250亿美元,越来越多的开发者开始进入手游研发领域,而 ...

  3. Unity3D游戏开发之RPG游戏剧情呈现策略

    喜欢我的博客请记住我的名字:秦元培,我的博客地址是:http://qinyuanpei.com 转载请注明出处,本文作者:秦元培, 本文出处:http://blog.csdn.net/qinyuanp ...

  4. [Unity3D]Unity3D游戏开发之ACT游戏三连击效果实现综述

    各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我的博客地址是blog.csdn.net/qinyuanpei.在研究了Unity3D Mecanim动画系统的重定向特性后,今天我们继续来探索Me ...

  5. Firefox os 游戏开发之2048游戏源码

    <2048 >是一款数字益智游戏,<2048>的初始数字则是由2+2组成的基数4.在操作方面的不同则表现为一步一格的移动,变成更为爽快的一次到底.相同数字的方况在靠拢.相撞时会 ...

  6. DirectX游戏开发之3D角色动起(下)

    DirectX游戏开发之3D角色动起(下) 直接先上图吧! 动作idle 动作attack 动作walk 动作run 看,多动作的模型搞下来了.原则上只要在此基础上略做修改就可以实现3d游戏的基本制作 ...

  7. libGDX游戏开发之Box2D(十四)

    libGDX游戏开发之Box2D(十四) libGDX系列,游戏开发有unity3D巴拉巴拉的,为啥还用java开发?因为我是Java程序员emm-国内用libgdx比较少,多数情况需要去官网和goo ...

  8. 开发中的“软”与“硬”:高画质移动游戏开发之道

    摘要:游戏的效果不仅与游戏引擎的渲染相关,与硬件优化也有千丝万缕的联系.一款基于芯片优化的移动游戏界面,甚至可以堪比视频游戏的视觉效果.高通半导体事业部资深经理刘晓光从软硬件两个层面分享了移动游戏开发 ...

  9. 游戏开发之U3D实现技能图标冷却的效果

    游戏开发之U3D实现技能图标冷却的效果 --本次使用的NGUI插件.     制作思路:NGUI插件里面有个UISprite组件,在它上面有个属性叫Type,改变相应的Type类型有不同的作用,本次使 ...

最新文章

  1. 速卖通店铺流量少的原因分析以及解决办法
  2. leetcode 55. Jump Game | 55. 跳跃游戏(暴力递归->傻缓存->DP)
  3. Linux学习1——文件权限
  4. vim 下的 ex 指令(底行命令模式下)
  5. 深入探讨C++中的引用
  6. Spark学习之第一个程序打包、提交任务到集群
  7. python数据库管理软件_MySQL管理工具MySQL Utilities — 介绍与安装(1)
  8. 程序员如何 Get 分布式锁的正确姿势?| 技术头条
  9. Scala Package Package Objects
  10. Leetcode题目:Reverse String
  11. [转载] python bytearray拼接_python-4-bytes和bytearray
  12. 这个 SpringCloud+Vue 在线教育系统,牛得起飞!
  13. 苹果的编程语言--Swift
  14. win10怎么用记事本打开html文件,Win10系统怎么打开记事本
  15. Webstorm汉化方法
  16. 网管员的最爱!解密六款低成本RADIUS
  17. Nitrux 图标主题与 Faenza 一样的设计 – 漂亮
  18. 解决双蛋问题的C代码实现
  19. 51单片机串口通信的程序实现与Proteus仿真
  20. 安装Vue-cli并且创建项目

热门文章

  1. PhotoFilter for Insta Like Support Of Technology
  2. JUC-线程池理解与学习
  3. wordpress建站(空间+域名+备案)
  4. 北京一建增报专业成绩如何进行管理
  5. ntr模式_doHnadoHnantr怎么避开 一起做坏事吧ntr避开方法一览_游侠网
  6. mysql格式化去掉千分号_SQL 格式化数字,千分位分隔符并保留2位小数
  7. 2164 Bincomial Coeffcients(组合数求模)
  8. 统信UOS家庭版全民测评~
  9. “古今第一美男子”是怎么掉了脑袋的
  10. C#IO之导入导出Excel的多种方式