html5游戏开发-零基础开发RPG游戏-开源讲座(一)

转载 2011年12月14日 10:01:36
 

因为上一篇雷电的开发中,有朋友反应不太理解,本篇将以零基础的视点,来讲解如何开发一款RPG游戏。

在游戏的世界里,我们可以看到各种地图,各种游戏人物,看到人物在地图上行走,对话等,无论是地图还是人物,其实都是图片的处理与显示,把不同的图片显示到屏幕上,我们就看到不同的游戏界面,要想让这些图片同时显示到界面上,我们就需要处理好层次,让他们来分层显示,我们可以想象,如果游戏人物显示在地图的下层的话,显然会被地图遮挡住。
一款RPG游戏,我简单把它分为地图层,人物层,效果层(一些法术效果等),对话层,控制层(按钮菜单等)。

如下图

我们只要依次将图片画在屏幕上,游戏人物将站在地图上,如果有对话,对话将出现在人物和地图的上面,而按钮等控件会出现在游戏的最外层

下面,我们一步步来实现一个简单的RPG游戏的开发


准备工作

一,库件下载

本游戏开发,需要用到开源库件:LegendForHtml5Programming

请到这里下载最新版的LegendForHtml5Programming,本次开发需要1.2版以上

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

库件的开发过程请看这里

http://blog.csdn.net/lufy_legend/article/details/6844949

二,库件配置

首先建立一个文件夹rpg(你也可以起其他的名字)

然后将下载的库件解压,解压后将legend文件夹放到与rpg文件夹同目录
然后,在rpg文件夹里建一个index.html文件和一个js文件夹,在js文件夹里建一个Main.js文件

最后,在index.html里加入下面的代码

  1. <!DOCTYPE html>  
  2. <html>  
  3. <head>  
  4. <meta charset="UTF-8">  
  5. <title>rpg</title>  
  6. </head>  
  7. <body>  
  8. <div id="mylegend">loading……</div>  
  9. <!-- 引入LegendForHtml5Programming库件 -->  
  10. <script type="text/javascript" src="../legend/legend.js"></script>   
  11. <script type="text/javascript" src="./js/Main.js"></script>   
  12. </body></html>  

当然,你也可以将legend文件夹放到其他地方,但是你需要修改legend文件夹下的legend.js文件中的LEGEND_PATH的值,来配置库件的路径


游戏地图的实现

接下来,我们先来画最底层的地图层,
地图当然就是是由图片来组成的,如何在画面上显示一张图片,我之前已经写过专门的文章,代码如下

  1. var loader;    
  2. function main(){    
  3.     loader = new LLoader();    
  4.     loader.addEventListener(LEvent.COMPLETE,loadBitmapdata);    
  5.     loader.load("map.jpg","bitmapData");    
  6. }    
  7. function loadBitmapdata(event){    
  8.     var bitmapdata = new LBitmapData(loader.content);    
  9.     var bitmap = new LBitmap(bitmapdata);    
  10.     addChild(bitmap);    
  11. }    
如果想更详细了解的话,看下面的帖子
用仿ActionScript的语法来编写html5——第一篇,显示一张图片
http://blog.csdn.net/lufy_legend/article/details/6753032

游戏中的地图可以是一张比较大的图片,即整个图片就是游戏的地图,当人物或者地图移动的时候,改变图片显示的区域范围,从而实现地图的滚动和显示等,这样的话,必须为每个场景准备一张地图。

另外,地图也可以是由许多小的地图块儿来组成,比如,我们熟悉的《吞食天地》,《勇者斗恶龙》等经典小型rpg游戏,这样的地图,我们需要准备一张或几张地图块儿,把这些地图块组合成地图来显示,比如下图

在地图显示的时候,首先把图片切割,然后在根据预先设定好的位置显示到地图层上,这样我们就看到了一张完整的地图了


接下来,打开Main.js

在里面加入

  1. init(50,"mylegend",480,320,main);  
在legendForHtml5Progarmming中,用init这个函数来初始化canvas,上面的代码表示,初始化一个速度为50,名字为mylegend,大小为480*320的游戏界面,初始化完成后调用main(),这个速度值是说每个多少毫秒游戏循环一次,所以这个值设定的越小,游戏运行的速度就越快

因为要调用main方法,所以我们要写一个main方法,main方法里做一些简单的准备工作。

虽说读取图片只需要一个

  1. loader.load("map.jpg","bitmapData");    
但是游戏中往往用到很多张图片,你可以用到哪一张再加载哪一张,也可以一次性全部加载完,然后再开始显示游戏

为了一次性把图片加载完,我的做法是,将需要的图片放到一个数组里,然后设定一个索引,每加载一个图片,让这个索引加1,当这个索引小于数组的长度,则继续加载,直到将数组中的图片全部加载完,然后开始进行下一步的工作

具体实现看下面的代码

  1. //图片path数组   
  2. var imgData = new Array();  
  3. //读取完的图片数组   
  4. var imglist = {};  
  5.   
  6. function main(){  
  7.     //准备读取图片   
  8.     imgData.push({name:"map",path:"./image/map.jpg"});  
  9.     imgData.push({name:"mingren",path:"./image/mingren.png"});  
  10.     imgData.push({name:"e1",path:"./image/e1.png"});  
  11.     imgData.push({name:"e2",path:"./image/e2.png"});  
  12.     //实例化进度条层   
  13.     loadingLayer = new LSprite();  
  14.     loadingLayer.graphics.drawRect(1,"black",[50, 200, 200, 20],true,"#ffffff");  
  15.     addChild(loadingLayer);  
  16.     //开始读取图片   
  17.     loadImage();  
  18. }  
  19. function loadImage(){  
  20.     //图片全部读取完成,开始初始化游戏   
  21.     if(loadIndex >= imgData.length){  
  22.         removeChild(loadingLayer);  
  23.         legendLoadOver();  
  24.         gameInit();  
  25.         return;  
  26.     }  
  27.     //开始读取图片   
  28.     loader = new LLoader();  
  29.     loader.addEventListener(LEvent.COMPLETE,loadComplete);  
  30.     loader.load(imgData[loadIndex].path,"bitmapData");  
  31. }  
  32. function loadComplete(event){  
  33.     //进度条显示   
  34.     loadingLayer.graphics.clear();  
  35.     loadingLayer.graphics.drawRect(1,"black",[50, 200, 200, 20],true,"#ffffff");  
  36.     loadingLayer.graphics.drawRect(1,"black",[50, 203, 200*(loadIndex/imgData.length), 14],true,"#000000");  
  37.     //储存图片数据   
  38.     imglist[imgData[loadIndex].name] = loader.content;  
  39.     //读取下一张图片   
  40.     loadIndex++;  
  41.     loadImage();  
  42. }  
上面的代码不难明白,当图片没有读取完之前,会不断循环loadImage和loadComplete两个方法,当读取完之后,移除进度条,用legendLoadOver告诉游戏已经读取完成,然后调用gameInit方法,进行游戏的初始化工作。

看gameInit方法

  1. function gameInit(event){  
  2.     //游戏层显示初始化   
  3.     layerInit();  
  4.     //添加地图   
  5.     addMap();  
  6.     //添加人物   
  7.     addChara();  
  8. }  
在gameInit方法中,首先进行游戏层的初始化,然后添加游戏地图,然后添加人物
游戏层显示初始化,按照我们一开始所说,我们一次来初始化地图层,人物层,效果层,对话层,控制层

  1. //游戏层显示初始化   
  2. function layerInit(){  
  3.     //游戏底层添加   
  4.     backLayer = new LSprite();  
  5.     addChild(backLayer);  
  6.     //地图层添加   
  7.     mapLayer = new LSprite();  
  8.     backLayer.addChild(mapLayer);  
  9.     //人物层添加   
  10.     charaLayer = new LSprite();  
  11.     backLayer.addChild(charaLayer);  
  12.     //效果层添加   
  13.     effectLayer = new LSprite();  
  14.     backLayer.addChild(effectLayer);  
  15.     //对话层添加   
  16.     talkLayer = new LSprite();  
  17.     backLayer.addChild(talkLayer);  
  18.     //控制层添加   
  19.     ctrlLayer = new LSprite();  
  20.     backLayer.addChild(ctrlLayer);  
  21. }  
有了游戏层次的划分,我们在添加游戏对象的时候,将地图添加到地图层,人物添加到人物层,他们就会依次显示在游戏的界面上

下面开始添加地图

首先我们需要准备好显示地图的数组

  1. //地图图片数组   
  2. var map = [  
  3. [18,18,18,18,18,18,18,18,18,18,18,18,55,55,18],  
  4. [18,18,18,17,17,17,17,17,17,17,17,17,55,55,18],  
  5. [18,18,17,17,17,17,18,18,17,17,17,17,55,55,18],  
  6. [18,17,17,17,18,18,18,18,18,17,17,55,55,17,18],  
  7. [18,17,17,18,22,23,23,23,24,18,17,55,55,17,18],  
  8. [18,17,17,18,25,28,26,79,27,18,55,55,17,17,18],  
  9. [18,17,17,17,17,10,11,12,18,18,55,55,17,17,18],  
  10. [18,18,17,17,10,16,16,16,11,55,55,17,17,17,18],  
  11. [18,18,17,17,77,16,16,16,16,21,21,17,17,17,18],  
  12. [18,18,18,18,18,18,18,18,18,55,55,18,18,18,18]  
  13. ];  
这些数字分别对应着图中如下位置


然后看下面代码

  1. //添加地图   
  2. function addMap(){  
  3.     var i,j,index,indexX,indexY;  
  4.     var bitmapdata,bitmap;  
  5.     //地图图片数据   
  6.     bitmapdata = new LBitmapData(imglist["map"]);  
  7.     //将地图图片拆分,得到拆分后的各个小图片的坐标数组   
  8.     imageArray = LGlobal.divideCoordinate(bitmapdata.image.width,bitmapdata.image.height,10,10);  
  9.   
  10.     //在地图层上,画出15*10的小图片   
  11.     for(i=0;i<10;i++){  
  12.         for(j=0;j<15;j++){  
  13.             //从地图数组中得到相应位置的图片坐标   
  14.             index = map[i][j];  
  15.             //小图片的竖坐标   
  16.             indexY = Math.floor(index /10);  
  17.             //小图片的横坐标   
  18.             indexX = index - indexY*10;  
  19.             //得到小图片   
  20.             bitmapdata = new LBitmapData(imglist["map"],indexX*32,indexY*32,32,32);  
  21.             bitmap = new LBitmap(bitmapdata);  
  22.             //设置小图片的显示位置   
  23.             bitmap.x = j*32;  
  24.             bitmap.y = i*32;  
  25.             //将小图片显示到地图层   
  26.             mapLayer.addChild(bitmap);  
  27.         }  
  28.     }  
  29. }  
这样,我们就把预先设置好的图片显示到了游戏界面上,形成了地图

先把addChara方法加上

  1. //添加人物   
  2. function addChara(){  
  3. }  
然后运行游戏

可以得到下面画面



游戏人物的实现

为了更好的实现游戏人物的控制,我们新建一个游戏人物类Character.js

里面代码如下

  1. function Character(data,row,col,speed){  
  2.     base(this,LSprite,[]);  
  3.     var self = this;  
  4.     //设定人物动作速度   
  5.     self.speed = speed==null?3:speed;  
  6.     self.speedIndex = 0;  
  7.     //设定人物大小   
  8.     data.setProperties(0,0,data.image.width/col,data.image.height/row);  
  9.     //得到人物图片拆分数组   
  10.     var list = LGlobal.divideCoordinate(data.image.width,data.image.height,row,col);  
  11.     //设定人物动画   
  12.     self.anime = new LAnimation(this,data,list);  
  13. };  
  14. Character.prototype.onframe = function (){  
  15.     var self = this;  
  16.     if(self.speedIndex++ < self.speed)return;  
  17.     self.speedIndex = 0;  
  18.     self.anime.onframe();  
  19. };  
在legendForHtml5Programming里,有一个LAnimation类,用来实现图片数组顺序播放,形成动画

使用LAnimation类需要三个参数,一个是显示动画的层,一个是图片,一个是图片的坐标数组

然后,调用LAnimation类的onframe方法,就可以实现动画的播放了

在index.html中引入Character类,然后修改addChara方法,

  1. //添加人物   
  2. function addChara(){  
  3.     bitmapdata = new LBitmapData(imglist["mingren"]);  
  4.     player = new Character(bitmapdata,4,4);  
  5.     player.x = 32*5;  
  6.     player.y = 32*6;  
  7.     charaLayer.addChild(player);  
  8.       
  9. }  
在gameInit的末尾添加循环事件

  1. //添加贞事件,开始游戏循环   
  2.     backLayer.addEventListener(LEvent.ENTER_FRAME,onframe);  
最后,添加onframe方法
  1. /** 
  2.  * 循环 
  3.  * */  
  4. function onframe(){  
  5.     player.onframe();  
  6. }  

运行代码,看到了吗

一个会动的鸣人出现在游戏的地图上了


游戏演示

http://fsanguo.comoj.com/html5/rpg/index.html

最后,附上这次的游戏源代码

http://legend-demo.googlecode.com/files/rpg.zip


下次,就要添加控制层,实现人物的走动和地图的滚动等,希望大家多多支持。

如何定义领域模型(概念模型)

作为OOAD中的第二步,概念模型的识别显得比用例识别更加困难。 为什么要创建领域模型 降低与OO建模之间的表示差异。 领域层软件类的名称要源于领域模型中的名称,以使对象具有源于领...

Unity_2D游戏实例从零讲起(1)——认识游戏引擎与Unity

之前几个同学用Unity4.6做过一个Android跑酷手游,现在一看感觉真是各种混乱,现在打算重新整理一下游戏项目,正好一边修改,一边写写博客,把经验积累下来,如果有时间,之后可能也研究研究UE4吧...

html5游戏开发-零基础开发RPG游戏-开源讲座(四)-游戏脚本化&地图跳转

首先,本篇文章是零基础开发RPG游戏-开源讲座系列文章的第四篇,来实现游戏的脚本化,和利用游戏脚本实现地图场景的切换,离上次更新貌似很长时间了,你在看下面的文字之前,需要先了解前三篇在下啰嗦了些什么东...

html5游戏开发-愤怒的小鸟-开源讲座(一)-跳入弹出的小鸟

http://blog.csdn.net/lufy_legend/article/details/7804165 愤怒的小鸟是一款人气火爆的益智游戏,现在我试着用lufylegend库件和Box2d...

html5游戏开发-愤怒的小鸟-开源讲座(一)-跳入弹出的小鸟

愤怒的小鸟是一款人气火爆的益智游戏,现在我试着用lufylegend库件和Box2dWeb物理引擎来看看在html5中如何制作此类经典的物理游戏。准备工作一首先,你需要下载lufylegend库件1....

html5游戏开发-愤怒的小鸟-开源讲座(二)-跟随小鸟的镜头

上一讲中介绍了如何让小鸟旋转跳上弹弓,以及利用外部力使小鸟弹飞出去,但是如果不做任何处理的话,小鸟就这么直冲冲的飞出屏幕了,本次我们就要让镜头时刻跟随小鸟来移动。下面是上一讲的连接,没有看过上一讲的朋...

html5游戏开发-愤怒的小鸟-开源讲座(一)-跳入弹出的小鸟

转载自: http://blog.csdn.net/lufy_legend/article/details/7765599   目前IE浏览器还不支持HTML5,但可以用火狐浏览器测试。   ...

html5游戏开发-愤怒的小鸟-开源讲座(三)-碰撞产生的冲力

在前面已经实现了利用外力将小鸟弹飞出去,并且实现了镜头的跟随。本次来研究一下小鸟与其他物体之间发生碰撞时的冲力,以及由碰撞而使物体发生变形,进而消失,下面是前两讲的链接,看本篇教程之前请朋友们最好先了...

[html5游戏开发]数独游戏-完整算法-开源讲座

开言:本次讲一下数独游戏的开发,数独游戏是一个填数字的游戏,在一个9x9的方格内,这个9x9的大格子又可以分为9个3x3的小的九宫格,在这些格子内填写上1至9的数字,使得每一行,每一列,并且每个小的九...

【HTML5游戏开发小技巧】RPG情景对话中,令文本逐字输出

以前用javascript实现过令文本逐字输出的效果,今天我来用html5中的canvas实现一下。canvas里的内容可不像那样好操作,首先,你需要懂得一些html5的API才能操作canvas,而...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:html5游戏开发-零基础开发RPG游戏-开源讲座(一)
举报原因:
原因补充:

(最多只允许输入30个字)