>

像素小鸟,Canvas前端游戏支付

- 编辑:至尊游戏网站 -

像素小鸟,Canvas前端游戏支付

[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。

 四、游戏完结:

现行反革命结合脑图来日趋落实大家的22日游。

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.add伊芙ntListener("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制作全流程: 一、前言 像素小鸟那几个大致的游戏于2016年在网络上爆红,游戏上...

全总源码

<!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>

总结

在攻读玩乐支付的时候,笔者蓦地怀恋起大学的概略。那时很纳闷,学Computer学怎么着物理,后来再接触游戏开荒才精晓,未有一定的概况知识,根本不能模拟游戏中的种种场景。

而经过这几个轻松的小游戏,也捡起来了广大旧文化。

参考

【1】:Canvas参谋手册

【2】:《HTML5玩耍支付》

【3】:EdisonChou的FlappyBird

2 赞 6 收藏 评论

图片 29

本文由设计建站发布,转载请注明来源:像素小鸟,Canvas前端游戏支付