游戏震屏效果的实现
2015-10-01 06:40
337 查看
震屏效果在游戏里使用相当广泛的,特别在被物体撞击的时候,震屏效果能大大提高游戏的真实感。我开始以为实现震屏效果很简单,通过正弦函数去设置场景位置偏移量即可,但真正去做时发现还是有一点点挑战。
1.通过正弦函数去设置场景位置偏移量,只能实现单独的上下/左右/斜线震动,怎么也无法实现其它游戏里那种效果。仔细分析之后才知道,垂直和水平方向分别分别用正弦函数和余弦函数计算偏移量。
2.提供各种定制参数,以满足不同情况的需要。比如振幅的变化(减弱/增强/增强再减弱),振动的次数和持续的时间等等。
3.我希望可以让任何一个控件都可以支持震动效果,而不光是整个场景才能震动,同时又不想修改基类UIElement。当然装饰模式是比较好的选择,不过在JS不需要那么麻烦。UIShaker去重载它所在容器的paintSelf函数就行了,UIShaker放到任何一个控件里面,启用UIShaker时就会让这个控件震动,震动完成后自动恢复原状。
在TangIDE里使用震屏控件非常方便,拖动一个震屏控件到场景中,在特定事件发生时启用它即可,整个过程不需要写一行代码。
震屏控件的完整实现请参考CanTK的源码。
1.通过正弦函数去设置场景位置偏移量,只能实现单独的上下/左右/斜线震动,怎么也无法实现其它游戏里那种效果。仔细分析之后才知道,垂直和水平方向分别分别用正弦函数和余弦函数计算偏移量。
var xo = aX * Math.cos(angle); var yo = aY * Math.sin(angle);
2.提供各种定制参数,以满足不同情况的需要。比如振幅的变化(减弱/增强/增强再减弱),振动的次数和持续的时间等等。
UIShaker.prototype.setAmplitudeX = function(value) { this.amplitudeX = value; return this; } UIShaker.prototype.setAmplitudeY = function(value) { this.amplitudeY = value; return this; } UIShaker.prototype.setDuration = function(value) { this.duration = value; return this; } UIShaker.prototype.setTimes = function(value) { this.times = value; return this; } UIShaker.prototype.setAmplitudeModifier = function(value) { this.amplitudeModifier = value; return this; }
3.我希望可以让任何一个控件都可以支持震动效果,而不光是整个场景才能震动,同时又不想修改基类UIElement。当然装饰模式是比较好的选择,不过在JS不需要那么麻烦。UIShaker去重载它所在容器的paintSelf函数就行了,UIShaker放到任何一个控件里面,启用UIShaker时就会让这个控件震动,震动完成后自动恢复原状。
UIShaker.prototype.setEnable = function(enable) { var parent = this.getParent(); if(!parent || this.enable == enable) { return this; } if(!enable) { this.enable = enable; return this; } var me = this; var aX = this.amplitudeX ? this.amplitudeX : 0; var aY = this.amplitudeY ? this.amplitudeY : 0; var n = this.times ? this.times : 1; var duration = this.duration ? this.duration : 200; var startTime = Date.now(); var oldPaintSelf = parent.paintSelf; var range = n * 2 * Math.PI; var am = this.amplitudeModifier; parent.paintSelf = function(canvas) { var dt = (Date.now() - startTime); if(dt < duration) { var factor = 1; var percent = dt/duration; var angle = range * percent; var xo = aX * Math.cos(angle); var yo = aY * Math.sin(angle); if(am === "i") { factor = percent; } else if(am === "d") { factor = (1-percent); } else if(am === "i->d") { factor = 2 * (percent < 0.5 ? percent : (1-percent)); } xo *= factor; yo *= factor; canvas.translate(xo, yo); } else { parent.paintSelf = oldPaintSelf; me.enable = false; } oldPaintSelf.call(parent, canvas); } return this; }
在TangIDE里使用震屏控件非常方便,拖动一个震屏控件到场景中,在特定事件发生时启用它即可,整个过程不需要写一行代码。
震屏控件的完整实现请参考CanTK的源码。
相关文章推荐
- K-th largest element in an array
- Android Api Demos登顶之路(八十二)Graphics-->Picture
- OSChina 周四乱弹 —— 十一精品旅游路线
- ZOJ.2540 Form a Square【水】 2015/10/01
- Android项目使用support v7时遇到的各种问题GOOD
- nf使用 Python 的 turtle 模块画图
- Peeking Iterator
- 二进制的一个常见技巧
- 写Swift用Cocoapods兼容IOS7
- Solr 4.2.0的一些知识
- PowerShell 查询操作
- PowerShell 条件判断和循环
- svg vs canvas
- Bootlaoder分析详解
- nw
- 在线Markdown Editor
- *LeetCode-Reorder List
- jsp片段
- 本人博客排名(2015年10月1日:第67408名)
- *LeetCode-Sort List