动画是所有游戏的必要组成部分,Starling能帮助你快速的制作简单动画。
如果你想了解一下,那么这里有两种动画类型。其中一种动画是你知道即将发生什么,比如当消息提示框被关闭,或者某些界面元素被移动出屏幕。另外一种动画更为灵活,例如玩家人物的移动。这些动画能够在每一帧改变他们的状态,同时这些动作是受到玩家控制的。
下面我们来看看后面这种动画类型,动态动画。
EnterFrame事件在一些游戏yiinqing中,你能够通过调用“run-loop”类似的命令。这是一个无限循环,每次循环都会处理场景中的所有元素。在Starling中,我们采用的是树状显示结构,所以这种方式对于我们来说没有太多的意义。你可能在你的游戏中定义了许多不同的可视化元素,并且这些元素在某些时刻应该进行一些操作。
这时你需要EnterFrame时间。这个事件适用于所有的显示元素,并且再每一帧都会触发。下面用一段简单的带来来演示如何使用它:
// e.g. in the constructor this.addEventListener(Event.ENTER_FRAME, onEnterFrame); // the corresponding event listener private function onEnterFrame(event:EnterFrameEvent):void { trace("Time passed since last frame: " + event.passedTime); enemy.moveBy(event.passedTime * enemy.velocity); }
onEnterFrame方法会在每帧都调用一次,并且你通过接收这个事件来对当前帧的状态进行改变。比如你能移动你的士兵,或者让场景中的雪花下落几个像素。
Tween现在我们来介绍另外一种动画。使用这种动画我们能很容易的实现一些平滑的动画效果,例如旋转,缓动等等。Starling拥有一些简单的动画类型。这些动画可以用到你所有的对象当中,只要你改变的属性是Number,int,uint类型。
这些对象之所以能够产生动画,完全依赖于"Tween"。"Tween"来源于手工动画,当你设定了一个动画的关键帧之后,其中的过渡帧会被“tween”自动完成绘制。
下面我们来看一个范例:
var tween:Tween = new Tween(msgBox, 0.5); tween.animate("y", 20); tween.animate("scaleX", 2); tween.animate("scaleY", 2); tween.animate("alpha", 0);
这个动画是将一个msgBox放大两倍尺寸,并且降低了它的透明度,直到它的透明度变为完全透明。这个动画运行需要半秒。如果你没有设置启动状态,那么这个动画会从当前状态开始运行。
正如你看到的,一个动画可以同时修改多个属性,并且你能用一个Tween对象控制多个动画对象。
注意,由于你经常使用缓动位置或者改变尺寸操作,那么你可以用下面的方法更加方便的进行操作:
tween.moveTo(0, 20); // animating "x" and "y" tween.scaleTo(2); // animating "scaleX" and "scaleY" tween.fadeTo(0); // animating "alpha"
这里还有更多的补间动画类型,例如从快到慢,或者从慢到快。
下面这些都是可以使用的类型: (默认的补间动画类型是'linear')
除此之外,你还可以设置延迟执行,或者设置执行后回调函数。
var tween:Tween = new Tween(msgBox, 0.5, Transitions.EASE_IN); tween.delay = 2; tween.onComplete = function():void { trace("tween complete!"); };
但是现在你看不到任何动画,因为一个tween对象所执行动画的首要前提是你必须对juggler对象进行操作。
Jugglerjuggler是所有的动画的控制器(这里是所有动画的接口)。Starling在初始化的时候会默认生成一个juggler事例。下面的方法是使用juggler来启动动画。
Starling.juggler.add(tween);
I通常情况下,简单的处理将会出现意想不到的问题。
不过有时候你想对一些不同的容器进行分组的哦光滑。例如你某些游戏动画发生,游戏中的舞台区域可能会改变。当用户点击一个退出按钮的时候,你需要暂停你游戏中所有元素的动画,同事弹出一个消息提示框,告诉你现在游戏已经暂停,并且询问用户是否现在退出游戏。
这种情况下,使用juggler控制是非常方便的。比如一个退出按钮可以先暂停一些动画。这时候游戏的所有状态将被冻结,然后弹出消息提示框,这些都可以使用juggle来进行操作的方法。
When you create a custom juggler, all you have to do is to call its “advanceTime” method in every frame. I recommend using jugglers the following way: 当你创建了一个自定义juggler,那么你必须在每一帧上调用“advanceTime”方法。使用方法如下:
// In your main game class, listen to Event.ENTER_FRAME: private function onEnterFrame(event:EnterFrameEvent):void { if (activeMsgBox) // message box is visible, wait for user input else gameArea.advanceTime(event.passedTime); } // the game area class advances its juggler in the // "advanceTime" method private function advanceTime(passedTime:Number):void { gameJuggler.advanceTime(passedTime); }
上面的代码已经将游戏的动画部分和消息提示框部分分离。
另外一种方法是你不在通过juggler来控制Tween补间动画。你需要让你的类实现IAnimatable接口,这样你就可以添加juggler,这个接口的使用方法如下:
function advanceTime(time:Number):void
通过这种方法,你可以创建一个简单的类似于MovieClip的类,在“advanceTime”方法中,它可以帮你完成贴图变化。在启动这个影片的时候你只需要为他添加一个juggler即可。
现在引发了另外一个值得关注的问题,我们如何从juggler中移除一个对象呢?
补间一旦完成,他们会从juggler中被自动删除。但对数对象是如此,但是像MovieClip类,当你决定他不在执行动画的时候,他才会被移除。
如果你想自定义类,并且实现juggler中自动删除功能,那么需要监听“Event.REMOVE_FROM_JUGGLER”事件。但是juggler监听到这个事件的时候对象将被删除。
回调函数还有另外一种动画类型,有时你想在未来做些什么事情。比如玩家用光了他的所有技能能量,那么你不希望立刻让游戏停止,你可能希望弹出一个"gameOver"的提示,然后在三秒钟之后退回到主画面。
juggler能够非常容易的做到这一点。你需要先弹出gameover,并且让游戏暂停。然后你只要暂停所有动画并让gameover方法延迟一段时间就可以了。
你只需要下面这样的语句就可以做到这一点:
Starling.juggler.delayCall(gameOver, 3);
“gameOver”函数是在3秒钟之后被调用的函数(当时间到的时候juggler会自动调用这个函数)。
来自:http://www.starlinglib.com/wiki/StarlingManual:%E5%8A%A8%E7%94%BB
之前一直没有搞懂android:padding和android:layout_margin的区别,其实概念很简单,padding是站在父view的角度描述问题,它规定它里面的内容必须与这个父view边界的距离。margin则是站在自己的角度描述问题,规定自己和其他(上下左右)的view之间的距离,如果同一级只有一个view,那么它的效果基本上就和padding一样了。例如我的XML layout代码如下:
过年回家,手机中有两个应用是爱不释手的,一个是微信,一个就是网易云阅读了。这里不谈论微信了,说说网易云阅读。刚刚接触网易云阅读,是偶然的,具体咋知道的已经忘了。这个APP且不谈交互体验好不好(在交互细节上面只能说还凑活,能够满足需求,但是没有超出期望),但确实解决了我的问题,零碎时间的阅读问题。之前网页端阅读36氪文档以及其他网站的文章,下了个虎嗅的客户端看文章,觉得有点分散,后来这个app有了之后,直接订阅了,减少了看文章来回切换的麻烦了,至此之后,爱不释手呵呵。
正好最近Infoq上面有篇关于移动架构的文章,大体看了一下PPT,觉得写得挺实在,例子就是网易云阅读,所以正好算是简介翻译一下这篇文章,结合我这个菜鸟的理解,也算是学习一下优秀的架构。
网易云阅读的下载地址:http://yuedu.163.com/
移动应用架构策略(infoq地址):http://www.infoq.com/cn/presentations/mobile-application-architecture-strategy (作者和我是一个工种呵呵,IT中的服务端开发)
1、平台类的应用
第一次使用这个app,就发现他是平台级的应用产品,自己不生产内容,聚合第三方的信息,为用户提供阅读服务,作为用户不需要到处查看文章内容,内容提供者不需要考虑推广等事情,可以专注于自己的内容。
2、移动产品存在的问题
A、目前的网络十分复杂,导致的就是网络速度不均匀,有地地方会出现网络死角、在移动过程中网速不稳定;(根据友盟的数据来看,目前2G和wifi的联网方式各占40%左右,3G的占20%左右)。
B、不同设备的屏幕尺寸不统一,导致需要根据尺寸来进行内容适配,要达到两盒的视觉呈现还是有点费劲的;(IOS系列的产品有十余种,其中iPhone和iPad占比比较大;android系列的产品更是很多,友盟的数据有四十余种 http://umindex.com/#android_device )。
C、移动设备自身硬件能力具有局限性
移动设备运行着APP,此时就相当于一个独立的服务器啊。首先电池容量小,这要求编写的app要能够省电;内存小,经常会出现应为内存不足而造成app闪退的现象(话说我之前搞的那个玩具在测试的时候也经常闪退呢);CPU处理能力有限,要进行复杂的逻辑处理,做好在云端服务器中处理掉;存储空间有限,这个受限于内存卡,大家都懂的。
3、服务器端架构
这个的话没有啥特别之处,典型的web应用的架构形式(为app提供http请求的服务,如果是静态图片或者静态文件,会有相应的CDN服务器,来加速这类的请求)。最前端有负载均衡处理器(例如运行的LVS程序的机器);然后是webserver(例如apache或者nginx,目前淘宝系主推tengine,一个改善的nginx的版本,有一个团队在维护);之后是appServer(作为java开发,我就暂且理解为java的web程序,appServer是分布式的,可以动态水平扩展,就是加减机器对于前台请求以及后台数据没有影响);然后再后面是数据库、缓存处理器、分布式文件系统等持久化设施。
对于云阅读产品来说,貌似之前听说有几种获取信息的策略,虽然是坊间传闻,但是我觉得也差不多。
A、开放平台对接,内容提供者通过调用API接口,把最新的文章信息同步给appServer对应的持久化设施,这种最方便,但是需要监控接口的稳定程度;
B、内容提供者把内容维护在网易云阅读提供的后台,在后台直接录入文章等信息;
C、网易云阅读搞一个服务端程序,去抓取内容提供者发布的信息,然后过滤、清洗,存储起来对外提供服务;
下图是抓取服务的架构图:
Manager负责load第三方提供的URL信息,然后Crawler负责抓取信息,之后Analyzer负责分析页面的DOM结构,之后存储在DB中,对外提供服务。
4、客户端架构
从下面这张图来看,客户端设计是分层的,非常清晰。
A、客户端本地数据库,负责存储用户个人信息、系统配置信息,以及缓存数据,这里存储的数据,是需要在服务器端也存储起来的,就是数据要同步,负责我更换了一个手机,之前设置的信息没有同步过来,是一个比较痛苦的事情;
B、View层,总体负责View的展现、UI的优化。动画效果、以及页面回调等,类似web中的View层,就是负责展示的;
C、网络层,我个人理解,负责网络请求的封装(组装参数、发起请求、解析返回结果);
D、逻辑控制、服务组合和数据持久化我认为是一层,就是核心逻辑处理,运行在客户端,数据获取和存储依赖于网络层向服务器端发起请求;
这样,客户端的架构就比较清晰,维护起来也就没那么蛋疼了。
5、优化策略
A、图片服务器智能化,尽量返回客户端合适的图片,例如pad类的产品,就直接返回他尺寸大一点的图片,手机类的就返回尺寸小一点的图片,图片的剪裁和浓缩在服务器端完成,需要在客户端再来做这些事情;
B、确定是否进行预加载和加载的优先级,图片或者文章,都有“下一页”和“上一页”的翻页操作,可以根据用户的使用习惯,来进行预先加载,例如用户在看文章的时候,习惯进行“下一页”操作,那我们就在用户“阅读当前页面”的时候,把下一页的文章加载进行,这样用户在进行下一页阅读的时候,体验会很好(可以在客户端维持几个变量,把用户的行为转变为可衡量的数字,这样就可以依赖这些变量来判断是否需要预先加载);
C、缓存要进行管理,缓存是否需要失效,需要有判断的原则,一种是请求服务器端,如果数据过期,则直接进行失效即可,另外一种就是客户端根据容量情况来进行失效(这一点类似于服务器端缓存失效策略呵呵);
D、数据压缩,要省流量,需要压缩(使用UC浏览器能省流量,原因也是由于压缩),网易云阅读使用的是GZIP的压缩方式,服务器端在发送数据的时候,把数据通过Gzip来压缩,然后客户端接受之后,再按照协议来解压缩,这样流量就省下了;
E、使用http长连接(因为构建http链接是很耗时的操作,所以可以保值长连接,减少反复握手的网络和资源开销),断点续传(对于较大文件,能够减少网络流量),重连策略(如果网络异常,则可以根据适当的算法来进行重连,但是方法最好是幂等的);
F、消息推送,IOS有自带的通知机制(IOS Push),android的话google有产品,但是在国内不好用,你懂的,需要自己为移动终端自建Push服务。有一个原则是网易云阅读分享出来的,一个是移动终端登录后和Push服务器保持连接,Push服务器主动心跳来保持这个连接(移动终端可以动态调整Push服务器的心跳间隔);
6、系统复用
A、 尽量使用现有的,因为成本低、风险小;
B、UI组件复用、源代码复用、开源组件复用,框架设计巧妙,直接插件开发即可;
最理想的情况是,集成现用的系统来创建新的应用。
PPT中基本上介绍了“网易云阅读”这款产品的情况,十分详尽,后面作者有提到关于产品设计以及需求处理方面,这里就不多讲了。