代码改变世界

未雨绸缪,Win8 Metro开发实例分享

2012-02-10 17:01 姜 萌@cnblogs 阅读(...) 评论(...) 编辑 收藏

    着手win8 metro的东西有一段时间了,在这里用一个实实在在的小游戏设计分享给大家。
我使用的开发环境是官方9月份公开的Windows Developer Preview(含VS11 P版),不过某些厂商内部可以拿到Developer Preview Update和Win8 Beta。目前开发语言可以选择C++,C#,Js,vb和其他.NET语言。基础API和.NET BCL几乎差不多,做了很多删减(比如socket),去掉了所有阻塞性的同步api,IO上只有异步api供使用(不过由于c#4.5的await和async,异步代码写起来和同步代码差不多,开发体验灰常不错哦),一些资源路径和使用方式有所变化(比如代码里使用的话是ms-resource:/Image/Logo.png,或者ResourceLoader.GetFile(……)),运行时某些特殊权限需要声明(contract,protocol,网络,媒体库等等),程序间通讯需要使用特别的机制( Protocol)等等。

 

   用.net语言开发的Metro程序实际上是一个.net core的程序。编译后为的appx+xaml文件和资源文件(位置在C:\Users\{你的用户名}\AppxLayouts\下),运行时部分托管执行&部分通过winrt执行(实际上底层大部分已经是winrt来跑了)。

 


这个实例游戏是给小孩纸玩的游戏合集之一,这里给大家演示的是其中一个猜数字的游戏,游戏内容是:一辆公交车从蘑菇后面跑过去时会随机隐藏掉几个动物,公交车离开屏幕后让小孩纸猜猜有几个动物消失(下面有0-5的数字供选择,选对就播放笑的动画,选错就播放哭的动画)。

之前做过一个wpf版,当时的动画都是叫美工用Blend画出来的(都是path动画,非常细腻),可是目前metro不支持path动画,所以公交车和蘑菇、动物都是用图片序列帧来替换(吐血~~)。


    PS:蛋疼的dp版win8,输入法、焦点经常出问题,调试metro app时也常出现触控操作失灵(Tap、PointerXXX等事件不触发),用了一段时间后vs designer就再也不能用。(同仁们如有好的办法请告诉我)。

 这个metro项目的代码下载 (需要在开发环境下编译后执行)

Win8 Metro联盟群:148462643

技术交流 商务合作 猎头咨询 盈利分享。抓住移动平台(Win8,wp7,android,ios)为开发者带来的丰富机遇与财富! 

本文重点讲里面针对目前的metro api设计一套简化版精灵机制,方便调用。设计之初的定位是

性能高效。虽然用这套类似于wpf/sl的GUI机制本身并不是特别适合做游戏,但是作一般的2D游戏还是木有问题的。这里强调亮点:

A.精灵的驱动方式:我使用一个不可重入的timer来驱动所有精灵,每个精灵都实现由OnFrame方法,每次onUpdate的时候遍历这些精灵,依次调用OnFrame。

B.精灵的移除操作:由于GameLoop的update频率很高,很可能当需要移除精灵时候正在便利这个集合从而引发一些麻烦(不管你用线程安全的集合还是不安全的)。,我的GameLoop中提供移除精灵的方法(RemoteSprite),实现原理是调用需要remote一个sprite时会将这个sprite的id放到一个队列中,当GameLoop下次onUpdate的时候先从这个队列中依次将要移除的精灵id取出,移除所有需要移除的精灵后再对集合进行遍历。

帧数可调

每个精灵的帧速单独可控

每个精灵的每两帧之间的帧速可控

这几个功能的设计很有用,实现起来也简单,FrameInfo里可以记录每一帧到下一帧的时间(一个TImeSpan),Sprite本身会保留自己上次OnFrame的时间,在ISprite.OnFrame里判断时间间隔即可。



方便其他开发者使用,友好易用的api

用起来很简单,根上继承的是Canvas,可以直接放到布局里去。另外像坐标,中心点偏移、旋转角度、伸缩量也都在Sprite里实现了:),你可以播放一遍,也可以播放n遍,也可以在播放若干次后callback一个事件……



可扩展,方便定制

比如我这个实例里面的BusSprite和MushSprite,他们都有特别之初,只需要继承,重 载你需要的方法即可。


SpritesLoop用于驱动精灵的组件,上面提到过。



FrameInfo:一帧的数据,包括帧图信息,帧序号,每一帧速的帧速等


SpriteResource:帧信息集合,当前帧数,所有帧数等


ISprite:精灵实体抽象,直接或间接继承自UIElement,可以直接放到metro布局里去。


辅助:

ResourceMaker系按照约定方式根据图片为精灵生成SpriteResource对象。

整体的Sprites系统是这样的:


创造我们的公交车(Bus Sprite)

公交车有个特点,他上面还要装载5个能动的动物(5个AnimalSprite),这就需要我们在基本的Sprite之上进行扩展,我们做一个字类,通过继承来创造这个bus。


同时创建5个AnimalSprite,他同样是继承在Sprite(这个很简单,只是为了调整动物每一帧在公交车上的位置才做的,具体请看代码。)

在BusSprite的初始化时将5只动物以及他们的位置准备好。


加到BusSprite身体上:


OK,这样Bus就能够动起来了。


这个metro项目的代码下载 (需要在开发环境下编译后执行)

Win8 Metro联盟群:148462643

技术交流 商务合作 猎头咨询 盈利分享。抓住移动平台(Win8,wp7,android,ios)为开发者带来的丰富机遇与财富!