博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
用canvas写一个h5小游戏
阅读量:6786 次
发布时间:2019-06-26

本文共 5535 字,大约阅读时间需要 18 分钟。

这篇文章我们来讲一讲用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.οnlοad=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

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

 

转载于:https://www.cnblogs.com/bobogoodgoodstudy/p/6024790.html

你可能感兴趣的文章
mysql悲观锁与乐观锁
查看>>
ubuntu下python2-python3版共存,创建django项目出现的问题
查看>>
2018.4.3三周第二次课
查看>>
eclipse_jee版本提供了从数据库直接生成实体类的工具!
查看>>
Error: Can't set headers after they are sent
查看>>
本地用户模式、虚拟用户模式使用
查看>>
任正非接班人亮相:原来他要的是这种类型!
查看>>
valgrind 运行出错
查看>>
ubuntu日常使用心得(随时更新中。。。)
查看>>
Java 多线程回顾
查看>>
二、nginx服务器基础配置命令
查看>>
TEMP表空间之Ogg复制进程占用
查看>>
java中的构造函数总结
查看>>
windows下kangle虚拟主机-安装mysql教程及心得
查看>>
我的友情链接
查看>>
ios中SQLite的重构封装
查看>>
centos 搭建 nagios 监控系统.
查看>>
管理禁忌小记录(一)
查看>>
遍历接口信息
查看>>
Dell R710 服务器更新windows server 2012的相关问题
查看>>