云顶娱乐手机官网-云顶娱乐网址

热门关键词: 云顶娱乐手机官网,云顶娱乐网址

[Canvas前端游戏支付]——FlappyBird详解

2019-09-29 作者:前端开发   |   浏览(200)

[Canvas前端游戏开采]——FlappyBird详解

2016/01/03 · HTML5 · Canvas

原稿出处: xingoo   

间接想和睦做点小东西,直到近日看了本《HTML5戏耍开辟》,才领会游戏开辟中的一丢丢入门知识。

本篇就针对学习的多少个样例,本身入手试行,做了个FlappyBird,源码分享在度盘 ;也足以参照他事他说加以考察github,里面有越来越多的娱乐样例。

canvas 制作flappy bird(像素小鸟)全流程,canvasflappy

打闹截图

图片 1

图片 2

flappy bird制作全流程:

图片 3

HTML5之Canvas

Canvas是Html5中用于绘图的成分,它可以绘制各类图片,比方长方形,多边形,圆形等等。即使想要精通Canvas的接纳能够参照:

 

//要是想要使用canvas,首先需求获得上下文对象: ctx = document.getElementById('canvas').getContext('2d'); //然后使用那几个ctx绘制图形

1
2
3
//如果想要使用canvas,首先需要获得上下文对象:
ctx = document.getElementById('canvas').getContext('2d');
//然后使用这个ctx绘制图形

在cavas每一个绘制都以单独的操作。比方下图的多个绘制图形,首个会以遮掩的情势绘制,由此制图图形的一一就展现相当最主要了。

图片 4

一、前言

像素小鸟这一个轻松的十三日游于二零一六年在网络上爆红,游戏上线一段时间内appleStore上的下载量一度达到伍仟万次,风靡有的时候,

前段时间移动web的遍布为如此未有复杂逻辑和精美动画效果,不过野趣十足的小游戏提供了美好的景况,

再者借助各大社交软件平台的传播效应,创新意识不断的小游戏有着杰出的经营出卖效果与利益,获得了多数的关心。

开首在英特网查询了众多关于这些小游戏的资料,不过基本上乌烟瘴气,自个儿的组合相关学科将这一个游乐的基本点框架整理出来,供大家一起学习。

canvas之drawImage()

本篇的嬉戏开垦中,首要行使的是依靠图片绘制的api:drawImage(),它有多少个为主的运用格局:

ctx.drawImage(image,this.bx,this.by,this.bwidth,this.bheight); ctx.drawImage(image,x,y,width,height,this.px,this.py,this.pwidth,this.pheight);

1
2
ctx.drawImage(image,this.bx,this.by,this.bwidth,this.bheight);
ctx.drawImage(image,x,y,width,height,this.px,this.py,this.pwidth,this.pheight);

首先个api中,钦赐Image对象,然后给出绘制图片的x,y坐标以及宽度和可观就可以。

其次个api中,第一组x,y,width,height则钦命了裁剪图片的坐标尺寸,那在使用多成分的矢量图时很常用。譬如:

图片 5

地点的图样中为了削减图片财富的呼吁数量,把过多的成分放在了一个图纸中,此时就要求通过裁剪的方式,获取钦点的图样成分。

二、才能大旨

 基本JavaScript基础 ,canvas 基础, 面向对象的思辨;

FlappyBird原理剖判

实在这些游乐很简短,一张图就能够看懂在那之中的神秘:

图片 6

里头背景和地面是不动的。

鸟类独有上和下七个动作,能够经过垄断小鸟的y坐标达成。

上下的管仲只会向左移动,为了简单完毕,游戏中贰个画面仅仅会油不过生一些管仲,那样当管仲移出左边的背景框,就机关把管仲放在最侧面!

if(up_pipe.px+up_pipe.pwidth>0){ up_pipe.px -= velocity; down_pipe.px -= velocity; }else{ up_pipe.px = 400; down_pipe.px = 400; up_pipe.pheight = 100+Math.random()*200; down_pipe.py = up_pipe.pheight+pipe_height; down_pipe.pheight = 600-down_pipe.py; isScore = true; }

1
2
3
4
5
6
7
8
9
10
11
if(up_pipe.px+up_pipe.pwidth>0){
                up_pipe.px -= velocity;
                down_pipe.px -= velocity;
            }else{
                up_pipe.px = 400;
                down_pipe.px = 400;
                up_pipe.pheight = 100+Math.random()*200;
                down_pipe.py = up_pipe.pheight+pipe_height;
                down_pipe.pheight = 600-down_pipe.py;
                isScore = true;
            }

很简短吗!

出于该游戏一共就那多少个因素,因而把她们都放入一个Objects数组中,通过setInteral()方法,在早晚上隔时间内,实行一次重绘

重绘的时候会先去掉画面中的全体因素,然后依照新的因素的坐标一回绘制图形,那样就能够冒出活动的功用。

三、思路整理

宪章小鸟重力

是因为那么些游戏不涉及小鸟横向的位移,由此一旦模拟出小鸟下跌的动作以及上涨的动作就能够了。

图片 7

上升:这一个异常的粗略,只要把小鸟的y坐标减去肯定的值就可以了

下落:其实重力不须要动用gt^2来效仿,能够差不离的钦赐多少个变量,v1和gravity,那四个变量与setInterval()中的时间共同功能,就能够模仿重力。

ver2 = ver1+gravity; bird.by += (ver2+ver1)*0.5;

1
2
ver2 = ver1+gravity;
bird.by += (ver2+ver1)*0.5;

全方位娱乐的逻辑比较轻松:

第一游戏法规:鸟撞到管道上,地上要身故,飞到显示器外要离世。

附带:鸟在飞翔的进度中,会落下,类似落体运动,要求游戏发烧友不断点击荧屏让鸟向上海飞机成立厂。

重复正是:鸟和背景成分的相对移动的进度,鸟不动,背景左移。

碰撞检查实验

娱乐中型袖珍鸟遇到管仲或然地面都会算游戏截止:

图片 8

其中条件1上管道的检查实验为:

((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&(bird.by<up_pipe.py+up_pipe.pheight))|| ((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&(bird.by<up_pipe.py+up_pipe.pheight))

1
2
((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&(bird.by<up_pipe.py+up_pipe.pheight))||
((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&(bird.by<up_pipe.py+up_pipe.pheight))

条件2下管道的检验为:

((bird.bx>down_pipe.px)&&(bird.by>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by<down_pipe.py+down_pipe.pheight))|| ((bird.bx>down_pipe.px)&&(bird.by+bird.bheight>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by+bird.bheight<down_pipe.py+down_pipe.pheight))

1
2
((bird.bx>down_pipe.px)&&(bird.by>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by<down_pipe.py+down_pipe.pheight))||
((bird.bx>down_pipe.px)&&(bird.by+bird.bheight>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by+bird.bheight<down_pipe.py+down_pipe.pheight))

条件3地面的检查测量试验最简便易行,为:

bird.by+bird.bheight>ground.bgy

1
bird.by+bird.bheight>ground.bgy

如若知足那多个条件,即使游戏结束,会解决循环以及提示游戏甘休消息。

将全方位娱乐细化:

咱俩使用面向对象的思路来成立,具体的东西用构造函数来创立,方法放到构造函数的真面目对象中。

打闹细化那些历程不是轻松的,如若在尚未相关指导的场馆下,自个儿要时时随地的结缘自个儿的主见去试错。

笔者使用的艺术是使用Xmind将流程以脑图的款式绘制下来,分块去做,不断细化记录本身的笔触,最后表现的成效如下:

(顺序依据图片中的序号去看  脑图、素材、及全体源码下载地址: 想练习的同班能够点这里)

脑图分为三大块:1、计划阶段 2、主函数 3、游戏优化。

图片 9

图片 10

 

 

分数计算

分数的计量与碰撞检查实验类似,设置三个开关,当管敬仲重新出现时,设置为true。当分值加1时,设置为false。

鸟类的最左侧的x坐标如若过量了管仲的x+width,就觉着成功通过。

if(isScore && bird.bx>up_pipe.px+up_pipe.pwidth){ score += 1; isScore = false; if(score>0 && score%10 === 0){ velocity++; } }

1
2
3
4
5
6
7
if(isScore && bird.bx>up_pipe.px+up_pipe.pwidth){
                score += 1;
                isScore = false;
                if(score>0 && score%10 === 0){
                    velocity++;
                }
            }

通过后,分值加1,速度+1。

 四、游戏达成:

近日组合脑图来渐渐达成大家的游艺。

1.装置canvas画布,准备图片数据,当图片加载成功后施行回调函数;

图片 11<canvas id="cvs" width="800" height="600"></canvas> <script> var imglist = [ { "name":"birds","src":"res/birds.png"}, { "name":"land","src":"res/land.png"}, { "name":"pipe1","src":"res/pipe1.png"}, { "name":"pipe2","src":"res/pipe2.png"}, { "name":"sky","src":"res/sky.png"} ]; var cvs = document.getElementById("cvs"); var ctx = cvs.getContext("2d"); </script> 画布计划,图片数据准备

此处这一个入口函数的设置要注意,必需保障图片能源加载成功后再实行其余操作,每加载一张图片大家让imgCount--,减到0的时候再进行主函数;

图片 12function load (source, callback ){ var imgEls={}; var imgCount=source.length; for (var i = 0; i < imgCount; i++) { var name = source[i].name; var newImg = new Image (); newImg.src = source[i].src; imgEls[name] = newImg; imgEls[name].addEventListener("load",function(){ imgCount--; if(imgCount==0){ callback(imgEls); }; }) }; }; 入口函数设置

主循环的安装:这里大家不应用setInterval来决定循环次数,大家利用二个叫requestAnimationFrame()的电火花计时器

       因为setInterval会生出时间标称误差,setInterval只好依照时间来运动固定距离。

       那对于轮播图一类几千微秒切换叁遍的动作来讲并不曾什么关系,然而对于我们16-18飞秒绘制二遍的动画片是老大不可靠赖的;

       requestAnimationFrame()这几个电火花计时器的裨益是依赖浏览器的性格来试行贰个函数,大家用来博取三次绘制的间隔时间;

       移动距离的估摸改变成速度×间隔时间的方式,来减轻绘图不标准的问题。

图片 13var preTime= Date.now(); //获取当明天子 function run(){ var now = Date.now(); //获取最新时刻 dt = now - preTime; //获取时间距离 preTime = now; //更新当前时光 ctx.clearRect(0,0,800,600); //清空画布 //--------------------------------------------- 绘制代码实施区域 //----------------------------------------------- requestAnimationFrame(run); //再度实践run函数 } requestAnimationFrame(run); //第二次推行run函数; 设置绘制方式

2、主函数分为两局地效用,轻易说正是把图画上去,然后管理动态效果,再剖断一下是还是不是违犯禁令。

2.1 小鸟的绘图:

  小鸟本身有多少个双翅扇动的效应,和一个下落的进度。

  羽翼扇动的进度是一张Smart图三幅画面包车型大巴的切换(设置贰个index属性,调控Smart图的地点),下跌进程是其y坐标在画布上的位移();

  所以小鸟的构造函数中应该包蕴(图源,x坐标,y坐标,速度,下降加快度,ctx(context画布))等参数。

  这里须要小心几点:

  •  小鸟的绘图采取canvas drawImage的九参数情势(分别是图表,原图的裁切起源,原图的宽高,贴到画布上的职责,贴到画布上的宽高);
  •  小鸟的翎翅扇动不能够太快,所以我们设置贰个阀门函数,当累计计时超过100ms的时候切换一下图片,然后在让一起计时减去100ms;
  •  小鸟的下降要求运用一定物理知识,可是都很轻易啦。 大家都以通过速度×时间来促成;

图片 14var Bird= function (img,x,y,speed,a,ctx){ this.img = img; this.x = x; this.y = y; this.speed = speed; this.a =a ; this.ctx = ctx; this.index = 0; //用于创设小鸟扇羽翼的动作 } Bird.prototype.draw = function (){ this.ctx.drawImage( this.img,52*this.index,0,52,45, this.x,this.y,52,45 ) } var durgather=0; Bird.prototype.update = function(dur){ //小鸟双翅扇动每100ms切换一张图纸 durgather+=dur; if(durgather>100){ this.index++; if(this.index===2){ this.index=0; } durgather -= 100; } //小鸟下降动作 this.speed = this.speed + this.a *dur; this.y = this.y + this.speed * dur; } 小鸟的构造函数及动作调节

  构造多少个鸟类,而且将其动作刷新函数和制图函数放置在大家地方提到的绘图区域,此后结构出的切近对象都以那般的操作步骤:

  这里必要潜心的有些是,怎么样让鸟儿顺畅的迈入飞翔,其实照旧物理知识,由于加快度的意义,大家给小鸟一个提升的顺时速度就能够了。

图片 15load(imglist ,function(imgEls){ //创设对象 //在主函数中创设多个小鸟 var bird = new Bird(imgEls["birds"],150,100,0.0003,0.0006,ctx); //主循环 var preTime= Date.now(); function run(){ var now = Date.now(); dt = now - preTime; preTime = now; ctx.clearRect(0,0,800,600); //--------图片绘制区域------- bird.update(dt) bird.draw(); //------------------------- requestAnimationFrame(run); } requestAnimationFrame(run); //设置点击事件。给小鸟叁个一眨眼的上进速度 cvs.addEventListener("click",function(){ bird.speed = -0.3; } ) }) 绘制小鸟,点击小鸟上飞

功能如下:

图片 16

2.2天上的绘图:

  天空的绘图相比轻松了,只要选拔canvas drawImage的三参数方式就足以(图源,画布上的坐标)。

  这里独一静心的一点是,无缝滚动的贯彻,对于800*600分辨率这种景况大家创立五个天空对象就能够了,不过为了适配越来越多的气象,大家将以此效果写活

  在穹幕的构造函数上加一个count属性设置多少个天空图片,count属性让实例通过原形中的方法访谈。后边涉及到再也出现的地面和管道,都给它们增加这种虚拟。

图片 17var Sky = function(img,x,speed,ctx) { this.img = img ; this.ctx = ctx; this.x = x; this.speed = speed; } Sky.prototype.draw = function(){ this.ctx.drawImage( this.img ,this.x,0 ) } Sky.prototype.setCount = function(count){ Sky.count = count; } Sky.prototype.update = function(dur){ this.x = this.x+ this.speed * dur; if(this.x<-800){ //天空图片的上涨的幅度是800 this.x = Sky.count * 800 + this.x; //当向左移动了一整张图形后当即切回第一张图纸 } } 天空构造函数及运动函数

  同理在主函数中创造2个天空对象,并将履新函数和制图函数放置在主循环的绘图区域;

  setcount是用来设置无缝滚动的

  注意一点:绘制上的图纸是有三个层级关系的,不可能把鸟画到天空的底下,那本来最后画鸟了,上面涉及到的掩没难题不再专门提到。

  这里仅插入部分连锁代码

图片 18var bird = new Bird(imgEls["birds"],150,100,0.0003,0.0006,ctx); var sky1 = new Sky(imgEls["sky"],0,-0.3,ctx); var sky2 = new Sky(imgEls["sky"],800,-0.3,ctx); //主循环 var preTime= Date.now(); function run(){ var now = Date.now(); dt = now - preTime; preTime = now; ctx.clearRect(0,0,800,600); //--------图片绘制区域------- sky1.update(dt); sky1.draw() sky2.update(dt); sky2.draw() sky1.setCount(2); bird.update(dt) bird.draw(); //------------------------- 绘制天空

2.3 地面的绘图

  和天上的绘图完全平等,由于本地图片尺寸相当的小,所以我们要多画多少个

图片 19var Land = function(img,x,speed,ctx){ this.img = img ; this.x = x; this.speed = speed; this.ctx = ctx ; } Land.prototype.draw = function(){ this.ctx.drawImage ( this.img , this.x ,488 ) } Land.prototype.setCount= function(count){ Land.count = count; } Land.prototype.update = function(dur){ this.x = this.x + this.speed * dur; if (this.x <- 336){ this.x = this.x + Land.count * 336; //无缝滚动的贯彻 } } 地面包车型地铁构造函数及运动函数 图片 20//创立----放置在开创区域 var land1 = new Land(imgEls["land"],0,-0.3,ctx); var land2 = new Land(imgEls["land"],336*1,-0.3,ctx); var land3 = new Land(imgEls["land"],336*2,-0.3,ctx); var land4 = new Land(imgEls["land"],336*3,-0.3,ctx); //绘制 ----放置在绘制区域 land1.update(dt); land1.draw(); land2.update(dt); land2.draw(); land3.update(dt); land3.draw(); land4.update(dt); land4.draw(); land1.setCount(4); //设置无缝滚动 绘制地面重要代码

2.4绘制管道

  管道的绘图有二个困难是管道中度的规定

  要点:

  •  为了保持游戏可玩性,管道必需有多少个恒定中度+二个大肆中度,且上下管道之间的留白是固定的增进率。
  • 管道不是接二连三的,多个相邻的管道之间有距离
  • 小心管道在无缝播放,抽回后必需交给二个新的随便中度,给客户一种错觉,以为又三个管道飘了过来。

  

图片 21var Pipe = function(upImg,downImg,x,speed,ctx){ this.x = x; this.upImg = upImg ; this.downImg = downImg; this.speed = speed; this.ctx = ctx; this.r = Math.random() *200 + 100; //随机低度+固定高度 } Pipe.prototype.draw = function(){ this.ctx.drawImage( this.upImg, this.x , this.r - 420 //管道图形的长度是420 ) this.ctx.drawImage( this.downImg, this.x , this.r +150 //管道中国建工业总群集团的留白是150px ) } Pipe.prototype.setCount = function( count,gap ){ Pipe.count = count; Pipe.gap = gap; //这里是这一次绘制的非常之处,出席了距离 } Pipe.prototype.update =function( dur ){ this.x = this.x + this.speed*dur; if(this.x <- 52){ //管道宽度52px this.x = this.x + Pipe.count * Pipe.gap; //无缝滚动 this.r = Math.random() *200 + 150; //切换后的管道必得再度设置二个冲天,给客户贰个新管道的错觉 } } 管道的构造函数及运动函数 图片 22//成立区域 var pipe1 = new Pipe(imgEls["pipe2"],imgEls["pipe1"],400, -0.1,ctx); var pipe2 = new Pipe(imgEls["pipe2"],imgEls["pipe1"],600, -0.1,ctx); var pipe3 = new Pipe(imgEls["pipe2"],imgEls["pipe1"],800, -0.1,ctx); var pipe4 = new Pipe(imgEls["pipe2"],imgEls["pipe1"],1000,-0.1,ctx); var pipe5 = new Pipe(imgEls["pipe2"],imgEls["pipe1"],1200,-0.1,ctx); //绘制区域 pipe1.update(dt); pipe1.draw(); pipe2.update(dt); pipe2.draw(); pipe3.update(dt); pipe3.draw(); pipe4.update(dt); pipe4.draw(); pipe5.update(dt); pipe5.draw(); pipe1.setCount(5,200); //设置管道数量和间隔 管道的绘图主要代码

到这一步大家的根本画面就制作出来了,是还是不是很简短呢O(∩_∩)O~

2.5 推断游戏是不是违犯禁令

图片 23 //大家改变一下主循环,设置贰个gameover为false来决定函数的实施//任何违法都会触发gameover=true; var gameover = false; if(bird.y < 0 || bird.y > 488 -45/2 ){ //遇到天和地 gameover = true ; } if(!gameover){ //若无结束游戏则持续玩乐 requestAnimationFrame(run); } 轻便判读gameover

  2. 碰着管道甘休游戏

图片 24//x和y到时候大家传入小鸟的运动轨迹,每便重绘管道都有咬定 Pipe.prototype.hitTest = function(x,y){ return (x > this.x && x < this.x + 52) //在管敬仲横向中间 &&(! (y >this.r && y < this.r +150)); //在管仲竖向中间 } 推断是或不是遭受管敬仲 图片 25 var gameover = false; gameover = gameover || pipe1.hitTest(bird.x ,bird.y); gameover = gameover || pipe2.hitTest(bird.x ,bird.y); gameover = gameover || pipe3.hitTest(bird.x ,bird.y); gameover = gameover || pipe4.hitTest(bird.x ,bird.y); gameover = gameover || pipe5.hitTest(bird.x ,bird.y); //逻辑终端 if(bird.y < 0 || bird.y > 488 -45/2 ){ gameover = true ; } if(!gameover){ requestAnimationFrame(run); } 主循环的决断标准构成

图片 26

到这一步大家的游玩产生的大半了,剩下的正是有的数码的匡正

主要要求纠正的八个点是碰撞的企图,因为我们全数的撞击都是比照小鸟图片的左上角总结的,那样就能够有不规范的主题材料,通过测量试验很轻巧将这些距离加减革新了

 

3.游戏的优化

 小鸟游戏的鸟儿在左右的历程中会随着点击,抬头飞翔,或投降冲锋,如何落成那几个效应呢?

 答案便是移动canvas 坐标系和挑选坐标系的角度  ctx.translate()和ctx.rotate();

 为了防范全部坐标系的共同体旋转运动

 须求在小鸟绘制函数Bird.prototype.draw里前面后端参加ctx.save() 和ctx.restore()来单独主宰小鸟画布

图片 27Bird.prototype.draw = function (){ this.ctx.save(); this.ctx.translate(this.x ,this.y); //坐标移动到小鸟的大旨点上 this.ctx.rotate((Math.PI /6) * this.speed / 0.3 ); //小鸟最大旋转30度,并乘机速度实时改换角度 this.ctx.drawImage( this.img,52*this.index,0,52,45, -52/2,-45/2,52,45 //这里相当的重大的有个别是,整个小鸟坐标系起先活动 ) this.ctx.restore(); } 参加小鸟旋转效果

理当如此最终不要忘记对管道碰撞的论断,在此间再改进贰次。

其实假使希图参与旋转效果,上贰遍的纠正没有须要,你会意识很多重复工。

终极做出的意义如下:

图片 28

 主体作用和逻辑已经全副落成。越来越多的效能能够自行增添。

 如若想协调集会演习一下,请点击游戏细化部分的链接下载相关质地和成套源码。

制作flappy bird(像素小鸟)全流程,canvasflappy flappy bird制作全流程: 一、前言 像素小鸟那些轻巧的游戏于二〇一四年在网络上爆红,游戏上...

全总源码

<!DOCTYPE html> <html> <head> <title>Flappy Bird</title> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <script type="text/javascript"> // Edit by xingoo // Fork on my github: var ctx; var cwidth = 400; var cheight = 600; var objects = []; var birdIndex = 0; var ver1 = 10; var ver2; var gravity = 2; var pipe_height = 200; var velocity = 10; var tid; var score = 0; var isScore = false; var birds = ["./images/0.gif","./images/1.gif","./images/2.gif"]; var back = new Background(0,0,400,600,"./images/bg.png"); var up_pipe = new UpPipe(0,0,100,200,"./images/pipe.png"); var down_pipe = new DownPipe(0,400,100,200,"./images/pipe.png"); var ground = new Background(0,550,400,200,"./images/ground.png"); var bird = new Bird(80,300,40,40,birds); objects.push(back); objects.push(up_pipe); objects.push(down_pipe); objects.push(ground); objects.push(bird); function UpPipe(x,y,width,height,img_src){ this.px = x; this.py = y; this.pwidth = width; this.pheight = height; this.img_src = img_src; this.draw = drawUpPipe; } function DownPipe(x,y,width,height,img_src){ this.px = x; this.py = y; this.pwidth = width; this.pheight = height; this.img_src = img_src; this.draw = drawDownPipe; } function drawUpPipe(){ var image = new Image(); image.src = this.img_src; ctx.drawImage(image,150,500,150,800,this.px,this.py,this.pwidth,this.pheight); } function drawDownPipe(){ var image = new Image(); image.src = this.img_src; ctx.drawImage(image,0,500,150,500,this.px,this.py,this.pwidth,this.pheight); } function Background(x,y,width,height,img_src){ this.bgx = x; this.bgy = y; this.bgwidth = width; this.bgheight = height; var image = new Image(); image.src = img_src; this.img = image; this.draw = drawbg; } function drawbg(){ ctx.drawImage(this.img,this.bgx,this.bgy,this.bgwidth,this.bgheight); } function Bird(x,y,width,height,img_srcs){ this.bx = x; this.by = y; this.bwidth = width; this.bheight = height; this.imgs = img_srcs; this.draw = drawbird; } function drawbird(){ birdIndex++; var image = new Image(); image.src = this.imgs[birdIndex%3]; ctx.drawImage(image,this.bx,this.by,this.bwidth,this.bheight); } function calculator(){ if(bird.by+bird.bheight>ground.bgy || ((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&( bird.by<up_pipe.py+up_pipe.pheight))|| ((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&( bird.by<up_pipe.py+up_pipe.pheight))|| ((bird.bx>down_pipe.px)&&(bird.by>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by<down_pipe.py+down_pipe.pheight))|| ((bird.bx>down_pipe.px)&&(bird.by+bird.bheight>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by+bird.bheight<down_pipe.py+down_pipe.pheight))){ clearInterval(tid); ctx.fillStyle = "rgb(255,255,255)"; ctx.font = "30px Accent"; ctx.fillText("You got "+score+"!",110,100) return; } ver2 = ver1+gravity; bird.by += (ver2+ver1)*0.5; if(up_pipe.px+up_pipe.pwidth>0){ up_pipe.px -= velocity; down_pipe.px -= velocity; }else{ up_pipe.px = 400; down_pipe.px = 400; up_pipe.pheight = 100+Math.random()*200; down_pipe.py = up_pipe.pheight+pipe_height; down_pipe.pheight = 600-down_pipe.py; isScore = true; } if(isScore && bird.bx>up_pipe.px+up_pipe.pwidth){ score += 1; isScore = false; if(score>0 && score%10 === 0){ velocity++; } } ctx.fillStyle = "rgb(255,255,255)"; ctx.font = "30px Accent"; if(score>0){ score%10!==0?ctx.fillText(score,180,100):ctx.fillText("Great!"+score,120,100); } } function drawall(){ ctx.clearRect(0,0,cwidth,cheight); var i; for(i=0;i<objects.length;i++){ objects[i].draw(); } calculator(); } function keyup(e){ var e = e||event; var currKey = e.keyCode||e.which||e.charCode; switch (currKey){ case 32: bird.by -= 80; break; } } function init(){ ctx = document.getElementById('canvas').getContext('2d'); document.onkeyup = keyup; drawall(); tid = setInterval(drawall,80); } </script> </head> <body onLoad="init();"> <canvas id="canvas" width="400" height="600" style="margin-left:200px;"> Your browser is not support canvas! </canvas> </body> </html>

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
<!DOCTYPE html>
<html>
<head>
    <title>Flappy Bird</title>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <script type="text/javascript">
        // Edit by xingoo
        // Fork on my github:https://github.com/xinghalo/CodeJS/tree/master/HTML5
        var ctx;
        var cwidth = 400;
        var cheight = 600;
        var objects = [];
        var birdIndex = 0;
        var ver1 = 10;
        var ver2;
        var gravity = 2;
        var pipe_height = 200;
        var velocity = 10;
        var tid;
        var score = 0;
        var isScore = false;
        var birds = ["./images/0.gif","./images/1.gif","./images/2.gif"];
        var back = new Background(0,0,400,600,"./images/bg.png");
        var up_pipe = new UpPipe(0,0,100,200,"./images/pipe.png");
        var down_pipe = new DownPipe(0,400,100,200,"./images/pipe.png");
        var ground = new Background(0,550,400,200,"./images/ground.png");
        var bird = new Bird(80,300,40,40,birds);
        objects.push(back);
        objects.push(up_pipe);
        objects.push(down_pipe);
        objects.push(ground);
        objects.push(bird);
        function UpPipe(x,y,width,height,img_src){
            this.px = x;
            this.py = y;
            this.pwidth = width;
            this.pheight = height;
            this.img_src = img_src;
            this.draw = drawUpPipe;
        }
        function DownPipe(x,y,width,height,img_src){
            this.px = x;
            this.py = y;
            this.pwidth = width;
            this.pheight = height;
            this.img_src = img_src;
            this.draw = drawDownPipe;
        }
        function drawUpPipe(){
            var image = new Image();
            image.src = this.img_src;
            ctx.drawImage(image,150,500,150,800,this.px,this.py,this.pwidth,this.pheight);
        }
        function drawDownPipe(){
            var image = new Image();
            image.src = this.img_src;
            ctx.drawImage(image,0,500,150,500,this.px,this.py,this.pwidth,this.pheight);
        }
        function Background(x,y,width,height,img_src){
            this.bgx = x;
            this.bgy = y;
            this.bgwidth = width;
            this.bgheight = height;
            var image = new Image();
            image.src = img_src;
            this.img = image;
            this.draw = drawbg;
        }
        function drawbg(){
            ctx.drawImage(this.img,this.bgx,this.bgy,this.bgwidth,this.bgheight);
        }
        function Bird(x,y,width,height,img_srcs){
            this.bx = x;
            this.by = y;
            this.bwidth = width;
            this.bheight = height;
            this.imgs = img_srcs;
            this.draw = drawbird;
        }
        function drawbird(){
            birdIndex++;
            var image = new Image();
            image.src = this.imgs[birdIndex%3];
            ctx.drawImage(image,this.bx,this.by,this.bwidth,this.bheight);
        }
        function calculator(){
            if(bird.by+bird.bheight>ground.bgy ||
                ((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&(    bird.by<up_pipe.py+up_pipe.pheight))||
                ((bird.bx+bird.bwidth>up_pipe.px)&&(bird.by>up_pipe.py)&&(bird.bx+bird.bwidth<up_pipe.px+up_pipe.pwidth)&&(    bird.by<up_pipe.py+up_pipe.pheight))||
                ((bird.bx>down_pipe.px)&&(bird.by>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by<down_pipe.py+down_pipe.pheight))||
                ((bird.bx>down_pipe.px)&&(bird.by+bird.bheight>down_pipe.py)&&(bird.bx<down_pipe.px+down_pipe.pwidth)&&(bird.by+bird.bheight<down_pipe.py+down_pipe.pheight))){
                clearInterval(tid);
                ctx.fillStyle = "rgb(255,255,255)";
                ctx.font = "30px Accent";
                ctx.fillText("You got "+score+"!",110,100)
                return;
            }
            ver2 = ver1+gravity;
            bird.by += (ver2+ver1)*0.5;
            if(up_pipe.px+up_pipe.pwidth>0){
                up_pipe.px -= velocity;
                down_pipe.px -= velocity;
            }else{
                up_pipe.px = 400;
                down_pipe.px = 400;
                up_pipe.pheight = 100+Math.random()*200;
                down_pipe.py = up_pipe.pheight+pipe_height;
                down_pipe.pheight = 600-down_pipe.py;
                isScore = true;
            }
            if(isScore && bird.bx>up_pipe.px+up_pipe.pwidth){
                score += 1;
                isScore = false;
                if(score>0 && score%10 === 0){
                    velocity++;
                }
            }
            ctx.fillStyle = "rgb(255,255,255)";
            ctx.font = "30px Accent";
            if(score>0){
                score%10!==0?ctx.fillText(score,180,100):ctx.fillText("Great!"+score,120,100);
            }
        }
        function drawall(){
            ctx.clearRect(0,0,cwidth,cheight);
            var i;
            for(i=0;i<objects.length;i++){
                objects[i].draw();
            }
            calculator();
        }
        function keyup(e){
            var e = e||event;
               var currKey = e.keyCode||e.which||e.charCode;
               switch (currKey){
                case 32:
                    bird.by -= 80;
                    break;
            }
        }    
        function init(){
            ctx = document.getElementById('canvas').getContext('2d');
            document.onkeyup = keyup;
            drawall();
            tid = setInterval(drawall,80);
        }
    </script>
</head>
<body onLoad="init();">
<canvas id="canvas" width="400" height="600" style="margin-left:200px;">
    Your browser is not support canvas!
</canvas>
</body>
</html>

总结

在上学玩乐开荒的时候,作者猛然驰念起大学的大要。那时候很疑心,学计算机学什么物理,后来再触及游戏支付才晓得,未有一定的大要知识,根本不也许模拟游戏中的种种场景。

而经过那么些大约的小游戏,也捡起来了众多旧文化。

参考

【1】:Canvas参谋手册

【2】:《HTML5游玩支付》

【3】:EdisonChou的FlappyBird

2 赞 6 收藏 评论

图片 29

本文由云顶娱乐手机官网发布于前端开发,转载请注明出处:[Canvas前端游戏支付]——FlappyBird详解

关键词: