用canvas写一个h5小游戏

Posted 放羊的阿波罗

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用canvas写一个h5小游戏相关的知识,希望对你有一定的参考价值。

这篇文章我们来讲一讲用canvas画一个躲水果的小游戏。就是通过手指控制一个人物移动来躲避水果,若发生碰撞,则游戏结束。

我们定义一个game_control对象来处理初始化,事件绑定,游戏开始,游戏结果判定,游戏结束等判定。

在游戏中,我们需要一个人物以及三种水果的图片,我们做成了雪碧图。

接下来直接上代码吧~

首先我们定义一个ship对象,3个水果、一个人物都是基于这个对象的。

function ship(options){
				if (options) {
					var width=options.width,
						height=options.height;
					this.x=options.x;
					this.y=options.y;
					this.width=width;
					this.height=height;
					this.first_x=options.x;
					this.first_y=options.y;
					this.speedx=options.speedx;
					this.speedy=options.speedy;
					this.csspeedx=options.speedx;
					this.csspeedy=options.speedy;
					this.xDirection=options.xDirection||1;//x轴方向
					this.yDirection=options.yDirection||1;//y轴方向
					var canvasOffscreen = document.createElement(‘canvas‘);
					canvasOffscreen.width =width;
					canvasOffscreen.height =height;
					canvasOffscreen.getContext(‘2d‘).drawImage(options.image, options.sourcex, options.sourcey, options.sourcewidth, options.sourceheight, 0, 0, width, height);
					this.canvasOffscreen=canvasOffscreen;
					this.init();
				}
			}

			ship.prototype={
				init:function(){
					
				},
				reset:function(){

				},
				draw:function(ctx){
					//let canvasOffscreen=this.canvasOffscreen;
					ctx.drawImage(this.canvasOffscreen, this.x, this.y);
				},
				move:function(modifier){
					this.x+=this.xDirection*this.speedx * modifier;
					this.y+=this.yDirection*this.speedy * modifier;
					if(this.x>winwidth-this.width){
						this.x=winwidth-this.width;
						this.xDirection=-1;
					}else if(this.x<0){
						this.x=0;
						this.xDirection=1
					}
					if(this.y>winheight-this.height){
						this.y=winheight-this.height;
						this.yDirection=-1;
					}else if(this.y<0){
						this.y=0;
						this.yDirection=1;
					}
				}
			}

  当我们用canvas绘制人物和水果时,可以采用离屏绘制的方法,就是先将每个水果,人物绘制一遍,然后每次重绘的时候,再用canvas将这个已绘制的绘制出来就可以了,这样效率会比每次都直接绘制图片要高

var canvasOffscreen = document.createElement(‘canvas‘);
					canvasOffscreen.width =width;
					canvasOffscreen.height =height;
					canvasOffscreen.getContext(‘2d‘).drawImage(options.image, options.sourcex, options.sourcey, options.sourcewidth, options.sourceheight, 0, 0, width, height);




ctx.drawImage(this.canvasOffscreen, this.x, this.y);

  接下来说一下game_control 初始化init方法吧

init:function(){
					var canvas=document.getElementById(‘game-canvas‘),
						self=this,
						ctx=canvas.getContext(‘2d‘);
					self.ctx=ctx;
					canvas.width=winwidth;
					canvas.height=winheight;
					let img=new Image();
					img.onload=function(){
						var zjb=new hero({
							image:img,
							x:gettruesize(250),
							y:gettruesize(56),
							width:gettruesize(50),
							height:gettruesize(50),
							sourcewidth:104,
							sourceheight:104,
							sourcex:0,
							sourcey:0
						});
						for(var i=0;i<3;i++){
							var x=60,y=110;
							if(i==1){x=38,y=330;}
							if(i==2){x=218,y=338;}
							var monster=new ship({
												image:img,
												x:gettruesize(x),
												y:gettruesize(y),
												width:gettruesize(50),
												height:gettruesize(50),
												sourcewidth:104,
												sourceheight:104,
												speedx:gettruesize(getrandom(60,100)),
												speedy:gettruesize(getrandom(60,100)),
												sourcex:104*(i+1),
												sourcey:0
											});
							self.monsters.push(monster);
						}
						self.objs=zjb;
						self.draw();
						self.bindmove(canvas,zjb);
					}
					img.src="all.png";					
				}

  主要作用是当 雪碧图载入完成后,定义出一个人物对象以及3个水果对象,并通过draw方法将他们用canvas绘制出来,同时给人物对象进行手指事件的绑定(bindmove方法)

接下来讲讲bindmove方法

bindmove:function(canvas,hero){
					let self=this;
					canvas.addEventListener(‘touchstart‘, function(e) {
						var event = e||window.event,
							csx = event.touches[0].clientX,
							csy = event.touches[0].clientY,
							nanshengcsx = hero.x,
							nanshengcsy = hero.y;
						if (csx <= hero.x + hero.width && csx >= hero.x && csy <= hero.y + hero.height && csy >= hero.y) {
							if (!self.startstate) {
								self.start();
			                    timer = setInterval(function(){
			                    	self.draw();
			                    }, 1);
							}
							document.addEventListener(‘touchmove‘, move,false);
							function move(e){
								e.preventDefault();
								var event = e||window.event,
									nowx = event.touches[0].clientX,
									nowy = event.touches[0].clientY;
								hero.x = nanshengcsx + nowx - csx;
								hero.y = nanshengcsy + nowy - csy;
								if(hero.x<0){
									hero.x=0;
								}else if(hero.x+hero.width>winwidth){
									hero.x=winwidth-hero.width;
								}
								if(hero.y<0){
									hero.y=0;
								}else if(hero.y+hero.height>winheight){
									hero.y=winheight-hero.height;
								}
							}
							function moveend(e){
								document.removeEventListener(‘touchend‘,moveend);
								document.removeEventListener(‘touchmove‘,move);
							}
							document.addEventListener(‘touchend‘, moveend ,false);
						}
					},false);
				}

  这个方法用来判断手指触碰屏幕时是否在 人物这个位置,如果是,则游戏开始(触发start方法),并注册移动事件,跟随手指移动而移动。

start方法中定义一个循环,让canvas 一帧一帧的画。

start:function(){
					var self=this;
					this.startstate=true;
					this.then=Date.now();
					this.starttime=this.then;
					document.getElementById(‘tips‘).style.display="none";
					timer = setInterval(function(){
                    	self.draw();
                    }, 1);
				}

  最后还要一个check方法,来判断人物与水果间有没有发生触碰,若有则游戏结束。

check:function(){
					var last=this.then-this.starttime;

					var monsters=this.monsters;
					var nansheng=this.objs;
					if (this.monsterSum != Math.floor(last / 5000)){//如果时间经过5秒就增加一个怪兽实例   
						this.monsterSum ++;   
						for(var i=0;i<monsters.length;i++){
							monsters[i].speedx+=60;
							monsters[i].speedy+=60;
						}
					}   
					for(var i=0;i<monsters.length;i++){
						var monster1=monsters[i];
						if ((monster1.x - nansheng.width) <= nansheng.x && nansheng.x <= (monster1.x + monster1.width) && (monster1.y - nansheng.height) <= nansheng.y && nansheng.y <= (monster1.y + monster1.height)) {
							this.end();
						}
					}
				}

  这样一个简单的小游戏就完成啦~

 

以上是关于用canvas写一个h5小游戏的主要内容,如果未能解决你的问题,请参考以下文章

[教你做小游戏] 用177行代码写个体验超好的五子棋

JS写小游戏「跳一跳」外挂之Canvas图像识别

java和h5 canvas德州扑克开发中

H5 canvas绘制出现模糊的问题

H5 Canvas 绘图

H5使用Canvas绘图