Canvas前端游戏开发

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

2016/01/03 · HTML5 ·
Canvas

原来的小说出处: xingoo   

一直想协调做点小东西,直到眼下看了本《HTML5戏耍支付》,才打听游戏支付中的一丢丢入门知识。

本篇就针对学习的几个样例,自个儿入手实践,做了个FlappyBird,源码共享在度盘 ;也足以参考Canvas前端游戏开发。github,里面有更加多的游玩样例。

直白想协调做点小东西,直到近日看了本《HTML伍戏耍开发》,才领会游戏支付中的一丝丝入门知识。

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

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

三、通过Canvas成分完毕高级图像操作

游戏截图

图片 1

图片 2

娱乐截图

图片 3

图片 4

平素想协调做点小东西,直到如今看了本《HTML5娱乐开发》,才打听游戏支付中的一丢丢入门知识。本篇就本着学习的多少个样例,自个儿出手实践,做了个FlappyBird,源码共享在度盘
;也得以参照github,里面有愈来愈多的游玩样例。

HTML5之Canvas

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

 

//假如想要使用canvas,首先须求获得上下文对象: ctx =
document.getElementById(‘canvas’).getContext(‘二d’);
//然后使用这些ctx绘制图形

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

在cavas每种绘制都以单身的操作。比如下图的四个绘制图形,第四个会以遮盖的格局绘制,由此制图图形的相继就呈现尤其人命关天了。

图片 5

HTML5之Canvas

Canvas是Html5中用于绘图的因素,它能够绘制各个图片,比如长方形,多边形,圆形等等。假如想要掌握Canvas的选择能够参考:

 

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

在cavas每一个绘制都以单身的操作。比如下图的五个绘制图形,第3个会以遮盖的花样绘制,因而绘图图形的相继就呈现十三分最重要了。

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

图片 7

地点的图样中为了收缩图片财富的伸手数量,把广大的要素放在了八个图片中,此时就必要通过裁剪的情势,获取钦点的图样成分。

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

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

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

图片 8

地点的图形中为了收缩图片能源的请求数量,把广大的要素放在了一个图纸中,此时就须要经过裁剪的艺术,获取钦命的图纸成分。

图片 9

上1篇小说演示了什么样行使Canvas落成二当中坚的图像动画。这么些例子很简短,同样的功力通过改动I名爵或DIV等专业HTML成分的部分性质,照样也能够私降低成。上边大家就来演示一下画布成分的尖端应用,体现一下它的的确威力。

FlappyBird原理分析

实则这么些游戏很简单,一张图就能够看懂个中的神妙:

图片 10

中间背景和本地是不动的。

鸟类唯有上和下八个动作,可以经过操纵小鸟的y坐标达成。

上下的管仲只会向左移动,为了简单达成,游戏中一个画面仅仅会产出1些管仲,那样当管敬仲移出左侧的背景框,就机关把管敬仲放在最左边!

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()方法,在必然间隔时间内,执行2回重绘

重绘的时候会先去掉画面中的全部因素,然后依据新的因素的坐标一次绘制图形,那样就会并发活动的功效。

FlappyBird原理分析

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

图片 11

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

鸟儿唯有上和下四个动作,能够通过操纵小鸟的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共就那多少个要素,因而把她们都放入贰个Objects数组中,通过setInteral()方法,在一定间隔时间内,执行壹遍重绘

重绘的时候会先去掉画面中的全体因素,然后根据新的因素的坐标三回绘制图形,那样就会出现活动的成效。

图片 12

率先,照旧准备几个HTML页面。

依傍小鸟引力

出于那些游乐不关乎小鸟横向的活动,由此只要模拟出小鸟下降的动作以及上升的动作就足以了。

图片 13

上升:这几个很简短,只要把小鸟的y坐标减去肯定的值就足以了

下落:其实引力不须要利用gt^2来效仿,能够简单的钦赐五个变量,v壹和gravity,那四个变量与setInterval()中的时间一起作用,就能模拟重力。

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

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

仿照小鸟引力

鉴于这么些游戏不涉及小鸟横向的运动,因而一旦模拟出小鸟下降的动作以及上涨的动作就能够了。

图片 14

上升:这些很不难,只要把小鸟的y坐标减去肯定的值就足以了

下落:其实重力不需求使用gt^贰来效仿,能够总结的内定多个变量,v一和gravity,那三个变量与setInterval()中的时间同步成效,就能模仿重力。

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

HTML5之Canvas

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

碰撞检验

游玩中型小型鸟遭受管敬仲恐怕地面都会算游戏甘休:

图片 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

假定满足那三个标准化,即使游戏截止,会消除循环以及提示游戏甘休新闻。

碰撞检查测试

打闹中型小型鸟蒙受管敬仲或然地面都会算游戏截止:

图片 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

倘若满意那四个规格,固然游戏截止,会化解循环以及提示游戏截止音信。

Canvas是Html5中用于绘图的成分,它能够绘制各个图片,比如星型,多边形,圆形等等。假设想要驾驭Canvas的行使能够参考:
http://www.w3school.com.cn/tags/html\_ref\_canvas.asp

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

分数总结

分数的猜测与碰撞检查测试类似,设置2个开关,当管敬仲重新出现时,设置为true。当分值加一时,设置为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个开关,当管仲重新现身时,设置为true。当分值加一时,设置为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。

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

以下是 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>

成套源码

图片 17图片 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

在cavas各样绘制都以单身的操作。比如下图的五个绘制图形,第二个会以覆盖的样式绘制,由此制图图形的1一就突显相当关键了。

 // 每秒多少帧  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);  } 

总结

在就学玩乐支付的时候,小编忽然牵记起大学的大体。当时很困惑,学电脑学如何物理,后来再接触游戏支付才知晓,未有一定的物理知识,根本不可能模拟游戏中的各种场景。

而因而那几个简单的小游戏,也捡起来了许多旧文化。

总结

在上学玩乐开发的时候,小编恍然惦念起高校的情理。当时很吸引,学电脑学什么物理,后来再接触游戏支付才晓得,未有必然的情理知识,根本无法模拟游戏中的各样场景。

而经过那一个大约的小游戏,也捡起来了好多旧文化。

图片 19

跟后面壹样,这么些JavaScript文件先定义了某个全局变量。

参考

【1】:Canvas参考手册

【2】:《HTML5戏耍开发》

【3】:EdisonChou的FlappyBird

2 赞 6 收藏
评论

图片 20

参考

【1】:Canvas参考手册

【2】:《HTML伍游玩支付》

【3】:EdisonChou的FlappyBird

canvas之drawImage()

◆ 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个api中,内定Image对象,然后给出绘制图片的x,y坐标以及宽度和中度即可。第三个api中,第一组x,y,width,height则钦点了裁剪图片的坐标尺寸,那在接纳多成分的矢量图时很常用。比如:


HALFCANVASWIDTH:画布宽度的一半,用于配合HALFIMAGEDIMENSION使用,以便在画布上居中图像

图片 21


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

位置的图片中为了收缩图片资源的恳求数量,把广大的要素放在了一个图纸中,此时就需求通过裁剪的章程,获取钦点的图样成分。

◆ currentFunction:渲染循环(参见上壹篇文章)中运维的函数

网站地图xml地图