开发html5 2d 赛车游戏以及打包发布为手机APP 第三话 拖动我们的主角车子

原本打算直接讲如何让NPC自动出来,但是检查代码的时候发现要让NPC车子出来得涉及到面向对象。所以决定这话先讲简单的面向对象化,还有怎么让主角车子能被拖动起来。

那么,我们就得修改一下咱们原来的代码,定义一个Car的类和定义用于保存Car类实例化对象的 zhujue

var zhujue;	
	
			function Car(x,y,width,height,img) {
				this.x=x;
				this.y=y;
				this.width=width;
				this.height=height;
				this.img=img;
                     }

Car类的属性有横坐标x,竖坐标y,宽width,高height,还有用保存Image()实例化对象的img,

然后在init()方法里面实例化 Car类,保存于zhujue, 把原先我们代码里面的主角车的那些属性的值都分别保存于zhujue.x ; zhujue.y ; zhujue.width ; zhujue.height ; zhujue.img

function init() {
                     .................
                                //实例化
   				zhujue=Object.create(Car);
                                
                                //
				zhujue.x=canvas1.width / 2 - 40 / 2;
				zhujue.y=canvas1.height - 80;
				zhujue.width=40;
				zhujue.height=80;
                                zhujuepic = new Image();
				zhujue.img=zhujuepic;
                      .................
}

我们画主角车的代码也改一改,改为zhujue的每一项属性

ctx.drawImage(zhujue.img, zhujue.x, zhujue.y, zhujue.width, zhujue.height);

这样一改,一看其实和上一话的效果差不多,但是区别就在于主角车的每一样属性这时已经是可变的了,这样也是为了后面能自动出现NPC车辆作准备

开发html5 2d 赛车游戏以及打包发布为手机APP 第三话 拖动我们的主角车子

////////////////////////////////////////////////////////////////////////////////////////

咱们接下来要做的就是实现主角车辆能被拖拽移动的代码

html5在移动设备上的拖拽功能离不开下面的代码

添加手指点下去时的事件监听处理,要是监听到,就到onTouchStart方法里面去处理
canvas1.addEventListener('touchstart', onTouchStart, false);

添加手指点下去并移动时的事件监听处理,要是监听到,就到onTouchMove方法里面去处理
canvas1.addEventListener('touchmove',onTouchMove,false);

添加手指终止拖拽时的事件监听处理,要是监听到,就到onTouchEnd方法里面去处理
canvas1.addEventListener('touchend',onTouchEnd,false);
//监听到手指点下去事件的发生,执行下面代码
function onTouchStart(event) {
                        .............
			}


//监听到手指点了下去并拖拽事件的发生,执行下面代码
function onTouchMove(event) {
                        .............
			}

//监听到手指终止拖拽事件的发生,执行下面代码
function onTouchEnd(event) {
                        ..............	
			}

那么怎么确定手指点到了主角车,,而不是路面背景呢??

咱们要用到一个叫做碰撞检测功能的代码,所谓碰撞检测就是检测游戏中2件物体有没有碰撞;于是,检测手指是否碰撞到主角车也是可以实现的

function checkimpact(finger_x, finger_y, el2) {
				var e1 = {
					x: finger_x,
					y: finger_y,
					w: 10,
					h: 10
				}
				var e2 = {
					x: el2.x,
					y: el2.y,
					w: el2.width,
					h: el2.height
				}
				var px, py;
				px = e1.x <= e2.x ? e2.x : e1.x;
				py = e1.y <= e2.y ? e2.y : e1.y;
				if (px >= e1.x && px <= e1.x + e1.w && py >= e1.y && py <= e1.y + e1.h && px >= e2.x && px <= e2.x + e2.w && py >= e2.y && py <= e2.y + e2.h) {

					return true;
				} else {
					return false;
				}
			}

 解释:参数finger_x用于传递手指点击下的横坐标,参数finger_y用于传递手指点击下的竖坐标,el2代表要检测是否和手指发生碰撞的物件(这里主要是主角车)

var e1其实就是用来保存手指点下去的横坐标,竖坐标,还有影响范围的宽和高

var e2就是用来保存主角车的横坐标,竖坐标,主角车的宽和高

后面整个的就是对两个物件的碰撞检测判断,下面4个判断流程不用修改,当返回true的时候就代表碰撞发生了;当返回 false的时候,就代表碰撞没有发生

var px, py;
				px = e1.x <= e2.x ? e2.x : e1.x;
				py = e1.y <= e2.y ? e2.y : e1.y;
				if (px >= e1.x && px <= e1.x + e1.w && py >= e1.y && py <= e1.y + e1.h && px >= e2.x && px <= e2.x + e2.w && py >= e2.y && py <= e2.y + e2.h) {
					return true;
				} else {
					return false;
				}

接着定义全局变量 is_clicked_zhujue,用于保存手指和主角车的碰撞检测结果

var is_clicked_zhujue;

然后在处理手指点击下事件发生的方法onTouchStart()里面去调用checkimpact()方法,看看是否点中了主角车

function onTouchStart(event) {
				//手指点击事件的实例化对象
				var touch = event.targetTouches[0];

                                //如果点中主角车则把true赋值给is_clicked_zhujue
				if(checkimpact(touch.pageX,touch.pageY,zhujue))
				{
					//alert("1");
				        is_clicked_zhujue=true;
				}
			}

 解释:大家看到//alert("1");可能会问是啥东西,有啥用途,,这是JS的弹框代码,如果把双斜杠//注释符号去掉,结合整个if(........)判断,就是当手指点击到主角车的时候,显示一个弹框,弹框的内容为“1”(默认代码里注释掉了弹框),然后把is_clicked_zhujue赋值为true

如果用的是HBuilder,我们复制HBuilder自带浏览器的当前页面地址,然后在360浏览器或者Google Chrome浏览器打开这个网址,按键盘上的F12打开调试模式,Device选择要模拟调试的设备型号(我随便选了iPhone5),然后点击一下主角车,看看有没有显示出弹框(普通网页浏览器由于只支持鼠标点击,不能模拟手指点击,所以我们这里要调试必须用到模拟手机模式,不然没法调试,另一个调试方法是用HBuilder线上打包为APK安装包,不过效率不好,除非你已经实现了全套功能,再放到自己的手机设备去调试)

开发html5 2d 赛车游戏以及打包发布为手机APP 第三话 拖动我们的主角车子
 

上图显示点击了主角车,,出现了内容为“1”的弹框

想要当手指拖拽移动的时候,主角车子也跟着手指拖拽移动,到onTouchMove方法里面去实现

function onTouchMove(event) {
				//手指点击事件的实例化对象
				var touch = event.targetTouches[0];
				
				if(is_clicked_zhujue)
				{
					zhujue.x=touch.pageX-zhujue.width/2;
					zhujue.y=touch.pageY-zhujue.height/2;
				}
			}

解释:当手指拖拽移动,并且is_clicked_zhujue为true的时候,把主角的横坐标zhujue.x赋值为手指事件的X横坐标touch.pageX,把主角的竖坐标zhujue.y赋值为手指事件的Y竖坐标touch.pageY,这样,主角车就跟随手指拖拽移动了

最后,当手指点击事件终结并离开屏幕时,会自动进入onTouchEnd()方法,于是咱们在里面添加给is_clicked_zhujue的值赋为false的处理,防止下一次错误的拖拽

function onTouchEnd(event) {
				
				
				is_clicked_zhujue=false;
				
			}

 效果


开发html5 2d 赛车游戏以及打包发布为手机APP 第三话 拖动我们的主角车子
  

完整代码

<!DOCTYPE html>
<html>

	<head>
		<meta charset="utf-8">
		<meta name="viewport" content="initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
		<title>赛车游戏</title>
		<script type="text/javascript">
			var ctx;
			var canvas1;
			var roadpic;
			var zhujuepic;
			var fenjiepic;
			var fen_y;
			var road_d;
			
			
			var zhujue;
			var is_clicked_zhujue;
			
			function Car(x,y,width,height,img) {
				this.x=x;
				this.y=y;
				this.width=width;
				this.height=height;
				this.img=img;
                     }
			

			function init() {
				
				ctx = document.getElementById('canvas').getContext('2d');
				canvas1 = document.getElementById('canvas');
				
				
				canvas1.addEventListener('touchstart', onTouchStart, false);
				canvas1.addEventListener('touchmove',onTouchMove,false);
				canvas1.addEventListener('touchend',onTouchEnd,false);
				//------------------------------------------//
				zhujue=Object.create(Car);
				zhujue.x=canvas1.width / 2 - 40 / 2;
				zhujue.y=canvas1.height - 80;
				zhujue.width=40;
				zhujue.height=80;
			        zhujuepic = new Image();
				zhujue.img=zhujuepic;
				//------------------------------------------//
				roadpic = new Image();
							
				fenjiepic = new Image();
				roadpic.src = "img/road.png";
				zhujuepic.src = "img/car1.png";
				fenjiepic.src = "img/fenjie.png";
				fen_y = 0;
				road_d = 1;
				setInterval(function(e) {
					animate();
				}, 50);
			}
			
			function onTouchMove(event) {
				
				var touch = event.targetTouches[0];
				
				if(is_clicked_zhujue)
				{
					zhujue.x=touch.pageX-zhujue.width/2;
					zhujue.y=touch.pageY-zhujue.height/2;
				}
			}
			
			function onTouchStart(event) {
				
				var touch = event.targetTouches[0];
				if(checkimpact(touch.pageX,touch.pageY,zhujue))
				{
					//alert("1");
				is_clicked_zhujue=true;
				}
			}
			
			
			function onTouchEnd(event) {
				
				
				is_clicked_zhujue=false;
				
			}

			
			

			function animate() {
				
				ctx.clearRect(0, 0, canvas1.width, canvas1.height);
				//----------------------------------//
				if (road_d == 1) {
					ctx.drawImage(roadpic, 0, 0, canvas1.width + 8, canvas1.height + 8);
					road_d = 0;
				} else {
					ctx.drawImage(roadpic, 0, 0, canvas1.width, canvas1.height);
					road_d = 1;
				}
				
			    //----------------------------------//
				for (var i = 0; i < 50; i++) {
					ctx.drawImage(fenjiepic, canvas1.width / 2 - 10 / 2, fen_y - 80 * i, 10, 30);
				}
				if (fen_y < canvas1.height) {
					fen_y = fen_y + 150;
				} else if (fen_y >= canvas1.height) {
					fen_y = 0;
				}
				
				//----------------------------------//
				ctx.drawImage(zhujue.img, zhujue.x, zhujue.y, zhujue.width, zhujue.height);
			}
			



			function checkimpact(finger_x, finger_y, el2) {
				var e1 = {
					x: finger_x,
					y: finger_y,
					w: 10,
					h: 10
				}
				var e2 = {
					x: el2.x,
					y: el2.y,
					w: el2.width,
					h: el2.height
				}
				var px, py;
				px = e1.x <= e2.x ? e2.x : e1.x;
				py = e1.y <= e2.y ? e2.y : e1.y;
				if (px >= e1.x && px <= e1.x + e1.w && py >= e1.y && py <= e1.y + e1.h && px >= e2.x && px <= e2.x + e2.w && py >= e2.y && py <= e2.y + e2.h) {
					return true;
				} else {
					return false;
				}
			}
		</script>
	</head>

	<body onLoad="init();">
		<canvas id="canvas" width="300" height="540">

		</canvas>
	</body>

</html>

相关推荐