今天我們來實現煙雨+飛雪效果。首先來說,一款經典的RPG遊戲難免需要加入天氣的變化。那麼為了使我們的RPG遊戲引擎更完美,我們就只好慢慢地實現它。
本文為該系列文章的第二篇,如果想瞭解以前的文章可以看看下面列表:
如何製作一款HTML5 RPG遊戲引擎——第一篇,地圖類的實現
http://blog.csdn.net/yorhomwang/article/details/8892305
該引擎是基於lufylegend開發的,學習時請先瞭解lufylegend。
官方網站地址:http://lufylegend.com/lufylegend
API地址:http://lufylegend.com/lufylegend/api
※獲得本次開發的靈感來自lufy在lufylegend.js下載包中編寫的一個執行個體。
一,LEffect類
首先來搞一個LEffect類,構造器如下:
function LEffect(){var s = this;base(s,LSprite,[]);s.rainList = [];s.snowList = [];s.rainLayer = new LSprite();s.addChild(s.rainLayer);s.snowLayer = new LSprite();s.addChild(s.snowLayer);}
這個LEffect類也是繼承自LSprite,rainList是用來裝雨點的一個數組,snowList則是用來裝雪的一個數組。rainLayer,snowLayer分別是一個LSprite,如果是雪就繪畫在snowLayer上,雨就在rainLayer。這個構造器很簡單,接下來就來看看下雨的效果是怎麼樣實現的。
二,煙雨紛紛
這裡我用煙雨來形容這個效果,難免有一些過分,因為它的美感遠遠還沒達到那種地步。不過能在螢幕上飄雨點子還是實現了的,那好,就來讓我們來看看關於它的代碼吧:
LEffect.prototype.raining = function(speed,size){var s = this;if(!speed)speed = 30;if(!size)size = 5;s.rainLayer.addEventListener(LEvent.ENTER_FRAME,function(){s.onshow("rain",speed,size);});}
首先,它是LEffect一個成員類,叫raining,有兩個參數,分別是下雨時雨點落下速度,另一個是雨點尺寸。當然,使用時可以不給它們賦值,如果不給它們賦值那就用預設的值。接著加入ENTER_FRAME事件,也就是說,當rainLayer重新整理一次,就調用以下功能,相當於一個時間軸。ENTER_FRAME具體的使用方法可以去lufylegend API文檔看看。也許有朋友心急了,想迫切地看看onshow是個什麼東西。本文最後一節會講它,因為它和下雪的效果也有些關係。
接下來就輪到飛雪效果了。
三,飛雪效果
這次直接上代碼吧,很raining差不多,只是改了最後調用onshow時傳的參數和參數賦值而已:
LEffect.prototype.snowing = function(speed,size){var s = this;if(!speed)speed = 10;if(!size)size = 1;s.snowLayer.addEventListener(LEvent.ENTER_FRAME,function(){s.onshow("snow",speed,size);});}
四,onshow方法
在實現raining和snowing時,我們都用到了onshow方法,並且還給它幾個參數,我們不妨先看看代碼:
LEffect.prototype.onshow = function(thing,speed,size){var s = this;if(thing == "rain"){s.rainLayer.graphics.clear();var rainX = Math.random()*(LStage.width-10-10)+10;var n = s.rainList.length;while(n--){var o = s.rainList[n];o.y += o.s;s.rainLayer.graphics.drawRect(1,"white",[o.x,o.y,1,size],true,"#f3f3f3");}s.rainList.push({x:rainX,y:0,s:speed});}else if(thing == "snow"){s.snowLayer.graphics.clear();var snowX = Math.random()*(LStage.width-10-10)+10;var n = s.snowList.length;while(n--){var o = s.snowList[n];o.y += o.s;s.snowLayer.graphics.drawArc(2,"white",[o.x,o.y,size,0,2*Math.PI],true,"white");}s.snowList.push({x:snowX,y:0,s:speed});}}
很顯然,這個onshow方法是整個效果類的核心部分,光看代碼長度就應該知道。。。首先我們來看看它的參數:
thing:效果類型,如果為snow就下雪,如果是rain就下雨
speed:下雨下雪的速度
size:下雨下雪的尺寸
speed,size和snowing、raining中的speed,size值是一樣的,因此,如果你在用snowing、raining時,直接給它們的參數賦值就行了。
我們現在來解釋一下代碼:
if(thing == "rain"){s.rainLayer.graphics.clear();var rainX = Math.random()*(LStage.width-10-10)+10;var n = s.rainList.length;while(n--){var o = s.rainList[n];o.y += o.s;s.rainLayer.graphics.drawRect(1,"white",[o.x,o.y,1,size],true,"#f3f3f3");}s.rainList.push({x:rainX,y:0,s:speed});}
以上是下雨效果的實現,首先我們先清屏一次,接著隨機取一個x座標作為繪製的位置。接著我們遍曆了一下我們的雨點數組,並且每遍曆到一個,就把這個的y座標加上速度的大小。然後用lufylegend中專門用來畫矩形的函數畫一個小矩形作為一個雨點。然後在雨點數組中記錄下這些雨點的資料。由於我們用了時間軸事件,所以就能使雨點不斷地畫出來。
下雪的原理是一樣的,就只有繪畫方式不同,把畫矩形改成了畫圓而已。大家可以根據我剛才說的對應看看。
五,封裝完成後應該怎麼寫?
剛剛我們把效果類封裝好了,那麼別人怎麼用呢?我不妨給大家呈現一下代碼,原本我們要寫百十行才能實現的,封裝完成後就只有這些了:
var backLayer = new LSprite();var effect = new LEffect();backLayer.addChild(effect);//下雪effect.snowing();//下雨effect.raining();
很簡單是不是?這就是封裝的力量!
六,效果示範
為了方便測試,我給它加了一個按鈕和選擇框用來顯示不同的效果。
如下:
示範地址:http://www.cnblogs.com/yorhom/articles/3073050.html
代碼很少,歸納後如下,感興趣的朋友可以複製下來看看:
/***LEffect效果類*/function LEffect(){var s = this;base(s,LSprite,[]);s.rainList = [];s.snowList = [];s.rainLayer = new LSprite();s.addChild(s.rainLayer);s.snowLayer = new LSprite();s.addChild(s.snowLayer);}LEffect.prototype.raining = function(speed,size){var s = this;if(!speed)speed = 30;if(!size)size = 5;s.rainLayer.addEventListener(LEvent.ENTER_FRAME,function(){s.onshow("rain",speed,size);});}LEffect.prototype.snowing = function(speed,size){var s = this;if(!speed)speed = 10;if(!size)size = 1;s.snowLayer.addEventListener(LEvent.ENTER_FRAME,function(){s.onshow("snow",speed,size);});}LEffect.prototype.onshow = function(thing,speed,size){var s = this;if(thing == "rain"){s.rainLayer.graphics.clear();var rainX = Math.random()*(LStage.width-10-10)+10;var n = s.rainList.length;while(n--){var o = s.rainList[n];o.y += o.s;s.rainLayer.graphics.drawRect(1,"white",[o.x,o.y,1,size],true,"#f3f3f3");}s.rainList.push({x:rainX,y:0,s:speed});}else if(thing == "snow"){s.snowLayer.graphics.clear();var snowX = Math.random()*(LStage.width-10-10)+10;var n = s.snowList.length;while(n--){var o = s.snowList[n];o.y += o.s;s.snowLayer.graphics.drawArc(2,"white",[o.x,o.y,size,0,2*Math.PI],true,"white");}s.snowList.push({x:snowX,y:0,s:speed});}}
前幾天做了一個留言板,歡迎大家發表自己的意見
留言板地址:http://www.cnblogs.com/yorhom/archive/2013/04/20/3033235.html
----------------------------------------------------------------
歡迎大家轉載我的文章。
轉載請註明:轉自Yorhom's Game Box
歡迎繼續關注我的部落格