HTML 5開發RPG游戲之二(跑起來吧英雄)
上一篇中,已經詳細講解了,如何添加地圖,以及添加了一個游戲人物,現在我們來添加控制事件,讓這個小英雄走動起來
我們已經給游戲人物建立了一個Character類,
現在先來在類里加入
- Character.prototype.changeDir = function (dir){
- };
- /**
- * 設定人物坐標
- * @param x方向坐標,y方向坐標
- **/
- Character.prototype.setCoordinate = function (sx,sy){
- };
- /**
- * 獲取人物坐標
- **/
- Character.prototype.getCoordinate = function (){
- };
changeDir 這個方法用來從外部控制人物方向和移動
要控制游戲的人物,首先,我們要由控制事件,當觸發這個事件的時候,就來調用相應的方法,做我們想要的做的處理setCoordinate和getCoordinate是設定和得到人物當前的坐標
首先,為了適應智能手機,我們暫時不用鍵盤事件,而是用點擊事件,所以我們先來添加兩個控制按鈕,在Main.js的gameInit方法的最下方,添加如下代碼
- //添加控制按鈕
- bitmapdata = new LBitmapData(imglist["e1"]);
- bitmap = new LBitmap(bitmapdata);
- bitmap.x = 0;
- bitmap.y = 0;
- ctrlLayer.addChild(bitmap);
- bitmapdata = new LBitmapData(imglist["e2"]);
- bitmap = new LBitmap(bitmapdata);
- bitmap.x = 280;
- bitmap.y = 30;
- ctrlLayer.addChild(bitmap);
- ctrlLayer.x = 40;
- ctrlLayer.y = 180;
運行代碼,得到預覽如下
在添加控制事件之前,為了實現控制方便,我們先來添加幾個變量
- //方向變量
- var DOWN = 0;
- var LEFT = 1;
- var RIGHT = 2;
- var UP = 3;
- var STEP = 32;
- //點擊狀態
- var isKeyDown = false;
STEP代表移動步長,因為地圖是有32*32的小圖片來組成的,所以我們設定人物移動的步長為32
方向變量的0,1,2,3分別對應下面圖片中的第1,2,3,4行的方向
之所以添加點擊狀態,是因為,當我們按下移動按鈕沒有抬起的時候,人物應該始終處于移動狀態,所以用這個變量來區分,我們是否按下或者抬起好了,做好了準備工作,現在就開始添加移動事件
- //添加點擊控制事件
- backLayer.addEventListener(LMouseEvent.MOUSE_DOWN,ondown);
- backLayer.addEventListener(LMouseEvent.MOUSE_UP,onup);
- function ondown(event){
- //根據點擊位置,判斷移動方向
- if(event.offsetX >= ctrlLayer.x + 40 && event.offsetX <= ctrlLayer.x+80){
- if(event.offsetY >= ctrlLayer.y && event.offsetY <= ctrlLayer.y+40){
- player.changeDir(UP);
- }else if(event.offsetY >= ctrlLayer.y+80 && event.offsetY <= ctrlLayer.y+120){
- player.changeDir(DOWN);
- }
- }else if(event.offsetX >= ctrlLayer.x && event.offsetX <= ctrlLayer.x+40){
- if(event.offsetY >= ctrlLayer.y +40 && event.offsetY <= ctrlLayer.y+80){
- player.changeDir(LEFT);
- }
- }else if(event.offsetX >= ctrlLayer.x+80 && event.offsetX <= ctrlLayer.x+120){
- if(event.offsetY >= ctrlLayer.y +40 && event.offsetY <= ctrlLayer.y+80){
- player.changeDir(RIGHT);
- }
- }
- isKeyDown = true;
- }
- function onup(event){
- isKeyDown = false;
- }
這里需要知道的是,在智能手機里,其實點擊事件是TOUCH_START,TOUCH_MOVE,TOUCH_END事件
使用legendForHtml5Programming庫件的時候,只需要添加MOUSE_DOWN,MOUSE_MOVE,MOUSE_UP事件,然后庫件會自動判斷是加載TOUCH事件還是MOUSE事件
在ondown方法中,我們將isKeyDown的狀態變為true,表示我們正處于按下狀態
然后,根據我們點擊的位置,來調用Character類的changeDir方法,并且傳入點擊的方向
有了控制事件,現在的關鍵就在于changeDir方法,只要根據傳進來的值,來實現移動就可以了
我們試想,如果每次移動一個步長的話,那么人物就會由一個小方格跳到令一個方格,而我們需要的是,讓它緩慢的移動到下一個方格,有一個移動的過程
為了實現這個過程,我們在移動的時候不是讓人物的坐標馬上就改變,而是改變人物的狀態,由靜止到移動,然后處于移動狀態的時候,再讓人物一小步一小步的移動到目標點
修改Character類的構造器,如下
- function Character(data,row,col,speed){
- base(this,LSprite,[]);
- var self = this;
- //設定人物動作速度
- self.speed = speed==null?3:speed;
- self.speedIndex = 0;
- //設定人物大小
- data.setProperties(0,0,data.image.width/col,data.image.height/row);
- //得到人物圖片拆分數組
- var list = LGlobal.divideCoordinate(data.image.width,data.image.height,row,col);
- //設定人物動畫
- self.anime = new LAnimation(this,data,list);
- //調整人物位置
- self.anime.y -= 16;
- //設定不移動
- self.move = false;
- //在一個移動步長中的移動次數設定
- self.moveIndex = 0;
- };
調整人物位置是因為,人物的圖片分割后,每個動作的大小為32*48,而地圖每個小格的大小是32*32,然后設定人物狀態為不移動,然后修改changeDir 方法
- /**
- * 改變人物方向
- **/
- Character.prototype.changeDir = function (dir){
- var self = this;
- //如果正在移動,則無效
- if(!self.move){
- //設定人物方向
- self.direction = dir;
- //設定圖片動畫
- self.anime.setAction(dir);
- //開始移動
- self.move = true;
- self.moveIndex = 0;
- }
- };
這里要簡單說明一下LAnimation類的setAction方法,setAction(rowindex,colindex)方法有兩個參數,LAnimation里傳進來的圖片數組是一個二維數組,這兩個參數分別可以改變目前顯示的圖片的動作,當然,也可以只傳其中一個參數
我這次是將4*4的人物動作圖片分割為4*4的二維數組傳給了LAnimation類,所以現在每一行圖片代表一個方向
人物狀態設置為移動后,就應該在循環事件里開始一步步的移動了
- /**
- * 循環事件
- **/
- Character.prototype.onframe = function (){
- var self = this;
- //人物動作速度控制
- if(self.speedIndex++ < self.speed)return;
- self.speedIndex = 0;
- //當人物可移動,則開始移動
- if(self.move)self.onmove();
- //人物動畫播放
- self.anime.onframe();
- };
- /**
- * 開始移動
- **/
- Character.prototype.onmove = function (){
- var self = this;
- //設定一個移動步長中的移動次數
- var ml_cnt = 4;
- //計算一次移動的長度
- var ml = STEP/ml_cnt;
- //根據移動方向,開始移動
- switch (self.direction){
- case UP:
- self.y -= ml;
- break;
- case LEFT:
- self.x -= ml;
- break;
- case RIGHT:
- self.x += ml;
- break;
- case DOWN:
- self.y += ml;
- break;
- }
- self.moveIndex++;
- //當移動次數等于設定的次數,開始判斷是否繼續移動
- if(self.moveIndex >= ml_cnt){
- self.moveIndex = 0;
- //如果已經松開移動鍵,則停止移動,否則繼續移動
- if(!isKeyDown){
- self.move = false;
- return;
- }
- }
- };
這里,我選擇了讓人物每個步長分四次進行移動,這樣就實現了緩慢移動的效果,運行程序,點擊畫面中的方向鍵,看到了把,人物已經可以開始移動了,而且是緩慢的移動
#p#
但是,光這樣還是不行,我們發現,人物是可以移動了,但是他現在是超人,飛檐走壁無所不入,移動的暢通無阻
這就需要我們在移動過程中,加入移動判斷,看看是否可以移動,
為了實現這個判斷,我們必須要知道地圖什么地方可以移動,什么地方不可以移動
所以,我們需要一個地圖的地形,如下
- //地圖地形數組
- var mapdata = [
- [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1],
- [1,1,1,0,0,0,0,0,0,0,0,0,1,1,1],
- [1,1,0,0,0,0,1,1,0,0,0,0,1,1,1],
- [1,0,0,0,1,1,1,1,1,0,0,1,1,0,1],
- [1,0,0,1,1,1,1,1,1,1,0,1,1,0,1],
- [1,0,0,1,1,1,0,1,1,1,1,1,0,0,1],
- [1,0,0,0,0,0,0,0,1,1,1,1,0,0,1],
- [1,1,0,0,0,0,0,0,0,1,1,0,0,0,1],
- [1,1,0,0,0,0,0,0,0,0,0,0,0,0,1],
- [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
- ];
地形數組中,0代表可以移動,1代表障礙物,是不可移動的,接下來,給Character類添加判斷方法
- /**
- * 障礙物判斷
- * @param 判斷方向
- **/
- Character.prototype.checkRoad = function (dir){
- var self = this;
- var tox,toy,myCoordinate;
- //當判斷方向為空的時候,默認當前方向
- if(dir==null)dir=self.direction;
- //獲取人物坐標
- myCoordinate = self.getCoordinate();
- //開始計算移動目的地的坐標
- switch (dir){
- case UP:
- tox = myCoordinate.x;
- toy = myCoordinate.y - 1;
- break;
- case LEFT:
- tox = myCoordinate.x - 1;
- toy = myCoordinate.y ;
- break;
- case RIGHT:
- tox = myCoordinate.x + 1;
- toy = myCoordinate.y;
- break;
- case DOWN:
- tox = myCoordinate.x;
- toy = myCoordinate.y + 1;
- break;
- }
- //如果移動的范圍超過地圖的范圍,則不可移動
- if(tox <= 0 || toy <= 0)return false;
- if(toy >= mapdata.length || tox >= mapdata[0].length)return false;
- //如果目的地為障礙,則不可移動
- if(mapdata[toy][tox] == 1)return false;
- return true;
- };
然后,在changeDir方法,和onmove方法中,添加相應的判斷,如下
- /**
- * 開始移動
- **/
- Character.prototype.onmove = function (){
- var self = this;
- //設定一個移動步長中的移動次數
- var ml_cnt = 4;
- //計算一次移動的長度
- var ml = STEP/ml_cnt;
- //根據移動方向,開始移動
- switch (self.direction){
- case UP:
- self.y -= ml;
- break;
- case LEFT:
- self.x -= ml;
- break;
- case RIGHT:
- self.x += ml;
- break;
- case DOWN:
- self.y += ml;
- break;
- }
- self.moveIndex++;
- //當移動次數等于設定的次數,開始判斷是否繼續移動
- if(self.moveIndex >= ml_cnt){
- self.moveIndex = 0;
- //如果已經松開移動鍵,或者前方為障礙物,則停止移動,否則繼續移動
- if(!isKeyDown || !self.checkRoad()){
- self.move = false;
- return;
- }
- }
- };
- /**
- * 改變人物方向,并判斷是否可移動
- **/
- Character.prototype.changeDir = function (dir){
- var self = this;
- //如果正在移動,則無效
- if(!self.move){
- //設定人物方向
- self.direction = dir;
- //設定圖片動畫
- self.anime.setAction(dir);
- //判斷是否可移動
- if(!self.checkRoad(dir))return;
- //如果可以移動,則開始移動
- self.move = true;
- self.moveIndex = 0;
- }
- };
好了,大功告成,開始運行吧
測試URL如下:http://fsanguo.comoj.com/html5/rpg/index.html
這次的源代碼下載:http://fsanguo.comoj.com/html5/rpg5/rpg5.rar
原文鏈接:http://www.cnblogs.com/html5cn/articles/2333828.html
【編輯推薦】