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

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

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

以下图html5



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

java

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


准备工做数组

一,库件下载ide

本游戏开发,须要用到开源库件:lufylegend,下载地址为http://lufylegend.com/lufylegend函数


库件的开发过程请看这里动画

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

二,库件配置

首先创建一个文件夹rpg(你也能够起其余的名字)

而后将下载的库件解压,解压后将legend文件夹放到与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>
<!-- 引入LegendForHtml5Programming库件 -->
<script type="text/javascript" src="../legend/legend.js"></script> 
<script type="text/javascript" src="./js/Main.js"></script> 
</body></html>

固然,你也能够将legend文件夹放到其余地方,可是你须要修改legend文件夹下的legend.js文件中的LEGEND_PATH的值,来配置库件的路径


游戏地图的实现

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

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);  
}
若是想更详细了解的话,看下面的帖子
用仿ActionScript的语法来编写html5——第一篇,显示一张图片
http://blog.csdn.net/lufy_legend/article/details/6753032

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

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



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


接下来,打开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]
];

这些数字分别对应着图中以下位置



而后看下面代码

//添加地图
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(){
}
而后运行游戏

能够获得下面画面




游戏人物的实现

为了更好的实现游戏人物的控制,咱们新建一个游戏人物类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();
};
在legendForHtml5Programming里,有一个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();
}

运行代码,看到了吗

一个会动的鸣人出如今游戏的地图上了


游戏演示

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


lufylegend.js引擎包内包含这个demo,请直接下载lufylegend.js引擎,查看引擎包内源码

lufylegend.js引擎下载地址

http://lufylegend.com/lufylegend


下次,就要添加控制层,实现人物的走动和地图的滚动等,但愿你们多多支持。