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

话说好久没有更新博客了,其实这段时间主要是工作忙,没时间。那又是什么刺激了我呢,为什么又有时间了呢?原因有两个,

第一个,前两天看到一款战棋网游《三国志を抱く》,这款游戏和我在家偷摸儿设想的游戏竟然出奇的相同,原来我一直想要做的事儿,在我还在抱怨没有时间的时候,已经被其他人做了,这着实让人感慨,也极其让人不爽。这也让我觉得,我再不做点儿什么的话,自己可能会遇到更不爽的事儿。

有句话说的好,时间就像海绵里的水,挤一挤总是有的,当然时间也像??,好了,当我没说。于是我从犄角旮旯里挤出来了点儿(除了从睡觉的时间挤还能从哪里挤啊...),跟各位在这里侃一侃大山。

第二个,就是引擎1.8.5发布了,下周的某天会接着发布1.8.6,正好宣传一下。

终于啰嗦完了,下面开始干正事儿。

由于战棋脚本部分写的比较早,用的是lufylegend1.7.7版,很多新功能,比如自定义事件,mvc框架等都还没有添加,所以打算抽时间把战棋部分重构一下。

在重构这段时间,我就先跳过战棋部分,直接从下一个比较大的模块,RPG模块开始写了。

我之前也写过一个短篇系列《零基础开发RPG游戏开源讲座》,介绍的也比较简单,这次我会更深入也更具体的介绍一下RPG游戏的开发过程。

游戏嘛,首先得有画面吧,所以本篇还是先来研究一下地图到底怎么做。

一张地图,可能是由一张大图组成的,如下

也可能是由一些小图块儿组成,如下

本次来研究一下如何开发一个两种情况都可用的地图系统。

原理很简单,将大地图也看作小地图块儿就可以了,比如设定一个数组,里面装有一些小地图块儿。


[地图块1,地图块2,地图块3],
[地图块4,地图块5,地图块6]

一张大地图的时候,就是一种特殊情况,如下


[地图块1]

当然,一张地图,不能只有图片,还要有地形。在《零基础开发RPG游戏开源讲座》里,每个小地图块和一个地形坐标是一一对应的,其实这不是必须的,比如上面的几张小图块儿图片

用它们来拼接地图的话,就不需要和地形坐标一一对应了,也就是说图片只是用来显示的,和地形并无关联。

如此,我们就可以设计下面一个地图文件

[javascript] view plaincopy
  1. {
  2. width:1280
  3. ,height:720
  4. ,data:[
  5. [0,0,0......]
  6. ,[0,0,0......]
  7. ......
  8. ]
  9. ,pieceWidth:1280
  10. ,pieceHeight:720
  11. ,imgs:[
  12. [{img:"map-1",rect:[0,0],path:"map-1.png"},{img:"map-2",rect:[0,0],path:"map2.png"},......]
  13. ,[{img:"map-1",rect:[0,0],path:"map-1.png"},{img:"map-2",rect:[0,0],path:"map2.png"},......]
  14. ......
  15. ]
  16. }

其中,各个变量含义如下

[javascript] view plaincopy
  1. width:地图的有效宽度
  2. height:地图的有效高度
  3. data:地图的地形数组,结合地图的有效宽度和高度,就可以计算出,地形数组的一个单位的大小
  4. pieceWidth:地图块儿的宽度
  5. pieceHeight:地图块儿的高度
  6. imgs:地图块儿数组

有了这个定义,地图层的显示,我们就可以这么写

[javascript] view plaincopy
  1. MapView.prototype.mapLayerInit=function(){
  2. var self = this;
  3. //获取地图定义
  4. var map = self.model.map;
  5. for(var i=0;i<map.imgs.length;i++){
  6. for(var j=0;j<map.imgs[i].length;j++){
  7. var imgObj = map.imgs[i][j];
  8. var bitmap = new LBitmap(new LBitmapData(LMvc.datalist[imgObj.img],imgObj.rect[0],imgObj.rect[1],map.pieceWidth,map.pieceHeight));
  9. bitmap.x = j*map.pieceWidth;
  10. bitmap.y = i*map.pieceHeight;
  11. self.mapLayer.addChild(bitmap);
  12. }
  13. }
  14. //地图点击事件
  15. self.mapLayer.addEventListener(LMouseEvent.MOUSE_UP, self.controller.mapClick);
  16. };

代码解析:

首先获取小地图块儿数组,循环二维数组,将所有小地图块儿添加到地图层的相应的位置上,这样就组成一张完整的地图了。

注:此处当然还可以优化,本次只将实现,优化处理下次会介绍。

地形部分,其实没有必要显示到页面上的,但是为了便于大家理解,我把地形以网格的形势显示到画面上,如下

[javascript] view plaincopy
  1. MapView.prototype.gridLayerInit=function(){
  2. var self = this;
  3. var map = self.model.map;
  4. var grids = map.data;
  5. var stepWidth = map.width/grids[0].length;
  6. var stepHeight = map.height/grids.length;
  7. self.controller.stepWidth = stepWidth;
  8. self.controller.stepHeight = stepHeight;
  9. self.gridLayer.graphics.add(function (){
  10. var c = LGlobal.canvas;
  11. c.beginPath();
  12. c.strokeStyle = "#000000";
  13. for(var i=1;i<grids.length;i++){
  14. c.moveTo(0,stepHeight*i);
  15. c.lineTo(map.width,stepHeight*i);
  16. }
  17. for(var i=1;i<grids[0].length;i++){
  18. c.moveTo(stepWidth*i,0);
  19. c.lineTo(stepWidth*i,map.height);
  20. }
  21. c.stroke();
  22. c.beginPath();
  23. c.fillStyle = "#FF0000";
  24. for(var i=0;i<grids.length;i++){
  25. for(var j=0;j<grids[i].length;j++){
  26. if(grids[i][j] == 0)continue;
  27. c.rect(stepWidth*j+stepWidth*0.25, stepHeight*i+stepHeight*0.25, stepWidth*0.5, stepHeight*0.5);
  28. }
  29. }
  30. c.fill();
  31. });
  32. };

代码解析:

graphics.add函数是在lufylegend.js引擎中使用canvas原生的绘图处理,graphics的相关使用请看官方API文档。

上面代码将地形以网格的形式画到了网格层上,并且当地形不可移动的时候,在网格层上加上了红色的矩形方框。

这两部分的效果如下图

RPG游戏怎么会没有角色上阵呢,下面我利用LAnimationTimeline来创建一个角色类Character,然后用它来新建一个角色添加到地图上。

[javascript] view plaincopy
  1. MapView.prototype.charaLayerInit=function(){
  2. var self = this;
  3. var map = self.model.map;
  4. var grids = map.data;
  5. var stepWidth = map.width/grids[0].length;
  6. var stepHeight = map.height/grids.length;
  7. var chara = new Character(LMvc.datalist["hero"],stepWidth,stepHeight);
  8. chara.setCoordinate(20*stepWidth,8*stepHeight);
  9. self.charaLayer.addChild(chara);
  10. self.hero = chara;
  11. };

代码解析:

Character类待会儿随代码下载。

本次主要介绍地图相关的处理,所以上面只是简单创建了一个角色,后续扩展等后面再详细讲。

加入角色后,效果如下

接着当然要有寻路和移动了,我在《(战棋部分) 战场上的寻路和移动》里面提供了一个A*寻路的类LStarQuery,这里可以直接拿来用了。用法很简单,大家可以到前面的文章里看一下。

在RPG游戏里,人物移动的时候,实际上是地图在移动,就是当人物移动的时候,同时改变地图层坐标,具体实现如下

[javascript] view plaincopy
  1. MapController.prototype.mapMove=function(){
  2. var self = this;
  3. var map = self.model.map;
  4. //根据地图缩放比例,重新计算缩放后的地图大小
  5. var w = map.width*self.view.baseLayer.scaleX;
  6. var h = map.height*self.view.baseLayer.scaleY;
  7. //根据地图缩放比例,重新计算地图的实际显示范围
  8. var showW = LGlobal.width/self.view.baseLayer.scaleX;
  9. var showH = LGlobal.height/self.view.baseLayer.scaleY;
  10. if(w > LGlobal.width){
  11. //移动人物层,保持角色的x始终处在地图中央
  12. self.view.charaLayer.x  = showW*0.5 - self.view.hero.x;
  13. if(self.view.charaLayer.x > 0){
  14. self.view.charaLayer.x = 0;
  15. }else if(self.view.charaLayer.x < showW - map.width){
  16. self.view.charaLayer.x = showW - map.width;
  17. }
  18. }else{
  19. self.view.charaLayer.x = 0;
  20. }
  21. if(h > LGlobal.height){
  22. //移动人物层,保持角色的y始终处在地图中央
  23. self.view.charaLayer.y  = showH*0.5 - self.view.hero.y;
  24. if(self.view.charaLayer.y > 0){
  25. self.view.charaLayer.y = 0;
  26. }else if(self.view.charaLayer.y < showH - map.height){
  27. self.view.charaLayer.y = showH - map.height;
  28. }
  29. }else{
  30. self.view.charaLayer.y = 0;
  31. }
  32. //保持其他层的坐标和人物层一致
  33. self.view.mapLayer.x = self.view.gridLayer.x = self.view.maskLayer.x = self.view.charaLayer.x;
  34. self.view.mapLayer.y = self.view.gridLayer.y = self.view.maskLayer.y = self.view.charaLayer.y;
  35. };

代码解析:

现在的游戏,手机是主流了,手机画面比较小,所以讲画面放大是很有用的一个功能,而画面放大后,可视范围就缩小了,所以我加入了缩放功能,以方便玩家切换,具体的实现方法大家一会儿下载代码自己看看吧。

虽然还是半成品,最后的效果如下。

只是为了测试功能,所以用的地图不一定合适,地形也是随便设置了几个遮挡点,大家将就这看一看吧。

测试连接:

http://lufylegend.com/demo/test/lsharp/rpg-lshape/index.html

代码下载地址:

http://lufylegend.com/demo/test/lsharp/rpg-lshape/rpg-lshape.zip

关于代码,lufylegend-1.8.5.min.js,lufylegend.ui-0.4.0.min.js,lufylegend.mvc.0.1.0.js等引擎相关文件,请自己下载lufylegend.js引擎获取。

注意,单单就地图功能来说,这也只是一个半成品,比如地图的优化工作没有做,比如人物移动的时候直线速度和斜角速度是不一样的,这些留着下次解决了,为什么要下次?这年头,不分开几次讲,怎么赚回头率啊?欢迎大家继续关注。

《游戏脚本的设计与开发》系列文章目录

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

本章就讲到这里,欢迎继续关注我的博客

转载请注明:转自lufy_legend的博客http://blog.csdn.net/lufy_legend

《游戏脚本的设计与开发》-(RPG部分)3.1 RPG地图到底怎么做?相关推荐

  1. 《游戏脚本的设计与开发》-(RPG部分)3.6 队员列表和人物属性

    注意:本系列教程为长篇连载无底洞,半路杀进来的朋友,如果看不懂的话,请从第一章开始看起,文章目录请点击下面链接. http://blog.csdn.net/lufy_legend/article/de ...

  2. 《游戏脚本的设计与开发》-(RPG部分)3.8 通过脚本来自由控制游戏(一)

    注意:本系列教程为长篇连载无底洞,半路杀进来的朋友,如果看不懂的话,请从第一章开始看起,文章目录请点击下面链接. http://blog.csdn.net/lufy_legend/article/de ...

  3. 《游戏脚本的设计与开发》-(RPG部分)3.4 地图跳转

    注意:本系列教程为长篇连载无底洞,半路杀进来的朋友,如果看不懂的话,请从第一章开始看起,文章目录请点击下面链接. http://blog.csdn.net/lufy_legend/article/de ...

  4. 《游戏脚本的设计与开发》-(RPG部分)3.5 游戏背包和任务系统

    注意:本系列教程为长篇连载无底洞,半路杀进来的朋友,如果看不懂的话,请从第一章开始看起,文章目录请点击下面链接. http://blog.csdn.net/lufy_legend/article/de ...

  5. 《游戏脚本的设计与开发》-目录序

    本系列文章目录 章节 标题 连接 序 游戏脚本简介 http://blog.csdn.net/lufy_legend/article/details/8888787 第一章 基本功能 1.1 读取和解 ...

  6. 《游戏脚本的设计与开发》-第一部分总结 文字脚本的功能扩展和一个游戏测试...

    脚本系列文章写了好几篇了,大家可能都不清楚这些脚本有什么用,游戏中如何能应用到这些东西.当然,目前所介绍的内容还只是个简单的开头,说到做游戏还远远不够.不过,本次就使用前几章所介绍的内容,先来尝试一下 ...

  7. 《游戏脚本的设计与开发》-1.1 读取和解析一个脚本文件

    上一篇<游戏脚本的设计与开发>-序中我介绍了游戏脚本的基本概念和准备工作,本篇来说说具体如何解析一个脚本 所谓解析脚本,就是按照自己定义的语法,将每一个脚本命令还原成不同的代码逻辑进行执行 ...

  8. 《游戏脚本的设计与开发》-第一章总结 文字脚本的功能扩展和一个游戏测试

    脚本系列文章写了好几篇了,大家可能都不清楚这些脚本有什么用,游戏中如何能应用到这些东西.当然,目前所介绍的内容还只是个简单的开头,说到做游戏还远远不够.不过,本次就使用前几章所介绍的内容,先来尝试一下 ...

  9. 《游戏脚本的设计与开发》-1.6 按钮,脚本的暂停和标签

    按钮 按钮在任何程序中都是必不可少的,本次先来看看如何脚本来实现按钮的各种功能.文章中要实现的几个脚本如下. /* 游戏脚本的设计与开发 第六章 */ //添加按钮 Button.add(layer0 ...

最新文章

  1. 英语口语(5月31日)
  2. 安全多方计算(MPC)从入门到精通:JUGO-IDE及SDK
  3. Windows——在当前目录打开 PowerShell 命令窗口
  4. git 克隆远端分支,关联到本地,修改代码并提交到远程分支
  5. C# ref跟out
  6. java中Date与DateFormat的格式输出
  7. ASP.NET Core 2.2 : 十六.扒一扒2.2版更新的新路由方案
  8. https://www.cnblogs.com/jingmoxukong/p/7755643.html
  9. python字典弱引用_如何使用弱引用优化 Python 程序的内存占用?
  10. Mybatis 批量操作总结
  11. 相对开音节java,L314 单音节词读音规则(二)-元音字母发音规则
  12. ASA REST API安装步骤
  13. Java中ElasticSearch的各种查询(普通,模糊,前缀,高亮,聚合,范围)
  14. win10进程太多怎么优化_win10全能优化工具箱
  15. Web端与移动端接入萤石云平台的视频数据
  16. 使用Blinker+ESP8266接入天猫精灵
  17. jsp文件木马代码分析
  18. 城乡规划编制单位资质开通申请
  19. linux三剑客-sed命令的学习笔记
  20. 【毕业设计】深度学习实现行人重识别 - python opencv yolo Reid

热门文章

  1. 牛客练习赛24 B 凤 凰
  2. 电容笔和触控笔有什么区别?实用平板电脑手写电容笔推荐
  3. oracle期间平均成本,小李飞刀系列之Oracle EBS期间平均成本(PAC)--生产成本计算(四)制造费用设置及成本计算...
  4. 微型计算机的特点及其主板构成,第1章 计算机基础知识教案
  5. 京东实战·案例·[项目]
  6. 本地文件搜索工具 Everything 为什么速度这么快?
  7. i.MX RT开发笔记-02 | i.MX RT1062开发环境搭建(MDK芯片包、NXP SDK详解)
  8. 桂林电子科技大学计算机学院钟艳如,桂林电子科技大学考研研究生导师简介-钟艳如...
  9. 什么是黑客、骇客、白客、红客?他们的工作是什么?
  10. android刷机恢复出厂设置吗,安卓手机恢复出厂设置和双清有什么区别?