html5游戏开发-零基础开发RPG游戏-开源讲座(三)-卷轴&对话实现 ... ...
了解上两篇的内容请点击:
html5游戏开发-零基础开发RPG游戏-开源讲座(一)
http://www.html5cn.org/article-1737-1.html
html5游戏开发-零基础开发RPG游戏-开源讲座(二)-跑起来吧英雄
http://www.html5cn.org/article-1738-1.html
前两篇,RPG的开发已经实现了添加地图和添加游戏人物,本篇来实现地图的卷轴滚动和人物对话的实现,效果如下
本次开发,更新了一下库件至1.3,请点击下面的链接,下载库件1.3版以上版本
http://code.google.com/p/legendforhtml5programming/downloads/list
地图的滚动
关于地图的滚动原理,可以参照下图
按照上图说明,实现地图滚动,只需要先把即将出现的地图(图中黄色部分)画上,然后滚动地图,待地图滚动完毕之后,将屏幕之外的部分(图中绿色部分)移除
首先要添加一个变量来控制地图是否滚动
- //地图滚动
- 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
- if(480 - mapLayer.x >= map[0].length*STEP)break;
- addMap(1,0);
- mapmove = true;
- break;
- case DOWN:
- if(self.y
- 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
- if(imageArray == null){
- //地图图片数据
- bitmapdata = new LBitmapData(imglist["map"]);
- //将地图图片拆分,得到拆分后的各个小图片的坐标数组
- imageArray = LGlobal.divideCoordinate(bitmapdata.image.width,bitmapdata.image.height,10,10);
- }
- mapLayer.removeAllChild();
- //在地图层上,画出15*10的小图片
- for(i=my;i
- for(j=mx;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
- bitmap = mapLayer.childList[i];
- if(bitmap.x + mapLayer.x = 480 ||
- bitmap.y + mapLayer.y = 288){
- mapLayer.removeChild(bitmap);
- i--;
- }
- }
- }
看一下效果如下
人物的对话
对话的实现,在点击控制按钮的方形按钮时添加,所以,先在鼠标抬起的时候,判断是否点击了方形按钮
- function onup(event){
- isKeyDown = false;
- if(event.offsetX >= ctrlLayer.x + 280 && event.offsetX
- if(event.offsetY >= ctrlLayer.y+40 && event.offsetY
- //对话
- 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
- //得到对话内容
- 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://fsanguo.comoj.com/html5/rpg3/index.html
之前其他地方也稍微做了修改,具体修改请看源代码,此次更新源代码,下载地址如下
http://legend-demo.googlecode.com/files/rpg3.zip

핫 AI 도구

Undresser.AI Undress
사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover
사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool
무료로 이미지를 벗다

Clothoff.io
AI 옷 제거제

AI Hentai Generator
AI Hentai를 무료로 생성하십시오.

인기 기사

뜨거운 도구

메모장++7.3.1
사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전
중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기
강력한 PHP 통합 개발 환경

드림위버 CS6
시각적 웹 개발 도구

SublimeText3 Mac 버전
신 수준의 코드 편집 소프트웨어(SublimeText3)

뜨거운 주제











이 기사에서는 Viewport Meta 태그를 사용하여 모바일 장치의 페이지 스케일링을 제어하여 폭과 최적의 응답 성 및 성능을위한 초기 스케일과 같은 설정에 중점을 둡니다. character count : 159

이 기사는 JavaScript를 사용하여 대화식 HTML5 게임을 만드는 자세한 내용입니다. 게임 디자인, HTML 구조, CSS 스타일, JavaScript 로직 (이벤트 처리 및 애니메이션 포함) 및 오디오 통합을 다룹니다. 필수 JavaScript 라이브러리 (Phaser, PI

이 기사는 & lt; audio & gt를 사용하여 HTML5에 오디오를 포함시키는 방법을 설명합니다. 형식 선택에 대한 모범 사례 (MP3, OGG Vorbis), 파일 최적화 및 재생에 대한 JavaScript 컨트롤을 포함한 요소. 다중 오디오를 사용하는 것을 강조합니다

이 기사는 지리적 위치 API를 사용하여 사용자 위치 개인 정보 및 권한 관리, 권한 요청, 데이터 보안 보장 및 개인 정보 보호법 준수에 대한 모범 사례를 강조하는 것에 대해 설명합니다.

이 기사에서는 HTML5 양식을 작성하고 검증하는 방법을 설명합니다. 그것은 & lt; form & gt; 요소, 입력 유형 (텍스트, 이메일, 번호 등) 및 속성 (필수, 패턴, 최소, 최대). HTML5의 장점은 오래된 방법에 비해 형성됩니다

이 기사에서는 HTML5 페이지 가시성 API를 사용하여 페이지 가시성을 감지하고 사용자 경험을 향상 시키며 리소스 사용량을 최적화하는 것에 대해 설명합니다. 주요 측면에는 미디어 일시 정지, CPU 부하 감소 및 가시성 변경에 기반한 분석 관리가 포함됩니다.

이 기사는 HTML5 드래그 앤 드롭 API를 사용하여 대화식 사용자 인터페이스를 생성하고 요소를 드래그 가능하게 만들고 주요 이벤트를 처리하며 사용자 정의 피드백으로 사용자 경험을 향상시키는 방법을 자세히 설명합니다. 또한 일반적인 함정에 대해 설명합니다

이 기사에서는 실시간, 양방향 클라이언트 서버 커뮤니케이션을위한 HTML5 WebSockets API를 설명합니다. 클라이언트 측 (JavaScript) 및 서버 측 (Python/Flask) 구현에 대해 자세히 설명하여 확장 성, 상태 관리,
