HTML 5开发RPG游戏之三(卷轴和对话)

开发 前端
按照上图说明,实现地图滚动,只需要先把即将出现的地图(图中黄色部分)画上,然后滚动地图,待地图滚动完毕之后,将屏幕之外的部分(图中绿色部分)

前两篇,RPG的开发已经实现了添加地图和添加游戏人物,本篇来实现地图的卷轴滚动和人物对话的实现,效果如下

本次开发,更新了一下库件至1.3,请点击下面的链接,下载库件1.3版以上版本

http://code.google.com/p/legendforhtml5programming/downloads/list

地图的滚动

关于地图的滚动原理,可以参照下图

按照上图说明,实现地图滚动,只需要先把即将出现的地图(图中黄色部分)画上,然后滚动地图,待地图滚动完毕之后,将屏幕之外的部分(图中绿色部分)移除

首先要添加一个变量来控制地图是否滚动

//地图滚动  
var mapmove = false
  • 1.
  • 2.

然后,在人物移动的时候,判断地图是否需要滚动

/**  
 * 地图是否滚动  
 **/ 
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;  
    }  
}; 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.

在移动过程中,判断地图是否处于滚动状态,如果地图处于滚动,则滚动地图,否则移动人物

/**  
 * 开始移动   
 **/ 
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);  
    }  
}; 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.

最后,将地图的数组和地形扩大为大于屏幕大小

//地图图片数组  
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]  
]; 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.

为了实现地图滚动,修改添加地图的方法,根据参数来实现添加上面图片的黄色地图部分

//添加地图  
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--;  
        }  
    }  

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.

看一下效果如下

 

 


 

#p#

人物的对话

对话的实现,在点击控制按钮的方形按钮时添加,所以,先在鼠标抬起的时候,判断是否点击了方形按钮

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();  
        }  
    }  

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.

在完善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:"真的吗?一定要想想办法啊。"}  
        )  
}; 
  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.

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;  
    }  

  • 1.
  • 2.
  • 3.
  • 4.
  • 5.
  • 6.
  • 7.
  • 8.
  • 9.
  • 10.
  • 11.
  • 12.
  • 13.
  • 14.
  • 15.
  • 16.
  • 17.
  • 18.
  • 19.
  • 20.
  • 21.
  • 22.
  • 23.
  • 24.
  • 25.
  • 26.
  • 27.
  • 28.
  • 29.
  • 30.
  • 31.
  • 32.
  • 33.
  • 34.
  • 35.
  • 36.
  • 37.
  • 38.
  • 39.
  • 40.
  • 41.
  • 42.
  • 43.
  • 44.
  • 45.
  • 46.
  • 47.
  • 48.
  • 49.
  • 50.
  • 51.
  • 52.
  • 53.
  • 54.
  • 55.
  • 56.
  • 57.
  • 58.
  • 59.
  • 60.
  • 61.
  • 62.
  • 63.
  • 64.
  • 65.
  • 66.
  • 67.
  • 68.
  • 69.
  • 70.
  • 71.
  • 72.
  • 73.
  • 74.
  • 75.
  • 76.
  • 77.
  • 78.
  • 79.
  • 80.
  • 81.
  • 82.
  • 83.
  • 84.
  • 85.
  • 86.
  • 87.
  • 88.
  • 89.
  • 90.
  • 91.
  • 92.
  • 93.
  • 94.
  • 95.
  • 96.

效果看下图

 

游戏演示地址:http://fsanguo.comoj.com/html5/rpg3/index.html

之前其他地方也稍微做了修改,具体修改请看源代码,此次更新源代码,下载地址如下:http://fsanguo.comoj.com/html5/rpg5/rpg5.rar

原文链接:http://www.cnblogs.com/html5cn/articles/2337032.html

【编辑推荐】

  1. HTML 5开发RPG游戏之一(地图人物实现)
  2. HTML 5开发RPG游戏之二(跑起来吧英雄)
  3. HTML 5开发RPG游戏之四(游戏脚本化)
  4. 开发HTML5跨平台游戏相关经验
  5. HTML 5开发的优秀网页游戏

 

责任编辑:张伟 来源: HTML5中国的博客
相关推荐

2012-05-15 13:57:41

HTML5

2012-05-15 13:10:57

HTML5

2012-05-15 13:29:20

HTML5

2012-09-17 09:32:16

JavaScriptJSHTML5

2012-05-15 10:35:35

HTML5

2012-01-06 14:10:13

HTML 5

2013-05-20 17:07:26

2015-07-08 16:38:10

Cocos游戏引擎

2012-05-30 13:17:46

HTML5

2012-03-06 10:56:32

HTML 5

2012-05-09 09:41:58

HTML5

2013-06-21 13:33:46

HTML 5游戏

2012-05-10 09:45:14

HTML5

2014-12-30 17:13:51

HTML5

2011-12-21 09:38:31

HTML 5

2012-11-07 09:43:58

IBMdw

2013-01-04 11:40:54

2013-06-26 10:14:40

2012-06-06 14:46:52

HTML5

2014-11-12 16:00:12

火舞游戏
点赞
收藏

51CTO技术栈公众号