html5遊戲開發-零基礎開發RPG遊戲-開源講座(三)-卷軸&對話實現
本文章首發自我的部落格 http://blog.csdn.net/lufy_legend/article/details/7094567
前兩篇,RPG的開發已經實現了新增地圖和新增遊戲人物,本篇來實現地圖的卷軸滾動和人物對話的實現,效果如下
地圖的滾動
關於地圖的滾動原理,可以參照下圖 按照上圖說明,實現地圖滾動,只需要先把即將出現的地圖(圖中黃色部分)畫上,然後滾動地圖,待地圖滾動完畢之後,將螢幕之外的部分(圖中綠色部分)移除
首先要新增一個變數來控制地圖是否滾動
//地圖滾動
var mapmove = false;
然後,在人物移動的時候,判斷地圖是否需要滾動
/**
* 地圖是否滾動
**/
Character.prototype.checkMap = function (dir){
var self = this;
mapmove = false;
//如果不是英雄,則地圖不需要滾動
if(!self.isHero)return;
switch (dir){
case UP:
if(self.y + charaLayer.y> STEP)break;
if(mapLayer.y >= 0)break;
addMap(0,-1);
mapmove = true;
break;
case LEFT:
if(self.x + charaLayer.x > STEP)break;
if(mapLayer.x >= 0)break;
addMap(-1,0);
mapmove = true;
break;
case RIGHT:
if(self.x < 480 - 2*STEP)break;
if(480 - mapLayer.x >= map[0].length*STEP)break;
addMap(1,0);
mapmove = true;
break;
case DOWN:
if(self.y < 288 - 2*STEP)break;
if(288 - mapLayer.y >= map.length*STEP)break;
addMap(0,1);
mapmove = true;
break;
}
};
在移動過程中,判斷地圖是否處於滾動狀態,如果地圖處於滾動,則滾動地圖,否則移動人物
/**
* 開始移動
**/
Character.prototype.onmove = function (){
var self = this;
//設定一個移動步長中的移動次數
var ml_cnt = 4;
//計算一次移動的長度
var ml = STEP/ml_cnt;
//根據移動方向,開始移動
switch (self.direction){
case UP:
if(mapmove){
mapLayer.y += ml;
charaLayer.y += ml;
}
self.y -= ml;
break;
case LEFT:
if(mapmove){
mapLayer.x += ml;
charaLayer.x += ml;
}
self.x -= ml;
break;
case RIGHT:
if(mapmove){
mapLayer.x -= ml;
charaLayer.x -= ml;
}
self.x += ml;
break;
case DOWN:
if(mapmove){
mapLayer.y -= ml;
charaLayer.y -= ml;
}
self.y += ml;
break;
}
self.moveIndex++;
//當移動次數等於設定的次數,開始判斷是否繼續移動
if(self.moveIndex >= ml_cnt){
//一個地圖步長移動完成後,如果地圖處於滾動狀態,則移除多餘地圖塊
if(mapmove)delMap();
self.moveIndex = 0;
//如果已經鬆開移動鍵,或者前方為障礙物,則停止移動,否則繼續移動
if(!isKeyDown || !self.checkRoad()){
self.move = false;
return;
}else if(self.direction != self.direction_next){
self.direction = self.direction_next;
self.anime.setAction(self.direction);
}
//地圖是否滾動
self.checkMap(self.direction);
}
};
最後,將地圖的陣列和地形擴大為大於螢幕大小
//地圖圖片陣列
var map = [
[18,18,18,18,18,18,18,18,18,18,18,18,55,55,18,18,18],
[18,18,18,17,17,17,17,17,17,17,17,17,55,55,17,17,18],
[18,18,17,17,17,17,18,18,17,17,17,17,55,55,17,17,18],
[18,17,17,17,18,18,18,18,18,17,17,55,55,17,17,17,18],
[18,17,17,18,22,23,23,23,24,18,17,55,55,17,17,17,18],
[18,17,17,18,25,28,26,79,27,18,55,55,17,17,17,17,18],
[18,17,17,17,17,10,11,12,18,18,55,55,17,17,17,17,18],
[18,18,17,17,10,16,16,16,11,55,55,17,17,17,17,17,18],
[18,18,17,17,77,16,16,16,16,21,21,17,17,17,17,17,18],
[18,18,17,17,77,16,16,16,16,55,55,17,17,17,17,17,18],
[18,18,18,18,18,18,18,18,18,55,55,18,18,18,18,18,18]
];
//地圖地形陣列
var mapdata = [
[1,1,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,0,0,1],
[1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1],
[1,0,0,0,1,1,1,1,1,0,0,1,1,0,0,0,1],
[1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,0,1],
[1,0,0,1,1,1,0,1,1,1,1,1,0,0,0,0,1],
[1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1],
[1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1],
[1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
];
為了實現地圖滾動,修改新增地圖的方法,根據引數來實現新增上面圖片的黃色地圖部分
//新增地圖
function addMap(cx,cy){
var i,j,index,indexX,indexY;
var bitmapdata,bitmap;
var mapX = mapLayer.x / STEP;
var mapY = mapLayer.y / STEP;
var mx = cx<0?-1:0,my = cy<0?-1:0;
if(imageArray == null){
//地圖圖片資料
bitmapdata = new LBitmapData(imglist["map"]);
//將地圖圖片拆分,得到拆分後的各個小圖片的座標陣列
imageArray = LGlobal.divideCoordinate(bitmapdata.image.width,bitmapdata.image.height,10,10);
}
mapLayer.removeAllChild();
//在地圖層上,畫出15*10的小圖片
for(i=my;i<9 +Math.abs(cy) && i-mapY < map.length;i++){
for(j=mx;j<15 +Math.abs(cx)&& j-mapX < map[0].length;j++){
//從地圖陣列中得到相應位置的圖片座標
index = map[i-mapY][j-mapX];
//小圖片的豎座標
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*STEP - mapLayer.x;
bitmap.y = i*STEP - mapLayer.y;
//將小圖片顯示到地圖層
mapLayer.addChild(bitmap);
}
}
}
//移除多餘地圖塊
function delMap(){
var bitmap,i;
for(i=0;i<mapLayer.childList.length;i++){
bitmap = mapLayer.childList[i];
if(bitmap.x + mapLayer.x < 0 || bitmap.x + mapLayer.x >= 480 ||
bitmap.y + mapLayer.y < 0 || bitmap.y + mapLayer.y >= 288){
mapLayer.removeChild(bitmap);
i--;
}
}
}
看一下效果如下
人物的對話
對話的實現,在點選控制按鈕的方形按鈕時新增,所以,先在滑鼠抬起的時候,判斷是否點選了方形按鈕
function onup(event){
isKeyDown = false;
if(event.offsetX >= ctrlLayer.x + 280 && event.offsetX <= ctrlLayer.x+330){
if(event.offsetY >= ctrlLayer.y+40 && event.offsetY <= ctrlLayer.y+100){
//對話
addTalk();
}
}
}
在完善addTalk()方法的時候,首先準備好對話的內容
var talkScriptList = {
"talk1":new Array(
{img:"m",name:"鳴人",msg:"我是木葉村的鳴人,你是誰?"},
{img:"n",name:"黑衣忍者甲",msg:"你就是鳴人?九尾還在你身體裡嗎?"}
),
"talk2":new Array(
{img:"n",name:"黑衣忍者乙",msg:"鳴人,聽說忍者大戰就要開始了。"},
{img:"m",name:"鳴人",msg:"真的嗎?一定要想想辦法啊。"}
)
};
talk1,talk2中talk後面的數字,代表人物的編號,其中每個對話單位的img為人物的頭像,name為人物的名稱,msg為對話的內容 新增對話時的做法是,當點選方形按鈕後,判斷小鳴人前方是否有人,如果有人,則將這個人物的編號取出來,再從上面的陣列中獲取相應的對話內容,然後,將相應的內容顯示到遊戲螢幕上,具體實現程式碼如下
//對話內容
var talkScript;
var talkScriptList = {
"talk1":new Array(
{img:"m",name:"鳴人",msg:"我是木葉村的鳴人,你是誰?"},
{img:"n",name:"黑衣忍者甲",msg:"你就是鳴人?九尾還在你身體裡嗎?"}
),
"talk2":new Array(
{img:"n",name:"黑衣忍者乙",msg:"鳴人,聽說忍者大戰就要開始了。"},
{img:"m",name:"鳴人",msg:"真的嗎?一定要想想辦法啊。"}
)
};
//對話序號
var talkIndex = 0;
//對話中
var talking = false;
/**
* 新增對話
* */
function addTalk(){
//如果對話內容為空,則開始判斷是否可以對話
if(talkScript == null){
var key,tx = player.x,ty = player.y;
switch (player.direction){
case UP:
ty -= STEP;
break;
case LEFT:
tx -= STEP;
break;
case RIGHT:
tx += STEP;
break;
case DOWN:
ty += STEP;
break;
}
for(key in charaLayer.childList){
//判斷前面又沒有npc,有則開始對話
if(charaLayer.childList[key].x == tx && charaLayer.childList[key].y == ty){
if(talkScriptList["talk"+charaLayer.childList[key].index]){
talkScript = talkScriptList["talk"+charaLayer.childList[key].index];
talkIndex = 0;
}
}
}
//如果前方沒有npc,則返回
if(talkScript == null)return;
}
//將對話層清空
talkLayer.removeAllChild();
//當對話開始,且按照順序進行對話
if(talkIndex < talkScript.length){
//得到對話內容
var talkObject = talkScript[talkIndex];
//對話背景
bitmapdata = new LBitmapData(imglist["talk"]);
bitmap = new LBitmap(bitmapdata);
bitmap.width = 330;
bitmap.height = 70;
bitmap.x = 100;
bitmap.y = 20;
bitmap.alpha = 0.7;
talkLayer.addChild(bitmap);
//對話頭像
bitmapdata = new LBitmapData(imglist[talkObject.img]);
bitmap = new LBitmap(bitmapdata);
bitmap.x = 0;
bitmap.y = 0;
talkLayer.addChild(bitmap);
//對話人物名稱
var name = new LTextField();
name.x = 110;
name.y = 30;
name.size = "14";
name.color = "#FFFFFF";
name.text = "[" + talkObject.name + "]";
talkLayer.addChild(name);
//對話內容
var msg = new LTextField();
msg.x = 110;
msg.y = 55;
msg.color = "#FFFFFF";
msg.text = talkObject.msg;
talkLayer.addChild(msg);
//對話內容逐字顯示
msg.wind();
talkLayer.x = 20;
talkLayer.y = 50;
talkIndex++;
}else{
//對話結束
talkScript = null;
}
}
效果看下圖
遊戲演示地址 http://lufylegend.com/demo/rpg/index.html
lufylegend.js引擎包內包含這個demo,請直接下載lufylegend.js引擎,檢視引擎包內原始碼
lufylegend.js引擎下載地址 http://lufylegend.com/lufylegend
相關文章
- html5遊戲開發-零基礎開發RPG遊戲-開源講座(一)HTML遊戲開發
- html5遊戲開發-零基礎開發RPG遊戲-開源講座(二)-跑起來吧英雄HTML遊戲開發
- html5遊戲開發-零基礎開發RPG遊戲-開源講座(四)-遊戲指令碼化&地圖跳轉HTML遊戲開發指令碼地圖
- HTML5 遊戲開發基礎的教程HTML遊戲開發
- 阿里開源HTML5小遊戲開發框架Hilo實戰教程阿里HTML遊戲開發框架
- 《HTML5完美遊戲開發》——2.8資源分享HTML遊戲開發
- 零基礎瞭解3D遊戲開發3D遊戲開發
- 來自 Mozilla 的 HTML5 遊戲開發資源HTML遊戲開發
- HTML5遊戲開發進階 12:多人對戰遊戲操作HTML遊戲開發
- Java嵌入式開發講座(第三講)Java
- HTML5遊戲開發進階 3 :物理引擎基礎HTML遊戲開發
- HTML5遊戲開發(三):使用webpack構建TypeScript應用HTML遊戲開發WebTypeScript
- HTML5 canvas遊戲開發實戰 5 : 石頭剪刀布HTMLCanvas遊戲開發
- HTML5遊戲開發——骰子游戲(一)HTML遊戲開發
- 實戰Flash遊戲開發遊戲開發
- 遊戲開發入門(一)遊戲開發概述遊戲開發
- HTML5遊戲開發進階 11:WebSocket與多人對戰模式HTML遊戲開發Web模式
- 遊戲開發遊戲開發
- HTML5 canvas遊戲開發實戰 6 : 俄羅斯方塊HTMLCanvas遊戲開發
- HTML5遊戲開發5條建議及開發工具分享HTML遊戲開發
- RPG 製作大師:古老的遊戲開發入門工具遊戲開發
- DirectShow系列講座之三——開發自己的Filter (轉)Filter
- iPhone遊戲開發實踐指南iPhone遊戲開發
- HTML5 canvas遊戲開發實戰 7 : "是男人就下一百層“遊戲HTMLCanvas遊戲開發
- 遊戲開發中怪物AI實現方案總結!遊戲開發AI
- CocosCreator遊戲開發(五)實現技能按鈕遊戲開發
- Unity遊戲開發技巧集錦2.1.3實現效果Unity遊戲開發
- Unity遊戲示例來了,用Unity開源遊戲資源做遊戲,遊戲開發不再難!Unity遊戲開發
- ios遊戲開發iOS遊戲開發
- flash遊戲開發遊戲開發
- 遊戲開發流程遊戲開發
- J2ME遊戲開發例項講解遊戲開發
- HTML5遊戲開發過程中的二三事HTML遊戲開發
- HTML5遊戲開發進階 6 :加入單位HTML遊戲開發
- HTML5遊戲開發進階 4 :物理引擎整合HTML遊戲開發
- HTML5遊戲開發進階 8 :新增更多的遊戲元素HTML遊戲開發
- HTML5遊戲開發進階 2 :建立基本的遊戲世界HTML遊戲開發
- 遊戲開發經驗——遊戲開發的基本常識(轉)遊戲開發