html5遊戲開發-零基礎開發RPG遊戲-開源講座(一)

lufy發表於2013-05-27

本文章首發自我的部落格 http://blog.csdn.net/lufy_legend/article/details/7063316

在遊戲的世界裡,我們可以看到各種地圖,各種遊戲人物,看到人物在地圖上行走,對話等,無論是地圖還是人物,其實都是圖片的處理與顯示,把不同的圖片顯示到螢幕上,我們就看到不同的遊戲介面,要想讓這些圖片同時顯示到介面上,我們就需要處理好層次,讓他們來分層顯示,我們可以想象,如果遊戲人物顯示在地圖的下層的話,顯然會被地圖遮擋住。 一款RPG遊戲,我簡單把它分為地圖層,人物層,效果層(一些法術效果等),對話層,控制層(按鈕選單等)。

如下圖 enter image description here 我們只要依次將圖片畫在螢幕上,遊戲人物將站在地圖上,如果有對話,對話將出現在人物和地圖的上面,而按鈕等控制元件會出現在遊戲的最外層 下面,我們一步步來實現一個簡單的RPG遊戲的開發 準備工作 一,引擎下載 本遊戲開發,需要用到HTML5開源引擎lufylegend.js 下載地址為:http://lufylegend.com/lufylegend 二,配置 首先建立一個資料夾rpg(你也可以起其他的名字) 將下載好的lufylegend.js引擎的最新版本放到與rpg資料夾同目錄 然後,在rpg資料夾裡建一個index.html檔案和一個js資料夾,在js資料夾裡建一個Main.js檔案 最後,在index.html里加入下面的程式碼

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>rpg</title>
</head>
<body>
<div id="mylegend">loading……</div>
<script type="text/javascript" src="./llufylegend-1.7.5.js"></script> 
<script type="text/javascript" src="./js/Main.js"></script> 
</body></html>

遊戲地圖的實現

接下來,我們先來畫最底層的地圖層, 地圖當然就是是由圖片來組成的,如何在畫面上顯示一張圖片,我之前已經寫過專門的文章,程式碼如下

var loader;  
function main(){  
    loader = new LLoader();  
    loader.addEventListener(LEvent.COMPLETE,loadBitmapdata);  
    loader.load("map.jpg","bitmapData");  
}  
function loadBitmapdata(event){  
    var bitmapdata = new LBitmapData(loader.content);  
    var bitmap = new LBitmap(bitmapdata);  
    addChild(bitmap);  
}  

遊戲中的地圖可以是一張比較大的圖片,即整個圖片就是遊戲的地圖,當人物或者地圖移動的時候,改變圖片顯示的區域範圍,從而實現地圖的滾動和顯示等,這樣的話,必須為每個場景準備一張地圖。

另外,地圖也可以是由許多小的地圖塊兒來組成,比如,我們熟悉的《吞食天地》,《勇者鬥惡龍》等經典小型rpg遊戲,這樣的地圖,我們需要準備一張或幾張地圖塊兒,把這些地圖塊組合成地圖來顯示,比如下圖 enter image description here 在地圖顯示的時候,首先把圖片切割,然後在根據預先設定好的位置顯示到地圖層上,這樣我們就看到了一張完整的地圖了 接下來,開啟Main.js 在裡面加入

init(50,"mylegend",480,320,main);

在lufylegend.js引擎中,用init這個函式來初始化canvas,上面的程式碼表示,初始化一個速度為50,名字為mylegend,大小為480*320的遊戲介面,初始化完成後呼叫main(),這個速度值是說每個多少毫秒遊戲迴圈一次,所以這個值設定的越小,遊戲執行的速度就越快 因為要呼叫main方法,所以我們要寫一個main方法,main方法裡做一些簡單的準備工作。 雖說讀取圖片只需要一個

loader.load("map.jpg","bitmapData");  

但是遊戲中往往用到很多張圖片,你可以用到哪一張再載入哪一張,也可以一次性全部載入完,然後再開始顯示遊戲 為了一次性把圖片載入完,我的做法是,將需要的圖片放到一個陣列裡,然後設定一個索引,每載入一個圖片,讓這個索引加1,當這個索引小於陣列的長度,則繼續載入,直到將陣列中的圖片全部載入完,然後開始進行下一步的工作 具體實現看下面的程式碼

//圖片path陣列
var imgData = new Array();
//讀取完的圖片陣列
var imglist = {};

function main(){
    //準備讀取圖片
    imgData.push({name:"map",path:"./image/map.jpg"});
    imgData.push({name:"mingren",path:"./image/mingren.png"});
    imgData.push({name:"e1",path:"./image/e1.png"});
    imgData.push({name:"e2",path:"./image/e2.png"});
    //例項化進度條層
    loadingLayer = new LSprite();
    loadingLayer.graphics.drawRect(1,"black",[50, 200, 200, 20],true,"#ffffff");
    addChild(loadingLayer);
    //開始讀取圖片
    loadImage();
}
function loadImage(){
    //圖片全部讀取完成,開始初始化遊戲
    if(loadIndex >= imgData.length){
        removeChild(loadingLayer);
        gameInit();
        return;
    }
    //開始讀取圖片
    loader = new LLoader();
    loader.addEventListener(LEvent.COMPLETE,loadComplete);
    loader.load(imgData[loadIndex].path,"bitmapData");
}
function loadComplete(event){
    //進度條顯示
    loadingLayer.graphics.clear();
    loadingLayer.graphics.drawRect(1,"black",[50, 200, 200, 20],true,"#ffffff");
    loadingLayer.graphics.drawRect(1,"black",[50, 203, 200*(loadIndex/imgData.length), 14],true,"#000000");
    //儲存圖片資料
    imglist[imgData[loadIndex].name] = loader.content;
    //讀取下一張圖片
    loadIndex++;
    loadImage();
}

上面的程式碼不難明白,當圖片沒有讀取完之前,會不斷迴圈loadImage和loadComplete兩個方法,當讀取完之後,移除進度條,用legendLoadOver告訴遊戲已經讀取完成,然後呼叫gameInit方法,進行遊戲的初始化工作。 看gameInit方法

function gameInit(event){
    //遊戲層顯示初始化
    layerInit();
    //新增地圖
    addMap();
    //新增人物
    addChara();
}

在gameInit方法中,首先進行遊戲層的初始化,然後新增遊戲地圖,然後新增人物 遊戲層顯示初始化,按照我們一開始所說,我們一次來初始化地圖層,人物層,效果層,對話層,控制層

//遊戲層顯示初始化
function layerInit(){
    //遊戲底層新增
    backLayer = new LSprite();
    addChild(backLayer);
    //地圖層新增
    mapLayer = new LSprite();
    backLayer.addChild(mapLayer);
    //人物層新增
    charaLayer = new LSprite();
    backLayer.addChild(charaLayer);
    //效果層新增
    effectLayer = new LSprite();
    backLayer.addChild(effectLayer);
    //對話層新增
    talkLayer = new LSprite();
    backLayer.addChild(talkLayer);
    //控制層新增
    ctrlLayer = new LSprite();
    backLayer.addChild(ctrlLayer);
}

有了遊戲層次的劃分,我們在新增遊戲物件的時候,將地圖新增到地圖層,人物新增到人物層,他們就會依次顯示在遊戲的介面上 下面開始新增地圖 首先我們需要準備好顯示地圖的陣列

//地圖圖片陣列
var map = [
[18,18,18,18,18,18,18,18,18,18,18,18,55,55,18],
[18,18,18,17,17,17,17,17,17,17,17,17,55,55,18],
[18,18,17,17,17,17,18,18,17,17,17,17,55,55,18],
[18,17,17,17,18,18,18,18,18,17,17,55,55,17,18],
[18,17,17,18,22,23,23,23,24,18,17,55,55,17,18],
[18,17,17,18,25,28,26,79,27,18,55,55,17,17,18],
[18,17,17,17,17,10,11,12,18,18,55,55,17,17,18],
[18,18,17,17,10,16,16,16,11,55,55,17,17,17,18],
[18,18,17,17,77,16,16,16,16,21,21,17,17,17,18],
[18,18,18,18,18,18,18,18,18,55,55,18,18,18,18]
];

這些數字分別對應著圖中如下位置 enter image description here 然後看下面程式碼

//新增地圖
function addMap(){
    var i,j,index,indexX,indexY;
    var bitmapdata,bitmap;
    //地圖圖片資料
    bitmapdata = new LBitmapData(imglist["map"]);
    //將地圖圖片拆分,得到拆分後的各個小圖片的座標陣列
    imageArray = LGlobal.divideCoordinate(bitmapdata.image.width,bitmapdata.image.height,10,10);

    //在地圖層上,畫出15*10的小圖片
    for(i=0;i<10;i++){
        for(j=0;j<15;j++){
            //從地圖陣列中得到相應位置的圖片座標
            index = map[i][j];
            //小圖片的豎座標
            indexY = Math.floor(index /10);
            //小圖片的橫座標
            indexX = index - indexY*10;
            //得到小圖片
            bitmapdata = new LBitmapData(imglist["map"],indexX*32,indexY*32,32,32);
            bitmap = new LBitmap(bitmapdata);
            //設定小圖片的顯示位置
            bitmap.x = j*32;
            bitmap.y = i*32;
            //將小圖片顯示到地圖層
            mapLayer.addChild(bitmap);
        }
    }
}

這樣,我們就把預先設定好的圖片顯示到了遊戲介面上,形成了地圖 先把addChara方法加上

//新增人物
function addChara(){
}

然後執行遊戲 可以得到下面畫面 enter image description here 遊戲人物的實現 為了更好的實現遊戲人物的控制,我們新建一個遊戲人物類Character.js 裡面程式碼如下

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);
};
Character.prototype.onframe = function (){
    var self = this;
    if(self.speedIndex++ < self.speed)return;
    self.speedIndex = 0;
    self.anime.onframe();
};

在lufylegend.js引擎裡,有一個LAnimation類,用來實現圖片陣列順序播放,形成動畫 使用LAnimation類需要三個引數,一個是顯示動畫的層,一個是圖片,一個是圖片的座標陣列 然後,呼叫LAnimation類的onframe方法,就可以實現動畫的播放了 在index.html中引入Character類,然後修改addChara方法,

//新增人物
function addChara(){
    bitmapdata = new LBitmapData(imglist["mingren"]);
    player = new Character(bitmapdata,4,4);
    player.x = 32*5;
    player.y = 32*6;
    charaLayer.addChild(player);

}

在gameInit的末尾新增迴圈事件

//新增貞事件,開始遊戲迴圈
backLayer.addEventListener(LEvent.ENTER_FRAME,onframe);

最後,新增onframe方法

/**
 * 迴圈
 * */
function onframe(){
    player.onframe();
}

執行程式碼,看到了嗎 一個會動的鳴人出現在遊戲的地圖上了 enter image description here 遊戲演示

http://lufylegend.com/demo/rpg/index.html

lufylegend.js引擎包內包含這個demo,請直接下載lufylegend.js引擎,檢視引擎包內原始碼

lufylegend.js引擎下載地址

http://lufylegend.com/lufylegend

下次,就要新增控制層,實現人物的走動和地圖的滾動等,希望大家多多支援。

相關文章