前两篇,RPG的开发已经实现了添加地图和添加游戏人物,本篇来实现地图的卷轴滚动和人物对话的实现,效果如下
地图的滚动
关于地图的滚动原理,可以参照下图
按照上图说明,实现地图滚动,只需要先把即将出现的地图(图中黄色部分)画上,然后滚动地图,待地图滚动完毕之后,将屏幕之外的部分(图中绿色部分)移除
首先要添加一个变量来控制地图是否滚动
//地图滚动 var mapmove = false;
然后,在人物移动的时候,判断地图是否需要滚动
/** * 地图是否滚动 **/ Character.prototype.checkMap = function (dir){ var self = this; mapmove = false; //如果不是英雄,则地图不需要滚动 if(!self.isHero)return; switch (dir){ case UP: if(self.y + charaLayer.y> STEP)break; if(mapLayer.y >= 0)break; addMap(0,-1); mapmove = true; break; case LEFT: if(self.x + charaLayer.x > STEP)break; if(mapLayer.x >= 0)break; addMap(-1,0); mapmove = true; break; case RIGHT: if(self.x < 480 - 2*STEP)break; if(480 - mapLayer.x >= map[0].length*STEP)break; addMap(1,0); mapmove = true; break; case DOWN: if(self.y < 288 - 2*STEP)break; if(288 - mapLayer.y >= map.length*STEP)break; addMap(0,1); mapmove = true; break; } };
在移动过程中,判断地图是否处于滚动状态,如果地图处于滚动,则滚动地图,否则移动人物
/** * 开始移动 **/ Character.prototype.onmove = function (){ var self = this; //设定一个移动步长中的移动次数 var ml_cnt = 4; //计算一次移动的长度 var ml = STEP/ml_cnt; //根据移动方向,开始移动 switch (self.direction){ case UP: if(mapmove){ mapLayer.y += ml; charaLayer.y += ml; } self.y -= ml; break; case LEFT: if(mapmove){ mapLayer.x += ml; charaLayer.x += ml; } self.x -= ml; break; case RIGHT: if(mapmove){ mapLayer.x -= ml; charaLayer.x -= ml; } self.x += ml; break; case DOWN: if(mapmove){ mapLayer.y -= ml; charaLayer.y -= ml; } self.y += ml; break; } self.moveIndex++; //当移动次数等于设定的次数,开始判断是否继续移动 if(self.moveIndex >= ml_cnt){ //一个地图步长移动完成后,如果地图处于滚动状态,则移除多余地图块 if(mapmove)delMap(); self.moveIndex = 0; //如果已经松开移动键,或者前方为障碍物,则停止移动,否则继续移动 if(!isKeyDown || !self.checkRoad()){ self.move = false; return; }else if(self.direction != self.direction_next){ self.direction = self.direction_next; self.anime.setAction(self.direction); } //地图是否滚动 self.checkMap(self.direction); } };
最后,将地图的数组和地形扩大为大于屏幕大小
//地图图片数组 var map = [ [18,18,18,18,18,18,18,18,18,18,18,18,55,55,18,18,18], [18,18,18,17,17,17,17,17,17,17,17,17,55,55,17,17,18], [18,18,17,17,17,17,18,18,17,17,17,17,55,55,17,17,18], [18,17,17,17,18,18,18,18,18,17,17,55,55,17,17,17,18], [18,17,17,18,22,23,23,23,24,18,17,55,55,17,17,17,18], [18,17,17,18,25,28,26,79,27,18,55,55,17,17,17,17,18], [18,17,17,17,17,10,11,12,18,18,55,55,17,17,17,17,18], [18,18,17,17,10,16,16,16,11,55,55,17,17,17,17,17,18], [18,18,17,17,77,16,16,16,16,21,21,17,17,17,17,17,18], [18,18,17,17,77,16,16,16,16,55,55,17,17,17,17,17,18], [18,18,18,18,18,18,18,18,18,55,55,18,18,18,18,18,18] ]; //地图地形数组 var mapdata = [ [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1], [1,1,1,0,0,0,0,0,0,0,0,0,1,1,0,0,1], [1,1,0,0,0,0,1,1,0,0,0,0,1,1,0,0,1], [1,0,0,0,1,1,1,1,1,0,0,1,1,0,0,0,1], [1,0,0,1,1,1,1,1,1,1,0,1,1,0,0,0,1], [1,0,0,1,1,1,0,1,1,1,1,1,0,0,0,0,1], [1,0,0,0,0,0,0,0,1,1,1,1,0,0,0,0,1], [1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1], [1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1], [1,1,0,0,0,0,0,0,0,1,1,0,0,0,0,0,1], [1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1] ];
为了实现地图滚动,修改添加地图的方法,根据参数来实现添加上面图片的黄色地图部分
//添加地图 function addMap(cx,cy){ var i,j,index,indexX,indexY; var bitmapdata,bitmap; var mapX = mapLayer.x / STEP; var mapY = mapLayer.y / STEP; var mx = cx<0?-1:0,my = cy<0?-1:0; if(imageArray == null){ //地图图片数据 bitmapdata = new LBitmapData(imglist["map"]); //将地图图片拆分,得到拆分后的各个小图片的坐标数组 imageArray = LGlobal.pideCoordinate(bitmapdata.image.width,bitmapdata.image.height,10,10); } mapLayer.removeAllChild(); //在地图层上,画出15*10的小图片 for(i=my;i<9 +Math.abs(cy) && i-mapY < map.length;i++){ for(j=mx;j<15 +Math.abs(cx)&& j-mapX < map[0].length;j++){ //从地图数组中得到相应位置的图片坐标 index = map[i-mapY][j-mapX]; //小图片的竖坐标 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*STEP - mapLayer.x; bitmap.y = i*STEP - mapLayer.y; //将小图片显示到地图层 mapLayer.addChild(bitmap); } } } //移除多余地图块 function delMap(){ var bitmap,i; for(i=0;i<mapLayer.childList.length;i++){ bitmap = mapLayer.childList[i]; if(bitmap.x + mapLayer.x < 0 || bitmap.x + mapLayer.x >= 480 || bitmap.y + mapLayer.y < 0 || bitmap.y + mapLayer.y >= 288){ mapLayer.removeChild(bitmap); i--; } } }
看一下效果如下
人物的对话
对话的实现,在点击控制按钮的方形按钮时添加,所以,先在鼠标抬起的时候,判断是否点击了方形按钮
function onup(event){ isKeyDown = false; if(event.offsetX >= ctrlLayer.x + 280 && event.offsetX <= ctrlLayer.x+330){ if(event.offsetY >= ctrlLayer.y+40 && event.offsetY <= ctrlLayer.y+100){ //对话 addTalk(); } } }
在完善addTalk()方法的时候,首先准备好对话的内容
var talkScriptList = { "talk1":new Array( {img:"m",name:"鸣人",msg:"我是木叶村的鸣人,你是谁?"}, {img:"n",name:"黑衣忍者甲",msg:"你就是鸣人?九尾还在你身体里吗?"} ), "talk2":new Array( {img:"n",name:"黑衣忍者乙",msg:"鸣人,听说忍者大战就要开始了。"}, {img:"m",name:"鸣人",msg:"真的吗?一定要想想办法啊。"} ) };
talk1,talk2中talk后面的数字,代表人物的编号,其中每个对话单位的img为人物的头像,name为人物的名称,msg为对话的内容
添加对话时的做法是,当点击方形按钮后,判断小鸣人前方是否有人,如果有人,则将这个人物的编号取出来,再从上面的数组中获取相应的对话内容,然后,将相应的内容显示到游戏屏幕上,具体实现代码如下
//对话内容 var talkScript; var talkScriptList = { "talk1":new Array( {img:"m",name:"鸣人",msg:"我是木叶村的鸣人,你是谁?"}, {img:"n",name:"黑衣忍者甲",msg:"你就是鸣人?九尾还在你身体里吗?"} ), "talk2":new Array( {img:"n",name:"黑衣忍者乙",msg:"鸣人,听说忍者大战就要开始了。"}, {img:"m",name:"鸣人",msg:"真的吗?一定要想想办法啊。"} ) }; //对话序号 var talkIndex = 0; //对话中 var talking = false; /** * 添加对话 * */ function addTalk(){ //如果对话内容为空,则开始判断是否可以对话 if(talkScript == null){ var key,tx = player.x,ty = player.y; switch (player.direction){ case UP: ty -= STEP; break; case LEFT: tx -= STEP; break; case RIGHT: tx += STEP; break; case DOWN: ty += STEP; break; } for(key in charaLayer.childList){ //判断前面又没有npc,有则开始对话 if(charaLayer.childList[key].x == tx && charaLayer.childList[key].y == ty){ if(talkScriptList["talk"+charaLayer.childList[key].index]){ talkScript = talkScriptList["talk"+charaLayer.childList[key].index]; talkIndex = 0; } } } //如果前方没有npc,则返回 if(talkScript == null)return; } //将对话层清空 talkLayer.removeAllChild(); //当对话开始,且按照顺序进行对话 if(talkIndex < talkScript.length){ //得到对话内容 var talkObject = talkScript[talkIndex]; //对话背景 bitmapdata = new LBitmapData(imglist["talk"]); bitmap = new LBitmap(bitmapdata); bitmap.width = 330; bitmap.height = 70; bitmap.x = 100; bitmap.y = 20; bitmap.alpha = 0.7; talkLayer.addChild(bitmap); //对话头像 bitmapdata = new LBitmapData(imglist[talkObject.img]); bitmap = new LBitmap(bitmapdata); bitmap.x = 0; bitmap.y = 0; talkLayer.addChild(bitmap); //对话人物名称 var name = new LTextField(); name.x = 110; name.y = 30; name.size = "14"; name.color = "#FFFFFF"; name.text = "[" + talkObject.name + "]"; talkLayer.addChild(name); //对话内容 var msg = new LTextField(); msg.x = 110; msg.y = 55; msg.color = "#FFFFFF"; msg.text = talkObject.msg; talkLayer.addChild(msg); //对话内容逐字显示 msg.wind(); talkLayer.x = 20; talkLayer.y = 50; talkIndex++; }else{ //对话结束 talkScript = null; } }
效果看下图
游戏演示地址
http://lufylegend.com/demo/rpg/index.html
lufylegend.js引擎包内包含这个demo,请直接下载lufylegend.js引擎,查看引擎包内源码
lufylegend.js引擎下载地址
http://lufylegend.com/lufylegend
以上就是html5游戏开发-零基础开发RPG游戏-开源讲座(三)-卷轴&对话实现 的内容,更多相关内容请关注PHP中文网(www.php.cn)!

H5是HTML5,是HTML的第五个版本。HTML5提升了网页的表现力和交互性,引入了语义化标签、多媒体支持、离线存储和Canvas绘图等新特性,推动了Web技术的发展。

无障碍访问和网络标准遵循对网站至关重要。1)无障碍访问确保所有用户都能平等访问网站,2)网络标准遵循提高网站的可访问性和一致性,3)实现无障碍访问需使用语义化HTML、键盘导航、颜色对比度和替代文本,4)遵循这些原则不仅是道德和法律要求,还能扩大用户群体。

HTML中的H5标签是第五级标题,用于标记较小的标题或子标题。1)H5标签帮助细化内容层次,提升可读性和SEO。2)结合CSS可定制样式,增强视觉效果。3)合理使用H5标签,避免滥用,确保内容结构逻辑性。

HTML5构建网站的方法包括:1.使用语义化标签定义网页结构,如、、等;2.嵌入多媒体内容,使用和标签;3.应用表单验证和本地存储等高级功能。通过这些步骤,你可以创建一个结构清晰、功能丰富的现代网页。

通过合理的H5代码结构可以让页面在众多内容中脱颖而出。1)使用语义化标签如、、等组织内容,使结构清晰。2)通过CSS布局如Flexbox或Grid控制页面在不同设备上的呈现效果。3)实现响应式设计,确保页面在不同屏幕尺寸上自适应。

HTML5(H5)与旧版本HTML的主要区别包括:1)H5引入了语义化标签,2)支持多媒体内容,3)提供离线存储功能。H5通过新标签和API增强了网页的功能和表现力,如和标签,提高了用户体验和SEO效果,但需注意兼容性问题。

H5和HTML5的区别在于:1)HTML5是网页标准,定义结构和内容;2)H5是基于HTML5的移动网页应用,适用于快速开发和营销。

HTML5的核心特性包括语义化标签、多媒体支持、表单增强和离线存储与本地存储。1.语义化标签如、等提高了代码可读性和SEO效果。2.多媒体支持通过和标签简化了嵌入媒体内容的过程。3.表单增强引入了新的输入类型和验证属性,简化了表单开发。4.离线存储和本地存储通过ApplicationCache和localStorage等提高了网页性能和用户体验。


热AI工具

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

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

Undress AI Tool
免费脱衣服图片

Clothoff.io
AI脱衣机

Video Face Swap
使用我们完全免费的人工智能换脸工具轻松在任何视频中换脸!

热门文章

热工具

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

Dreamweaver Mac版
视觉化网页开发工具

螳螂BT
Mantis是一个易于部署的基于Web的缺陷跟踪工具,用于帮助产品缺陷跟踪。它需要PHP、MySQL和一个Web服务器。请查看我们的演示和托管服务。

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

SublimeText3 英文版
推荐:为Win版本,支持代码提示!