html5游戏开发-零基础开发RPG游戏-开源讲座(二)-跑起来吧英雄

原创 2011年12月16日 10:25:59

上一篇中,已经详细讲解了,如何添加地图,以及添加了一个游戏人物,现在我们来添加控制事件,让这个小英雄走动起来


了解上一篇内容请看这里

html5游戏开发-零基础开发RPG游戏-开源讲座(一)

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


我们已经给游戏人物建立了一个Character类,

现在先来在类里加入

Character.prototype.changeDir = function (dir){
};
/**
 * 设定人物坐标
 * @param x方向坐标,y方向坐标 
 **/
Character.prototype.setCoordinate = function (sx,sy){
};
/**
 * 获取人物坐标
 **/
Character.prototype.getCoordinate = function (){
};
changeDir 这个方法用来从外部控制人物方向和移动
要控制游戏的人物,首先,我们要由控制事件,当触发这个事件的时候,就来调用相应的方法,做我们想要的做的处理setCoordinate和getCoordinate是设定和得到人物当前的坐标


首先,为了适应智能手机,我们暂时不用键盘事件,而是用点击事件,所以我们先来添加两个控制按钮,在Main.js的gameInit方法的最下方,添加如下代码

//添加控制按钮
	bitmapdata = new LBitmapData(imglist["e1"]);
	bitmap = new LBitmap(bitmapdata);
	bitmap.x = 0;
	bitmap.y = 0;
	ctrlLayer.addChild(bitmap);
	bitmapdata = new LBitmapData(imglist["e2"]);
	bitmap = new LBitmap(bitmapdata);
	bitmap.x = 280;
	bitmap.y = 30;
	ctrlLayer.addChild(bitmap);
	ctrlLayer.x = 40;
	ctrlLayer.y = 180;

运行代码,得到预览如下


在添加控制事件之前,为了实现控制方便,我们先来添加几个变量
//方向变量
var DOWN = 0;
var LEFT = 1;
var RIGHT = 2;
var UP = 3;
var STEP = 32;
//点击状态
var isKeyDown = false;
STEP代表移动步长,因为地图是有32*32的小图片来组成的,所以我们设定人物移动的步长为32

方向变量的0,1,2,3分别对应下面图片中的第1,2,3,4行的方向

之所以添加点击状态,是因为,当我们按下移动按钮没有抬起的时候,人物应该始终处于移动状态,所以用这个变量来区分,我们是否按下或者抬起好了,做好了准备工作,现在就开始添加移动事件

//添加点击控制事件
	backLayer.addEventListener(LMouseEvent.MOUSE_DOWN,ondown);
	backLayer.addEventListener(LMouseEvent.MOUSE_UP,onup);

function ondown(event){
	//根据点击位置,判断移动方向
	if(event.offsetX >= ctrlLayer.x + 40 && event.offsetX <= ctrlLayer.x+80){
		if(event.offsetY >= ctrlLayer.y && event.offsetY <= ctrlLayer.y+40){
			player.changeDir(UP);
		}else if(event.offsetY >= ctrlLayer.y+80 && event.offsetY <= ctrlLayer.y+120){
			player.changeDir(DOWN);
		}
	}else if(event.offsetX >= ctrlLayer.x && event.offsetX <= ctrlLayer.x+40){
		if(event.offsetY >= ctrlLayer.y +40 && event.offsetY <= ctrlLayer.y+80){
			player.changeDir(LEFT);
		}
	}else if(event.offsetX >= ctrlLayer.x+80 && event.offsetX <= ctrlLayer.x+120){
		if(event.offsetY >= ctrlLayer.y +40 && event.offsetY <= ctrlLayer.y+80){
			player.changeDir(RIGHT);
		}
	}
	isKeyDown = true;
}
function onup(event){
	isKeyDown = false;
}

这里需要知道的是,在智能手机里,其实点击事件是TOUCH_START,TOUCH_MOVE,TOUCH_END事件
使用legendForHtml5Programming库件的时候,只需要添加MOUSE_DOWN,MOUSE_MOVE,MOUSE_UP事件,然后库件会自动判断是加载TOUCH事件还是MOUSE事件
在ondown方法中,我们将isKeyDown的状态变为true,表示我们正处于按下状态
然后,根据我们点击的位置,来调用Character类的changeDir方法,并且传入点击的方向

有了控制事件,现在的关键就在于changeDir方法,只要根据传进来的值,来实现移动就可以了
我们试想,如果每次移动一个步长的话,那么人物就会由一个小方格跳到令一个方格,而我们需要的是,让它缓慢的移动到下一个方格,有一个移动的过程
为了实现这个过程,我们在移动的时候不是让人物的坐标马上就改变,而是改变人物的状态,由静止到移动,然后处于移动状态的时候,再让人物一小步一小步的移动到目标点
修改Character类的构造器,如下

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);
	//调整人物位置
	self.anime.y -= 16;
	//设定不移动
	self.move = false;
	//在一个移动步长中的移动次数设定
	self.moveIndex = 0;
};

调整人物位置是因为,人物的图片分割后,每个动作的大小为32*48,而地图每个小格的大小是32*32,
然后设定人物状态为不移动,然后修改changeDir 方法

/**
 * 改变人物方向
 **/
Character.prototype.changeDir = function (dir){
	var self = this;
	//如果正在移动,则无效
	if(!self.move){
		//设定人物方向
		self.direction = dir;
		//设定图片动画
		self.anime.setAction(dir);
		//开始移动
		self.move = true;
		self.moveIndex = 0;
	}
};

这里要简单说明一下LAnimation类的setAction方法,setAction(rowindex,colindex)方法有两个参数,LAnimation里传进来的图片数组是一个二维数组,这两个参数分别可以改变目前显示的图片的动作,当然,也可以只传其中一个参数。
我这次是将4*4的人物动作图片分割为4*4的二维数组传给了LAnimation类,所以现在每一行图片代表一个方向
人物状态设置为移动后,就应该在循环事件里开始一步步的移动了

/**
 * 循环事件 
 **/
Character.prototype.onframe = function (){
	var self = this;
	//人物动作速度控制
	if(self.speedIndex++ < self.speed)return;
	self.speedIndex = 0;
	//当人物可移动,则开始移动
	if(self.move)self.onmove();
	//人物动画播放
	self.anime.onframe();
};
/**
 * 开始移动 
 **/
Character.prototype.onmove = function (){
	var self = this;
	//设定一个移动步长中的移动次数
	var ml_cnt = 4;
	//计算一次移动的长度
	var ml = STEP/ml_cnt;
	//根据移动方向,开始移动
	switch (self.direction){
		case UP:
			self.y -= ml;
			break;
		case LEFT:
			self.x -= ml;
			break;
		case RIGHT:
			self.x += ml;
			break;
		case DOWN:
			self.y += ml;
			break;
	}
	self.moveIndex++;
	//当移动次数等于设定的次数,开始判断是否继续移动
	if(self.moveIndex >= ml_cnt){
		self.moveIndex = 0;
		//如果已经松开移动键,则停止移动,否则继续移动
		if(!isKeyDown){
			self.move = false;
			return;
		}
	}
};

这里,我选择了让人物每个步长分四次进行移动,这样就实现了缓慢移动的效果,运行程序,点击画面中的方向键,看到了把,人物已经可以开始移动了,而且是缓慢的移动


但是,光这样还是不行,我们发现,人物是可以移动了,但是他现在是超人,飞檐走壁无所不入,移动的畅通无阻
这就需要我们在移动过程中,加入移动判断,看看是否可以移动,
为了实现这个判断,我们必须要知道地图什么地方可以移动,什么地方不可以移动
所以,我们需要一个地图的地形,如下

//地图地形数组
var mapdata = [
[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,1],
[1,1,0,0,0,0,1,1,0,0,0,0,1,1,1],
[1,0,0,0,1,1,1,1,1,0,0,1,1,0,1],
[1,0,0,1,1,1,1,1,1,1,0,1,1,0,1],
[1,0,0,1,1,1,0,1,1,1,1,1,0,0,1],
[1,0,0,0,0,0,0,0,1,1,1,1,0,0,1],
[1,1,0,0,0,0,0,0,0,1,1,0,0,0,1],
[1,1,0,0,0,0,0,0,0,0,0,0,0,0,1],
[1,1,1,1,1,1,1,1,1,1,1,1,1,1,1]
];

地形数组中,0代表可以移动,1代表障碍物,是不可移动的,
接下来,给Character类添加判断方法

/**
 * 障碍物判断
 * @param 判断方向 
 **/
Character.prototype.checkRoad = function (dir){
	var self = this;
	var tox,toy,myCoordinate;
	//当判断方向为空的时候,默认当前方向
	if(dir==null)dir=self.direction;
	//获取人物坐标
	myCoordinate = self.getCoordinate();
	//开始计算移动目的地的坐标
	switch (dir){
		case UP:
			tox = myCoordinate.x;
			toy = myCoordinate.y - 1;
			break;
		case LEFT:
			tox = myCoordinate.x - 1;
			toy = myCoordinate.y ;
			break;
		case RIGHT:
			tox = myCoordinate.x + 1;
			toy = myCoordinate.y;
			break;
		case DOWN:
			tox = myCoordinate.x;
			toy = myCoordinate.y + 1;
			break;
	}
	//如果移动的范围超过地图的范围,则不可移动
	if(tox <= 0 || toy <= 0)return false;
	if(toy >= mapdata.length || tox >= mapdata[0].length)return false;
	//如果目的地为障碍,则不可移动
	if(mapdata[toy][tox] == 1)return false;
	return true;
};

然后,在changeDir方法,和onmove方法中,添加相应的判断,如下

/**
 * 开始移动 
 **/
Character.prototype.onmove = function (){
	var self = this;
	//设定一个移动步长中的移动次数
	var ml_cnt = 4;
	//计算一次移动的长度
	var ml = STEP/ml_cnt;
	//根据移动方向,开始移动
	switch (self.direction){
		case UP:
			self.y -= ml;
			break;
		case LEFT:
			self.x -= ml;
			break;
		case RIGHT:
			self.x += ml;
			break;
		case DOWN:
			self.y += ml;
			break;
	}
	self.moveIndex++;
	//当移动次数等于设定的次数,开始判断是否继续移动
	if(self.moveIndex >= ml_cnt){
		self.moveIndex = 0;
		//如果已经松开移动键,或者前方为障碍物,则停止移动,否则继续移动
		if(!isKeyDown || !self.checkRoad()){
			self.move = false;
			return;
		}
	}
};
/**
 * 改变人物方向,并判断是否可移动
 **/
Character.prototype.changeDir = function (dir){
	var self = this;
	//如果正在移动,则无效
	if(!self.move){
		//设定人物方向
		self.direction = dir;
		//设定图片动画
		self.anime.setAction(dir);
		//判断是否可移动
		if(!self.checkRoad(dir))return;
		//如果可以移动,则开始移动
		self.move = true;
		self.moveIndex = 0;
	}
};

好了,大功告成,开始运行吧


测试URL如下

http://lufylegend.com/demo/rpg/index.html


lufylegend.js引擎包内包含这个demo,请直接下载lufylegend.js引擎,查看引擎包内源码

lufylegend.js引擎下载地址

http://lufylegend.com/lufylegend


地图滚动和人物对话等,下次再继续吧,请大家多支持

人生如梦游戏间,RPG游戏开源开发讲座(JAVA篇)[5]——一树双花

继续,考虑到日后扩充的需要,开始将代码模块化重构,将原有MyPanel分解成Common,GameMap,GameHandle及MyPanel等4个子模块,逐步实现Sprite操作。0-5讲源码下载地...
  • cping1982
  • cping1982
  • 2007-08-17 11:30:00
  • 8164

人生如梦游戏间,RPG游戏开源开发讲座(JAVA篇)[3]——邯郸学步

书接前文,事表上回。话说上回书提到“画面闪烁问题和角色动作的变更”是目前我们所面临的两大难点之一,本次,将就解决画面闪烁的前提条件——角色动作变更,也即“动画”进行较为深入的分析。大家都很清楚的知道,...
  • cping1982
  • cping1982
  • 2007-07-17 08:06:00
  • 9328

人生如梦游戏间,RPG游戏开源开发讲座(JAVA篇)[2]——踏破红尘

“本鹏”上回书言道,Java 游戏中地图的构建是一件极其简单的事情,本次书接前文,探讨游戏中角色的移动问题。 众所周知,[角色]是一个游戏的灵魂所在,没有角色的游戏,就是没有灵魂的游戏。 那么,如何让...
  • cping1982
  • cping1982
  • 2007-06-24 11:17:00
  • 8041

人生如梦游戏间,RPG游戏开源开发讲座(JAVA篇)[4]——一步莲华

         从星期一开始一直郁闷……最近的状况……用迷信的说法就是犯小人,以社会学的观点是由于出现人际交往困难造成社会评价降低……无比郁闷中,继续写这个……上一回我们写到关于如何改变角色的移动样...
  • cping1982
  • cping1982
  • 2007-08-17 09:29:00
  • 9252

人生如梦游戏间,RPG游戏开源开发讲座(JAVA篇)[6]——走马观花

 在游戏中通常不可能允许一幅场景贯穿始终,这就提出了场景变更的要求,基于这一要求的实现,我们将进行如下效果的Java代码实现。下载地址http://www.3adisk.com/?onlinezero...
  • cping1982
  • cping1982
  • 2007-08-17 15:56:00
  • 7746

人生如梦游戏间,RPG游戏开源开发讲座(JAVA篇)[0]——月晕础润

开场诗:不儒不道又不仙,非神非圣也非贤。轻吐心头寻常语,开辟文武一片天。 自表诗:北冥沉渊有鲲鹏,吞噬金乌戮真龙。一日扶摇凌天起,三千世界可横行。      小子“鹏凌三千”,欲将心...
  • cping1982
  • cping1982
  • 2007-06-20 16:46:00
  • 14649

html5游戏开发-零基础开发RPG游戏-开源讲座(三)-卷轴&对话实现

前两篇,RPG的开发已经实现了添加地图和添加游戏人物,本篇来实现地图的卷轴滚动和人物对话的实现,效果如下想要了解前两篇内容,请电击下面的链接html5游戏开发-零基础开发RPG游戏-开源讲座(一)ht...
  • lufy_Legend
  • lufy_Legend
  • 2011-12-23 01:45:05
  • 22963

html5游戏开发-零基础开发RPG游戏-开源讲座(一)

因为上一篇雷电的开发中,有朋友反应不太理解,本篇将以零基础的视点,来讲解如何开发一款RPG游戏。在游戏的世界里,我们可以看到各种地图,各种游戏人物,看到人物在地图上行走,对话等,无论是地图还是人物,其...
  • lufy_Legend
  • lufy_Legend
  • 2011-12-13 13:49:21
  • 41403

cocos2dx3.2开发 RPG《Flighting》(十一)角色分类——英雄与怪物

一、前言 先补充一下,英雄的死亡 英雄的死亡,我们要在FlightLayer对m_rolesArray进行清除操作 void FlightLayer::cleanNullPtrInArray()...
  • hezijian22
  • hezijian22
  • 2015-01-10 21:27:36
  • 1315

HTML5游戏开发

一、如何学习HTML5游戏开发?   如果是刚接触HTML5,也是第一次开发游戏,过程中难免会遇到这样那样的问题,我所遇到的第一个问题就是:我对HTML5还不是很了解。因此我首先要分享的就是学习...
  • wjc19911118
  • wjc19911118
  • 2012-08-01 11:26:05
  • 5947
收藏助手
不良信息举报
您举报文章:html5游戏开发-零基础开发RPG游戏-开源讲座(二)-跑起来吧英雄
举报原因:
原因补充:

(最多只允许输入30个字)