话说好久没有更新博客了,其实这段时间主要是工作忙,没时间。那又是什么刺激了我呢,为什么又有时间了呢?原因有两个,
第一个,前两天看到一款战棋网游《三国志を抱く》,这款游戏和我在家偷摸儿设想的游戏竟然出奇的相同,原来我一直想要做的事儿,在我还在抱怨没有时间的时候,已经被其他人做了,这着实让人感慨,也极其让人不爽。这也让我觉得,我再不做点儿什么的话,自己可能会遇到更不爽的事儿。
有句话说的好,时间就像海绵里的水,挤一挤总是有的,当然时间也像??,好了,当我没说。于是我从犄角旮旯里挤出来了点儿(除了从睡觉的时间挤还能从哪里挤啊...),跟各位在这里侃一侃大山。
第二个,就是引擎1.8.5发布了,下周的某天会接着发布1.8.6,正好宣传一下。
什么?你说什么?你说原因不只这两个?拉票?
靠,你认为我有那么俗吗?也太小瞧我了吧,我在这里郑重声明,你猜的没错,这就是一个拉票贴。
投票地址如下,请用您帮下忙在按钮上狠狠的戳一下
http://vote.blog.csdn.net/blogstaritem/blogstar2013/lufy_Legend
终于啰嗦完了,下面开始干正事儿。
由于战棋脚本部分写的比较早,用的是lufylegend1.7.7版,很多新功能,比如自定义事件,mvc框架等都还没有添加,所以打算抽时间把战棋部分重构一下。
在重构这段时间,我就先跳过战棋部分,直接从下一个比较大的模块,RPG模块开始写了。
我之前也写过一个短篇系列《零基础开发RPG游戏开源讲座》,介绍的也比较简单,这次我会更深入也更具体的介绍一下RPG游戏的开发过程。
游戏嘛,首先得有画面吧,所以本篇还是先来研究一下地图到底怎么做。
一张地图,可能是由一张大图组成的,如下

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



本次来研究一下如何开发一个两种情况都可用的地图系统。
原理很简单,将大地图也看作小地图块儿就可以了,比如设定一个数组,里面装有一些小地图块儿。
[
[地图块1,地图块2,地图块3],
[地图块4,地图块5,地图块6]
]
一张大地图的时候,就是一种特殊情况,如下
[
[地图块1]
]
当然,一张地图,不能只有图片,还要有地形。在《零基础开发RPG游戏开源讲座》里,每个小地图块和一个地形坐标是一一对应的,其实这不是必须的,比如上面的几张小图块儿图片
用它们来拼接地图的话,就不需要和地形坐标一一对应了,也就是说图片只是用来显示的,和地形并无关联。
如此,我们就可以设计下面一个地图文件
{
width:1280
,height:720
,data:[
[0,0,0......]
,[0,0,0......]
......
]
,pieceWidth:1280
,pieceHeight:720
,imgs:[
[{img:"map-1",rect:[0,0],path:"map-1.png"},{img:"map-2",rect:[0,0],path:"map2.png"},......]
,[{img:"map-1",rect:[0,0],path:"map-1.png"},{img:"map-2",rect:[0,0],path:"map2.png"},......]
......
]
}
其中,各个变量含义如下
width:地图的有效宽度
height:地图的有效高度
data:地图的地形数组,结合地图的有效宽度和高度,就可以计算出,地形数组的一个单位的大小
pieceWidth:地图块儿的宽度
pieceHeight:地图块儿的高度
imgs:地图块儿数组
有了这个定义,地图层的显示,我们就可以这么写
MapView.prototype.mapLayerInit=function(){
var self = this;
//获取地图定义
var map = self.model.map;
for(var i=0;i<map.imgs.length;i++){
for(var j=0;j<map.imgs[i].length;j++){
var imgObj = map.imgs[i][j];
var bitmap = new LBitmap(new LBitmapData(LMvc.datalist[imgObj.img],imgObj.rect[0],imgObj.rect[1],map.pieceWidth,map.pieceHeight));
bitmap.x = j*map.pieceWidth;
bitmap.y = i*map.pieceHeight;
self.mapLayer.addChild(bitmap);
}
}
//地图点击事件
self.mapLayer.addEventListener(LMouseEvent.MOUSE_UP, self.controller.mapClick);
};
代码解析:
首先获取小地图块儿数组,循环二维数组,将所有小地图块儿添加到地图层的相应的位置上,这样就组成一张完整的地图了。
注:此处当然还可以优化,本次只将实现,优化处理下次会介绍。
地形部分,其实没有必要显示到页面上的,但是为了便于大家理解,我把地形以网格的形势显示到画面上,如下
MapView.prototype.gridLayerInit=function(){
var self = this;
var map = self.model.map;
var grids = map.data;
var stepWidth = map.width/grids[0].length;
var stepHeight = map.height/grids.length;
self.controller.stepWidth = stepWidth;
self.controller.stepHeight = stepHeight;
self.gridLayer.graphics.add(function (){
var c = LGlobal.canvas;
c.beginPath();
c.strokeStyle = "#000000";
for(var i=1;i<grids.length;i++){
c.moveTo(0,stepHeight*i);
c.lineTo(map.width,stepHeight*i);
}
for(var i=1;i<grids[0].length;i++){
c.moveTo(stepWidth*i,0);
c.lineTo(stepWidth*i,map.height);
}
c.stroke();
c.beginPath();
c.fillStyle = "#FF0000";
for(var i=0;i<grids.length;i++){
for(var j=0;j<grids[i].length;j++){
if(grids[i][j] == 0)continue;
c.rect(stepWidth*j+stepWidth*0.25, stepHeight*i+stepHeight*0.25, stepWidth*0.5, stepHeight*0.5);
}
}
c.fill();
});
};
代码解析:
graphics.add函数是在lufylegend.js引擎中使用canvas原生的绘图处理,graphics的相关使用请看官方API文档。
上面代码将地形以网格的形式画到了网格层上,并且当地形不可移动的时候,在网格层上加上了红色的矩形方框。
这两部分的效果如下图

RPG游戏怎么会没有角色上阵呢,下面我利用LAnimationTimeline来创建一个角色类Character,然后用它来新建一个角色添加到地图上。
MapView.prototype.charaLayerInit=function(){
var self = this;
var map = self.model.map;
var grids = map.data;
var stepWidth = map.width/grids[0].length;
var stepHeight = map.height/grids.length;
var chara = new Character(LMvc.datalist["hero"],stepWidth,stepHeight);
chara.setCoordinate(20*stepWidth,8*stepHeight);
self.charaLayer.addChild(chara);
self.hero = chara;
};
代码解析:
Character类待会儿随代码下载。
本次主要介绍地图相关的处理,所以上面只是简单创建了一个角色,后续扩展等后面再详细讲。
加入角色后,效果如下

接着当然要有寻路和移动了,我在《(战棋部分) 战场上的寻路和移动》里面提供了一个A*寻路的类LStarQuery,这里可以直接拿来用了。用法很简单,大家可以到前面的文章里看一下。
在RPG游戏里,人物移动的时候,实际上是地图在移动,就是当人物移动的时候,同时改变地图层坐标,具体实现如下
MapController.prototype.mapMove=function(){
var self = this;
var map = self.model.map;
//根据地图缩放比例,重新计算缩放后的地图大小
var w = map.width*self.view.baseLayer.scaleX;
var h = map.height*self.view.baseLayer.scaleY;
//根据地图缩放比例,重新计算地图的实际显示范围
var showW = LGlobal.width/self.view.baseLayer.scaleX;
var showH = LGlobal.height/self.view.baseLayer.scaleY;
if(w > LGlobal.width){
//移动人物层,保持角色的x始终处在地图中央
self.view.charaLayer.x = showW*0.5 - self.view.hero.x;
if(self.view.charaLayer.x > 0){
self.view.charaLayer.x = 0;
}else if(self.view.charaLayer.x < showW - map.width){
self.view.charaLayer.x = showW - map.width;
}
}else{
self.view.charaLayer.x = 0;
}
if(h > LGlobal.height){
//移动人物层,保持角色的y始终处在地图中央
self.view.charaLayer.y = showH*0.5 - self.view.hero.y;
if(self.view.charaLayer.y > 0){
self.view.charaLayer.y = 0;
}else if(self.view.charaLayer.y < showH - map.height){
self.view.charaLayer.y = showH - map.height;
}
}else{
self.view.charaLayer.y = 0;
}
//保持其他层的坐标和人物层一致
self.view.mapLayer.x = self.view.gridLayer.x = self.view.maskLayer.x = self.view.charaLayer.x;
self.view.mapLayer.y = self.view.gridLayer.y = self.view.maskLayer.y = self.view.charaLayer.y;
};
代码解析:
现在的游戏,手机是主流了,手机画面比较小,所以讲画面放大是很有用的一个功能,而画面放大后,可视范围就缩小了,所以我加入了缩放功能,以方便玩家切换,具体的实现方法大家一会儿下载代码自己看看吧。
虽然还是半成品,最后的效果如下。

只是为了测试功能,所以用的地图不一定合适,地形也是随便设置了几个遮挡点,大家将就这看一看吧。
测试连接:
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://vote.blog.csdn.net/blogstaritem/blogstar2013/lufy_Legend
《游戏脚本的设计与开发》系列文章目录
http://blog.csdn.net/lufy_legend/article/details/8888787
分享到:
相关推荐
“RPG-Maker-MV-Decrypter”是一个专门设计用于解密RPG Maker MV资源文件的工具或库。通过使用这个项目,开发者或玩家可以访问并编辑游戏的原始素材,包括图像、音频、脚本等,从而进行自定义和个性化修改。这可能是...
无论是初学者还是经验丰富的开发者,都能从这个开发包中受益,实现他们的游戏设计理念。在Unity的游戏开发旅程中,RPGKit 3.1.75无疑是一个值得信赖的伙伴,为你的游戏开发之路提供坚实的基础。
本"unity3d RPG开发包"是专为RPG开发者设计的工具集,旨在简化开发流程,提高效率,并提供一系列预设的组件、脚本、资源和功能。 在RPG游戏中,核心要素包括角色系统、战斗系统、剧情推进、物品管理系统、技能树、...
Petschko的RPG-Maker-MV文件解密器 那是什么? 此项目用于解密(和重新加密)RPG-Maker-MV-资源文件,这些文件已通过RPG-Maker的内置加密进行了加密。 该项目主要用于单文件解密。 >。<如果要解密大量文件(或...
- **开发环境**:Visual Studio、Code::Blocks等集成开发环境是开发游戏引擎的常见选择。 - **API与库**:DirectX SDK、OpenGL等图形库提供了强大的图形处理能力;SDL、SFML等库则简化了跨平台游戏开发的工作量。 #...
通过这套资源的学习,初学者可以系统地掌握Unity的基础操作及RPG游戏开发的核心技术,为进一步的游戏开发打下坚实的基础。希望每位学习者都能充分利用这些资源,不断进步,在游戏开发领域取得更多的成就。
《Visual C++角色扮演游戏程序设计》是一本深入探讨如何使用Microsoft的Visual C++开发角色扮演游戏(RPG)的书籍。...在实践中,读者可以尝试修改代码,添加新的功能,从而提升自己的编程技能和游戏设计能力。
3. **工具库层**:提供游戏开发所需的辅助工具,如地图编辑器、脚本解析器、人物对话模块等。 ##### 3.3 游戏引擎的IPO图 IPO图(输入-处理-输出图)直观地展示了游戏引擎的工作流程,从接收玩家输入到处理游戏...
角色扮演游戏引擎的设计涉及多个层面的技术和工具,从底层的图形渲染到高级的游戏逻辑实现,每一个环节都需要精心设计和开发。通过选择合适的开发工具和技术,如Visual C++和DirectX等,开发者可以有效地构建出沉浸...
在RMXP中,地图是游戏的核心组成部分之一。可以通过以下步骤绘制地图: - 在工程左下角的地图文件区域点击右键选择“新建地图”。 - 输入地图名称(如“主角的家”)。 - 设置地图尺寸(最大支持500格×500格)。 -...
- **脚本编写**:使用C#或JavaScript等脚本语言,实现复杂的游戏逻辑和交互设计。 - **UI设计**:通过Unity3D的GUI系统,创建直观易用的用户界面。 - **音频处理**:集成音效和背景音乐,提高游戏的沉浸感。 #### ...
为了尽可能地避免与其他游戏元素或脚本发生冲突,该脚本采用了较为保守的设计方式。例如,在复制事件时,会尽量选择不会与其他事件重叠的位置进行放置。 ### 3. 关键代码解析 #### 3.1 `make_events` 方法 该方法...
RPGLE(RPG IV Enhanced)是一种专为IBM AS/400系列计算机设计的高级编程语言,它继承了RPG(Report Program Generator)语言的基本特性,并在此基础上进行了扩展和优化。RPGLE语言特别适用于开发AS/400平台上的商业...
文档中也提供了一个RPG-CGI程序的示例,该程序演示了如何使用RPG语言编写一个CGI程序。RPG是一种在AS400上常用的编程语言。 4.5 CG_PARTSCGI程序源代码 通过分析源代码,开发者可以掌握如何编写标准的CGI程序,并...
《烧瓶探索》是一款以RPG(角色扮演游戏)为主题的早期作品,正处于开发的初步阶段,被称为Work In Progress(WIP)。...开发过程中涉及的技能包括游戏设计、编程、艺术创作以及音频制作等,体现了游戏开发的综合性。
matlab中微多普勒代码这个Matlab程序读取RPG的FMCW雷达记录的数据。 RPG以二进制格式存储数据。 该程序将其转换为netcdf4格式。 另外,可以对数据进行一些重新处理,包括取消雷达频谱和计算更高的力矩。 该程序最初...