在一款rpg遊戲中,與各處的npc對話,或是在地圖中翻箱倒櫃都是能令玩家深入挖掘的要素,
特別是在一款rpg遊戲中一般有着衆多的npc,而且豐富的npc對話可以很好的還原遊戲的世界觀和塑造人物性格,所以對於一款rpg遊戲來說,豐富的對話是必不可少的,下面就來介紹一下使用lufylegend如何實現這個功能,下面以npc對話爲列子來進行介紹。(寶箱的實現方式一致,稍微改一下所調用的東西即可)
既然是npc對話,就需要先看一下一般遊戲是什麼樣的形式,大致的情況是,接近npc後提示對話按鍵,按鍵後出現對話,並可以反覆對話,不同npc對話不同,這幾個條件,
那麼首先需要實現的就是npc類,用以顯示npc,npc類需要的就是npc模型,以及npc的對話,npc的位置,大致這幾個需要載入的變量,那麼類的定義就變的很容易了,下面是類的實現,npcdata代表npc的位置,img代表npc的模型,(這裏把對話拉出來定義了,一般是放在類裏面定義的)
function LNpc(npcdata,img){
var s = this;
base(s,LSprite,[]);
s.NpcData = npcdata;
s.imgData=img;
s.onshow();
}
ohshow函數的定義如下,和之前的人物類形式並沒有太大的區別
LNpc.prototype.onshow = function(){
var s = this;
var mapdata = s.NpcData;
var bitmapdata,bitmap;
for(var i=0;i<s.NpcData.length;i++){
var sprite=new LSprite();
bitmapdata=new LBitmapData(s.imgData,240,0,80,80);
bitmap=new LBitmap(bitmapdata);
bitmap.scaleX=0.4;
bitmap.scaleY=0.4;
sprite.width=32;
sprite.height=32;
sprite.x=s.NpcData[i][0];
sprite.y=s.NpcData[i][1];
sprite.addChild(bitmap);
s.addChild(sprite);
}
}
接下來實現接近npc後提示對話按鍵這個需求,爲了實現這個需求,就有必要判斷是否與npc接觸這個條件,這裏採用貼身爲判定條件,所以需要在人物類中添加檢測碰撞的函數,因爲採用貼身所以相比一般的判定來說多了一個貼身的條件
LCharcter.prototype.CheckboxContact=function(box){
var s=this;
//box在右側
if((s.x>box.x)&&(box.x+box.width==s.x)&&(s.y==box.y)){
return true;
//box在左側
}else if((s.x<box.x)&&(s.x+s.width==box.x)&&(s.y==box.y)){
return true;
//box在下測
}else if((s.y<box.y)&&(s.y+s.height==box.y)&&(s.x==box.x)){
return true;
//box在上測
}else if((s.y>box.y)&&(box.y+box.height==s.y)&&(s.x==box.x)){
return true;
}else{
return false;
}
}
之後將這個函數加入遊戲的刷新函數裏面進行判斷,如果爲貼身就提示按鍵,這裏選擇用A鍵來觸發對話,需要注意的是這裏的break,因爲npc的位置是不同的,因爲是全量判斷,所以如果一直做就會將 buttonLayer.text賦值爲空,所以這裏選擇一旦與其中一個npc解除就直接break,避免後續將賦值重置
function onframe(){
//checkscene();
for(var i=0;i<npcLayer.childList.length;i++){
if(playerLayer.CheckboxContact(npcLayer.childList[i])){
buttonLayer.text="A鍵";
npcnumber=i;
break;
}else{
buttonLayer.text="";
npcnumber=-1;
}
}
if(diaflag==false){
checkdialog();
}
}
接下來需要實現的就是載入對話,這個在之前已經實現了對話類,這裏直接使用,相關可以參考之前的blog:
http://blog.csdn.net/qq_26786555/article/details/45541539
修改一下按鍵觸發函數,這樣就可以在按下a鍵並與npc解除時觸發對話了,因爲npc對話並不同於劇情對話,所以這裏並沒有設置不可重複觸發的flag
function move(e){
if(!diastartflag){
if(e.keyCode==37||e.keyCode==38||e.keyCode==39||e.keyCode==40){
playerLayer.move(e.keyCode);
}else if((buttonLayer.text=="A鍵")&&(e.keyCode==65)){
var dia2=new LDialog(dia[npcnumber]);
diaLayer.addChild(dia2);
}
}
}
這樣與npc對話就實現了,效果如下:
源代碼:
index.php
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8" />
<title>LTileMap</title>
<script type="text/javascript" src="lufylegend.js-lufylegend-1.9.7/lufylegend-1.9.7.min.js"></script>
<script type="text/javascript" src="LCharcter.js"></script>
<script type="text/javascript" src="LDialog.js"></script>
<script type="text/javascript" src="map.js"></script>
<script type="text/javascript" src="LNpc.js"></script>
<script src="jquery/jquery-1.8.3.js"></script>
<script>
LInit(30,"legend",448,320,main);
LGlobal.setDebug(true);
var backLayer,loadingLayer,mapLayer,playerLayer,diaLayer;
var boxLayer;//寶箱層
var npcLayer;//npc所在位置
var boxData=[];
var npcData=[[64,96],[160,192]];
var buttonLayer;
var npcnumber=-1;//-1爲無npc可對話
var diaflag=false;//false代表未發生對話,true代表發生
var diastartflag=false;//代表對話開始,禁用操作
var dia;
var loadData = [
{name:"cr",path:"./images/charc.jpg"},
{name:"map",path:"./images/map.jpg"},
{name:"money",path:"./images/bird.png"},
{name:"photo1",path:"./images/66RPG_002_f.png"},
{name:"photo2",path:"./images/66RPG_005_f.png"}
];
var mapData=[[[18,1],[18,1],[18,1],[18,1],[18,1],[18,1],[18,1],[18,1],[18,1],[18,1],[18,1],[18,1],[55,1],[55,1],[18,1]],
[[18,1],[18,1],[18,1],[17,0],[17,0],[17,0],[17,0],[17,0],[17,0],[17,0],[17,0],[17,0],[55,1],[55,1],[18,1]],
[[18,1],[18,1],[17,0],[17,0],[17,0],[17,0],[18,1],[18,1],[17,0],[17,0],[17,0],[17,0],[55,1],[55,1],[18,1]],
[[18,1],[17,0],[17,2],[17,0],[18,1],[18,1],[18,1],[18,1],[18,1],[17,0],[17,0],[55,1],[55,1],[17,0],[18,1]],
[[18,1],[17,0],[17,0],[18,1],[22,1],[23,1],[23,1],[23,1],[24,1],[18,1],[17,0],[55,1],[55,1],[17,0],[18,1]],
[[18,1],[17,0],[17,0],[18,1],[25,1],[28,1],[26,1],[79,1],[27,1],[18,1],[55,1],[55,1],[17,0],[17,0],[18,1]],
[[18,1],[17,0],[17,0],[17,0],[17,0],[10,2],[11,0],[12,0],[18,1],[18,1],[55,1],[55,1],[17,0],[17,0],[18,1]],
[[18,1],[18,1],[17,0],[17,0],[10,0],[16,0],[16,0],[16,0],[11,0],[55,1],[55,1],[17,0],[17,0],[17,0],[18,1]],
[[18,1],[18,1],[17,0],[17,0],[77,0],[16,0],[16,0],[16,0],[16,0],[21,0],[21,0],[17,0],[17,0],[17,0],[18,1]],
[[18,1],[18,1],[18,1],[18,1],[18,1],[18,1],[18,1],[18,1],[18,1],[55,1],[55,1],[18,1],[18,1],[18,1],[18,1]]];
var imglist=[];
function main(){
//加入進度條
loadingLayer = new LoadingSample3();
addChild(loadingLayer);
//加載圖片並顯示進度
LLoadManage.load(
loadData,
function(progress){
loadingLayer.setProgress(progress);
},
gameInit
);
}
function gameInit(result){
removeChild(loadingLayer);
imglist = result;
backLayer = new LSprite();
addChild(backLayer);
mapLayer = new LTileMap(mapData,imglist["map"],32,32);
dia=[[[imglist["photo2"],"hello,My name is lianggong",1],
[imglist["photo1"],"well,you are so fast",2],
[imglist["photo2"],"em,I am the fastest",1],
[imglist["photo2"],"I am the lightning nova",1]],
[[imglist["photo2"],"hello,My name is lianggongzhazha",1],
[imglist["photo1"],"well,you are so fast",2],
[imglist["photo2"],"em,I am the fastest",1],
[imglist["photo2"],"I am the lightning nova",1]]];
backLayer.addChild(mapLayer);
playerLayer=new LCharcter(imglist["cr"]);
backLayer.addChild(playerLayer);
//加入寶箱層
boxLayer=new LSprite();
backLayer.addChild(boxLayer);
//加入npc層
npcLayer=new LNpc(npcData,imglist["cr"]);
npcLayer.x=0;
npcLayer.y=0;
backLayer.addChild(npcLayer);
//加入對話層
diaLayer=new LSprite();
backLayer.addChild(diaLayer);
//加入按鍵提示層
buttonLayer=new LTextField();
buttonLayer.x=422;
buttonLayer.y=300;
buttonLayer.size=12;
backLayer.addChild(buttonLayer);
//加入動畫和按鍵事件監聽
backLayer.addEventListener(LEvent.ENTER_FRAME,onframe);
LEvent.addEventListener(LGlobal.window, LKeyboardEvent.KEY_DOWN,move);
LEvent.addEventListener(LGlobal.window, LKeyboardEvent.KEY_UP,stop);
}
function onframe(){
//checkscene();
for(var i=0;i<npcLayer.childList.length;i++){
if(playerLayer.CheckboxContact(npcLayer.childList[i])){
buttonLayer.text="A鍵";
npcnumber=i;
break;
}else{
buttonLayer.text="";
npcnumber=-1;
}
}
if(diaflag==false){
checkdialog();
}
}
function move(e){
if(!diastartflag){
if(e.keyCode==37||e.keyCode==38||e.keyCode==39||e.keyCode==40){
playerLayer.move(e.keyCode);
}else if((buttonLayer.text=="A鍵")&&(e.keyCode==65)){
var dia2=new LDialog(dia[npcnumber]);
diaLayer.addChild(dia2);
}
}
}
function stop(e){
playerLayer.stop();
}
function checkscene(){
if((playerLayer.x==192)&&(playerLayer.y==192))
{
window.location.href="nextmap.php";
}
}
function checkdialog(){
var dia1=new Array(dia.length);
if((playerLayer.x==192)&&(playerLayer.y==192))
{
diastartflag=true;
var dia2=new LDialog(dia[0]);
diaLayer.addChild(dia2);
diaflag=true;
}
}
function loaddialog(dia){
/* var i=0;
var dia1=new LDialog(dia[i]);
diaLayer.addChild(dia1);
dia1.onshow(function(){if(i<dia.length){i=i+1;var dia1=new LDialog(dia[i]);diaLayer.addChild(dia1);dia1.onshow(function(){if(i<dia.length){i=i+1;
var dia1=new LDialog(dia[i]);diaLayer.addChild(dia1);dia1.onshow()}else{
i=i+1;var dia1=new LDialog(dia[i]);diaLayer.addChild(dia1);dia1.onshow();
}})}else{
i=i+1;var dia1=new LDialog(dia[i]);diaLayer.addChild(dia1);dia1.onshow();
}})
*/
}
function onMouseDown(){
for(i=0;i<diaLayer.childList.length;i++){
diaLayer.childList[i].clear();
}
}
</script>
</head>
<body>
<div id="legend"></div>
</body>
</html>
LNPc.js
var NpcLayer;
function LNpc(npcdata,img){
var s = this;
base(s,LSprite,[]);
s.NpcData = npcdata;
s.imgData=img;
s.onshow();
}
LNpc.prototype.GetMapData = function(){
var s=this;
return s.NpcData;
}
//0是x座標,1是Y座標
LNpc.prototype.onshow = function(){
var s = this;
var mapdata = s.NpcData;
var bitmapdata,bitmap;
for(var i=0;i<s.NpcData.length;i++){
var sprite=new LSprite();
bitmapdata=new LBitmapData(s.imgData,240,0,80,80);
bitmap=new LBitmap(bitmapdata);
bitmap.scaleX=0.4;
bitmap.scaleY=0.4;
sprite.width=32;
sprite.height=32;
sprite.x=s.NpcData[i][0];
sprite.y=s.NpcData[i][1];
sprite.addChild(bitmap);
s.addChild(sprite);
}
}