Canvas前端游戏开发

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

2016/01/03 · HTML5 ·
Canvas

原来的小说出处: xingoo   

一贯想本人做点小东西,直到眼前看了本《HTML5游乐支付》,才打听游戏支付中的一小点入门知识。

本篇就对准学习的几个样例,自身出手实践,做了个FlappyBird,源码共享在度盘 ;也足以参考github,里面有越多的娱乐样例。

作者:Xingoo
初稿地址:http://www.cnblogs.com/xing901022/p/5094550.html

直白想自身做点小东西,直到如今看了本《HTML5游戏支付》,才打听游戏支付中的一丢丢入门知识。

本篇就对准学习的几个样例,本人入手实践,做了个FlappyBird,源码共享在度盘 ;也足以参考github,里面有更加多的娱乐样例。

③ 、通过Canvas成分达成高级图像操作

打闹截图

yzc88 1

yzc88 2

平素想本人做点小东西,直到眼前看了本《HTML5嬉戏支付》,才打听游戏开发中的一丝丝入门知识。本篇就对准学习的多少个样例,本身入手实践,做了个FlappyBird,源码共享在度盘
;也能够参见github,里面有越多的玩耍样例。

二5日游截图

yzc88 3

yzc88 4

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每一个绘制都是独自的操作。比如下图的五个绘制图形,第四个会以遮盖的花样绘制,由此绘图图形的依次就展现分外珍视了。

yzc88 5

游玩截图

HTML5之Canvas

Canvas是Html5中用于绘图的要素,它可以绘制各类图片,比如圆锥形,多边形,圆形等等。若是想要掌握Canvas的使用能够参照:

 

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

在cavas每种绘制都以独自的操作。比如下图的八个绘制图形,第一个会以覆盖的款式绘制,因而绘制图形的依次Canvas前端游戏开发。就展现11分至关心珍视要了。

yzc88 6

那篇作品将带领大家学习应用JavaScript和Canvas成分操作图像了两种差别的措施,这一个主题在Canvas成分出现之前是不恐怕的事体。

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则钦赐了裁剪图片的坐标尺寸,那在使用多成分的矢量图时很常用。比如:

yzc88 7

上边的图样中为了削减图片能源的伸手数量,把无数的成分放在了多少个图纸中,此时就需求经过裁剪的情势,获取钦命的图形成分。

yzc88 8

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);

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

第1个api中,第1组x,y,width,height则内定了裁剪图片的坐标尺寸,这在使用多成分的矢量图时很常用。比如:

yzc88 9

上边包车型客车图样中为了削减图片财富的呼吁数量,把无数的成分放在了3个图纸中,此时就供给经过裁剪的法子,获取内定的图形成分。

上一篇小说演示了怎么利用Canvas实现二个大旨的图像动画。那个例子很简短,同样的法力通过改动IMG或DIV等专业HTML成分的一些性能,照样也能够专擅达成。上面我们就来演示一下画布成分的高等应用,体现一下它的确实威力。

FlappyBird原理分析

事实上这么些游乐很简短,一张图就能够看懂个中的奥妙:

yzc88 10

当中背景和地面是不动的。

鸟儿只有上和下五个动作,能够透过操纵小鸟的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()方法,在必然间隔时间内,执行一回重绘

重绘的时候会先解决画面中的全部因素,然后遵照新的要素的坐标一回绘制图形,那样就会产出活动的职能。

yzc88 11

Flappy伯德原理分析

其实这些游乐很简短,一张图就能够看懂个中的微妙:

yzc88 12

内部背景和当地是不动的。

鸟类唯有上和下八个动作,可以因此操纵小鸟的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;
            }

非常的粗略吗!

出于该游戏一共就那多少个要素,因而把她们都放入一个Objects数组中,通过setInteral()方法,在肯定间隔时间内,执行贰遍重绘

重绘的时候会先消除画面中的全数因素,然后依据新的要素的坐标三遍绘制图形,那样就会冒出活动的职能。

第贰,依旧准备一个HTML页面。

模仿小鸟重力

是因为那一个游戏不涉及小鸟横向的移动,由此一旦模拟出小鸟下降的动作以及回升的动作就足以了。

yzc88 13

上升:那些相当的粗略,只要把小鸟的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;

HTML5之Canvas

模仿小鸟重力

由于这些游戏不关乎小鸟横向的活动,由此一旦模拟出小鸟下跌的动作以及上升的动作就足以了。

yzc88 14

上升:这么些相当的粗略,只要把小鸟的y坐标减去肯定的值就足以了

下落:其实引力不须要使用gt^2来模拟,能够总结的钦点七个变量,v1和gravity,这八个变量与setInterval()中的时间共同作用,就能模仿动力。

ver2 = ver1+gravity;
bird.by += (ver2+ver1)*0.5;
  <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN">   <html lang="en">      <head>         <title>JavaScript Platformer 2</title>         <script type="text/javascript" src="jsplatformer2.js"></script>         <style type="text/css">            body { font-family: Arial,Helvetica,sans-serif;}         </style>      </head>     <body>        <p>           <a href="http://www.brighthub.com/internet/web-development/articles/38364.aspx">              Game Development with Javascript and the canvas element           </a>        </p>        <canvas id="canvas" width="600" height="400">           <p>Your browser does not support the canvas element.</p>        </canvas>        <br />        <button onclick="currentFunction=alpha;">Change Alpha</button>        <button onclick="currentFunction=shear;">Shear</button>        <button onclick="currentFunction=scale;">Scale</button>        <button onclick="currentFunction=rotate;">Rotate</button>     </body>  </html> 

碰撞检查和测试

游玩中型小型鸟遭遇管仲只怕地点都会算游戏甘休:

yzc88 15

其中条件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

假定满意那七个条件,尽管游戏甘休,会去掉循环以及提示游戏甘休新闻。

Canvas是Html5中用于绘图的成分,它能够绘制各样图片,比如纺锤形,多边形,圆形等等。尽管想要掌握Canvas的施用能够参考:
http://www.w3school.com.cn/tags/html\_ref\_canvas.asp

碰撞检查和测试

娱乐中型小型鸟遇到管仲只怕当地都会算游戏截至:

yzc88 16

其中条件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))

条件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

如果满足这四个规范,即便游戏甘休,会消除循环以及提示游戏停止音信。

与上个一例子的HTML页面比较,唯一的界别正是添加了有的按钮。单击那么些按钮,就会安装currentFunction变量(稍后介绍)的值,用以改变在渲染循环中运作的函数。

分数总括

分数的总结与碰撞检查和测试类似,设置2个开关,当管仲重新出现时,设置为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。

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

分数总计

分数的持筹握算与碰撞检查和测试类似,设置二个开关,当管敬仲重新出现时,设置为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,速度+1。

以下是 jsplatformer2.js 的代码。

漫天源码

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

在cavas每一种绘制都以单独的操作。比如下图的三个绘制图形,第3个会以遮盖的款式绘制,由此绘制图形的次第就显得非凡主要了。

整整源码

yzc88 17yzc88 18

<!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 = ["..gif","..gif","..gif"];
        var back = new Background(0,0,400,600,".g.png");
        var up_pipe = new UpPipe(0,0,100,200,".pipe.png");
        var down_pipe = new DownPipe(0,400,100,200,".pipe.png");
        var ground = new Background(0,550,400,200,".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>

View Code

 // 每秒多少帧  const FPS = 30;  const SECONDSBETWEENFRAMES = 1 / FPS;  const HALFIMAGEDIMENSION = 75;  const HALFCANVASWIDTH = 300;  const HALFCANVASHEIGHT = 200;  var image = new Image();  image.src = "jsplatformer2-smiley.jpg"; //还是第一个例子中的图像  var canvas = null;  var context2D = null;  var currentFunction = null;  var currentTime = 0;  var sineWave = 0;   window.onload = init;   function init()  {     canvas = document.getElementById('canvas');     context2D = canvas.getContext('2d');     setInterval(draw, SECONDSBETWEENFRAMES * 1000);     currentFunction = scale;  }   function draw()  {      currentTime += SECONDSBETWEENFRAMES;      sineWave = (Math.sin(currentTime) + 1) / 2;       context2D.clearRect(0, 0, canvas.width, canvas.height);       context2D.save();       context2D.translate(HALFCANVASWIDTH - HALFIMAGEDIMENSION, HALFCANVASHEIGHT - HALFIMAGEDIMENSION);       currentFunction();       context2D.drawImage(image, 0, 0);       context2D.restore();  }   function alpha()  {      context2D.globalAlpha = sineWave;  }   function shear()  {      context2D.transform(1, 0, (sineWave - 0.5), 1, 0, 0);  }   function scale()  {      context2D.translate(HALFIMAGEDIMENSION * (1 - sineWave), HALFIMAGEDIMENSION * (1 - sineWave));      context2D.scale(sineWave, sineWave);  }   function rotate()  {      context2D.translate(HALFIMAGEDIMENSION, HALFIMAGEDIMENSION);      context2D.rotate(sineWave * Math.PI * 2);      context2D.translate(-HALFIMAGEDIMENSION, -HALFIMAGEDIMENSION);  } 

总结

在求学玩乐支付的时候,笔者豁然挂念起大学的大体。当时很疑心,学电脑学什么物理,后来再接触游戏支付才通晓,没有一定的物理知识,根本无法模拟游戏中的种种场景。

而透过那些大致的小游戏,也捡起来了累累旧文化。

yzc88 19

总结

在上学玩乐开发的时候,小编突然怀念起高校的物理。当时很迷惑,学电脑学什么物理,后来再接触游戏支付才清楚,没有必然的物理知识,根本不能够模拟游戏中的种种场景。

而透过这一个简单的小游戏,也捡起来了众多旧文化。

前边面一样,那些JavaScript文件先定义了部分全局变量。

参考

【1】:Canvas参考手册

【2】:《HTML5娱乐开发》

【3】:EdisonChou的FlappyBird

2 赞 6 收藏
评论

yzc88 20

canvas之drawImage()

参考

【1】:Canvas参考手册

【2】:《HTML5嬉戏支付》

【3】:EdisonChou的FlappyBird

◆ FPS:每秒多少帧

本篇的嬉戏支付中,首要使用的是依照图片绘制的api:drawImage(),它有四个基本的采取办法:

◆ SECONDSBETWEENFRAMES:两帧之间距离的秒数(FPS的倒数)

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);


HALFIMAGEDIMENSION:要绘制图像的小幅度/中度的1/2,用于把图像定位到画布的中央点

第四个api中,钦命Image对象,然后给出绘制图片的x,y坐标以及宽度和高度即可。第四个api中,第1组x,y,width,height则内定了裁剪图片的坐标尺寸,那在利用多成分的矢量图时很常用。比如:


HALFCANVASWIDTH:画布宽度的二分之一,用于合作HALFIMAGEDIMENSION使用,以便在画布上居中图像

yzc88 21


HALFCANVASHEIGHT:画布中度的4/8,用于合营HALFIMAGEDIMENSION使用,以便在画布上居中图像

上面包车型客车图纸中为了削减图片财富的乞求数量,把无数的成分放在了一个图纸中,此时就须要经过裁剪的章程,获取钦赐的图片成分。

◆ currentFunction:渲染循环(参见上一篇小说)中运作的函数

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图