html5游戏开发-零基础开发RPG游戏-开源讲座(一)
在游戏的世界里,我们可以看到各种地图,各种游戏人物,看到人物在地图上行走,对话等,无论是地图还是人物,其实都是图片的处理与显示,把不同的图片显示到屏幕上,我们就看到不同的游戏界面,要想让这些图片同时显示到界面上,我们就需要处理好层次,让他们来分层显示,我们可以想象,如果游戏人物显示在地图的下层的话,显然会被地图遮挡住。
一款RPG游戏,我简单把它分为地图层,人物层,效果层(一些法术效果等),对话层,控制层(按钮菜单等)。
如下图
我们只要依次将图片画在屏幕上,游戏人物将站在地图上,如果有对话,对话将出现在人物和地图的上面,而按钮等控件会出现在游戏的最外层
下面,我们一步步来实现一个简单的RPG游戏的开发
准备工作
一,库件下载
本游戏开发,需要用到开源库件:LegendForHtml5Programming
请到这里下载最新版的LegendForHtml5Programming,本次开发需要1.2版以上
http://code.google.com/p/legendforhtml5programming/downloads/list
库件的开发过程请看这里
http://bbs.html5cn.org/thread-2712-1-1.html
二,库件配置
首先建立一个文件夹rpg(你也可以起其他的名字)
然后将下载的库件解压,解压后将legend文件夹放到与rpg文件夹同目录
然后,在rpg文件夹里建一个index.html文件和一个js文件夹,在js文件夹里建一个Main.js文件
最后,在index.html里加入下面的代码
-
-
-
-
-
rpg
-
-
-
loading……
-
-
-
当然,你也可以将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://bbs.html5cn.org/thread-2700-1-1.html
游戏中的地图可以是一张比较大的图片,即整个图片就是游戏的地图,当人物或者地图移动的时候,改变图片显示的区域范围,从而实现地图的滚动和显示等,这样的话,必须为每个场景准备一张地图。
另外,地图也可以是由许多小的地图块儿来组成,比如,我们熟悉的《吞食天地》,《勇者斗恶龙》等经典小型rpg游戏,这样的地图,我们需要准备一张或几张地图块儿,把这些地图块组合成地图来显示,比如下图
在地图显示的时候,首先把图片切割,然后在根据预先设定好的位置显示到地图层上,这样我们就看到了一张完整的地图了
接下来,打开Main.js
在里面加入
- init(50,"mylegend",480,320,main);
在legendForHtml5Progarmming中,用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);
- legendLoadOver();
- 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
- for(j=0;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.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://fsanguo.comoj.com/html5/rpg/index.html
最后,附上这次的游戏源代码
http://legend-demo.googlecode.com/files/rpg.zip

热AI工具

Undresser.AI Undress
人工智能驱动的应用程序,用于创建逼真的裸体照片

AI Clothes Remover
用于从照片中去除衣服的在线人工智能工具。

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

AI Hentai Generator
免费生成ai无尽的。

热门文章

热工具

记事本++7.3.1
好用且免费的代码编辑器

SublimeText3汉化版
中文版,非常好用

禅工作室 13.0.1
功能强大的PHP集成开发环境

Dreamweaver CS6
视觉化网页开发工具

SublimeText3 Mac版
神级代码编辑软件(SublimeText3)

uniapp如何实现小程序和H5的快速转换,需要具体代码示例近年来,随着移动互联网的发展和智能手机的普及,小程序和H5成为了不可或缺的应用形式。而uniapp作为一个跨平台的开发框架,可以在一套代码的基础上,快速实现小程序和H5的转换,大大提高了开发效率。本文将介绍uniapp如何实现小程序和H5的快速转换,并给出具体的代码示例。一、uniapp简介unia

win1121h2和22h2两个版本相比较的话还是后者22h2更加稳定一点,22h2的功能也是更加多一点的,相较于之前的21h2,很多功能都得到的提升一起来看看吧。win1121h2和22h2哪个稳定:答:22h2更加稳定win1121h2和22h2两者相比较的话22h2更加稳定一些。22h2增加了很多的功能,而且21h2的问题也在22h2中得到了改善。22h2更新功能:开始菜单中的应用程序文件夹。开始菜单中可调整的固定区域。在任务栏上拖放。焦点辅助与通知中心实现整合。新的“聚光灯”墙纸功能。新

适用场景:1、项目规模不大2、用户量不是很大、并发要求不强3、无专门运维力量4、精致的团队规模对于一些常规的项目,或者企业职责分工不是非常明确的单位来说。往往一个系统从需求到设计,开发,测试到最终上线,运维。往往80%的任务由开发团队来完成。由此,开发人员除了要实现系统的功能,还要为客户进行问题咨询答疑以及生产问题解决。试想,一个应用上线后,没有任何监控措施。跟开着一辆没有任何仪表盘的汽车一样,这样上路,任何人都没有安全感。如何在极简和追求效率上做平衡是一件特别值得思考的事情。一、Springb

如何使用Flask-Admin实现后台管理界面背景介绍:随着网站和应用程序的发展,后台管理界面越来越重要。在开发过程中,我们经常需要一个方便快捷的后台管理界面来管理数据、用户和其他重要信息。Flask-Admin是一个功能强大且易于使用的Flask扩展,可以帮助我们快速实现后台管理界面。Flask-Admin是基于Flask和SQLAlchemy的一个开源项

您需要admin提供的权限才能对此文件进行更改解决方法:1、在登录界面选择管理员账户并输入密码后,就可以顺利对文件进行修改了;2、可以通过右键点击文件选择“以管理员身份运行”的方式解决;3、修改文件权限,右键点击文件,选择“属性”,点击“安全”选项卡,然后点击“编辑”按钮,选择自己的用户名,然后勾选“完全控制”选项;4、利用命令提示符解决问题;5、设置UA权限。

Windows11系统中23h2版本和22h2版本分别先后于2023年和2022年发布,一般来说,系统的更新是越来越好,小编也认为23h2的版本比22h2的版本要更好一些。win1123h2和22h2哪个更好答:win1123h2更好。据介绍,win1123h2是22h2到下一个版本的累积的版本更新,而且它们都是相同的平台。这也就意味着这两个版本之间是没有任何兼容性问题的出现的,建议大家及时更新一下。win1123h2版本给我们带来了许多实用的功能,比如说任务栏窗口应用的永不合并的模式。还有更加

Windows101909目前被认为是最为稳定可靠的版本之一,然而令人感到遗憾的是,该版本的服务支持已于近期结束。而21H2则是一个比较稳定的版本,其实从实际情况来看,二者都是很不错的选择。win101909和21h2哪个好答:1909更稳定,21h2则会更安全。在目前的环境中,1909仍然被普遍认为是最为稳定可靠的版本之一。不过Win101909版本已于2021年5月11日正式停止服务WindowsServer21h2则致力于为广大用户提供更多专业化的IT功能支持。1、经过众多用户的实际测试反

大家最近都想要更新Win11的23H2版本,但是一小部分的用户至今还没有收到更新推送的消息,可能是后台更新进度中的某个进程卡住了,过段时间就好了。Win11更新获取不到23H2怎么办方法一:耐心等待如果用户查看电脑的更新升级情况,发现它卡住了,我们可以等待一段时间,系统就会继续更新的。方法二:清除更新的缓存如果用户之前更新过系统,而且未清除过更细腻的缓存就会影响23h2的正常更新,可以手动清理一下。方法三:使用镜像安装推荐大家到微软的官方网站去下载win1123h2的镜像文件,然后执行更新该文件
