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
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
|
---
title: 基本的动画
slug: Web/API/Canvas_API/Tutorial/Basic_animations
tags:
- Canvas
- HTML5
- 动画
- 图像
- 教程
- 进阶
translation_of: Web/API/Canvas_API/Tutorial/Basic_animations
---
<div>{{CanvasSidebar}} {{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}</div>
<div class="summary">
<p>由于我们是用 JavaScript 去操控 {{HTMLElement("canvas")}} 对象,这样要实现一些交互动画也是相当容易的。在本章中,我们将看看如何做一些基本的动画。</p>
</div>
<p>可能最大的限制就是图像一旦绘制出来,它就是一直保持那样了。如果需要移动它,我们不得不对所有东西(包括之前的)进行重绘。重绘是相当费时的,而且性能很依赖于电脑的速度。</p>
<h2 id="Basic_animation_steps" name="Basic_animation_steps">动画的基本步骤</h2>
<p>你可以通过以下的步骤来画出一帧:</p>
<ol>
<li><strong>清空 canvas</strong><br>
除非接下来要画的内容会完全充满 canvas (例如背景图),否则你需要清空所有。最简单的做法就是用 <code>clearRect</code> 方法。</li>
<li><strong>保存 canvas 状态</strong><br>
如果你要改变一些会改变 canvas 状态的设置(样式,变形之类的),又要在每画一帧之时都是原始状态的话,你需要先保存一下。</li>
<li><strong>绘制动画图形(animated shapes)</strong><br>
这一步才是重绘动画帧。</li>
<li><strong>恢复 canvas 状态</strong><br>
如果已经保存了 canvas 的状态,可以先恢复它,然后重绘下一帧。</li>
</ol>
<h2 id="Controlling_an_animation" name="Controlling_an_animation">操控动画 Controlling an animation</h2>
<p>在 canvas 上绘制内容是用 canvas 提供的或者自定义的方法,而通常,我们仅仅在脚本执行结束后才能看见结果,比如说,在 for 循环里面做完成动画是不太可能的。</p>
<p>因此, 为了实现动画,我们需要一些可以定时执行重绘的方法。有两种方法可以实现这样的动画操控。首先可以通过 <code>setInterval</code> 和 <code>setTimeout</code> 方法来控制在设定的时间点上执行重绘。</p>
<h3 id="有安排的更新画布_Scheduled_updates"><strong>有安排的更新画布 </strong>Scheduled updates</h3>
<p>首先,可以用{{domxref("window.setInterval()")}}, {{domxref("window.setTimeout()")}},和{{domxref("window.requestAnimationFrame()")}}来设定定期执行一个指定函数。</p>
<dl>
<dt>{{domxref("WindowTimers.setInterval", "setInterval(function, delay)")}}</dt>
<dd>当设定好间隔时间后,function会定期执行。</dd>
<dt>{{domxref("WindowTimers.setTimeout", "setTimeout(function, delay)")}}</dt>
<dt>在设定好的时间之后执行函数</dt>
<dd></dd>
<dt>{{domxref("Window.requestAnimationFrame()", "requestAnimationFrame(callback)")}}</dt>
<dd>告诉浏览器你希望执行一个动画,并在重绘之前,请求浏览器执行一个特定的函数来更新动画。</dd>
</dl>
<p>如果你并不需要与用户互动,你可以使用setInterval()方法,它就可以定期执行指定代码。如果我们需要做一个游戏,我们可以使用键盘或者鼠标事件配合上setTimeout()方法来实现。通过设置事件监听,我们可以捕捉用户的交互,并执行相应的动作。</p>
<div class="note">
<p>下面的例子,采用 {{domxref("window.requestAnimationFrame()")}}实现动画效果。这个方法提供了更加平缓并更加有效率的方式来执行动画,当系统准备好了重绘条件的时候,才调用绘制动画帧。一般每秒钟回调函数执行60次,也有可能会被降低。想要了解更多关于动画循环的信息,尤其是游戏,可以在<a href="https://developer.mozilla.org/zh-CN/docs/Games">Game development zone</a> 参考这篇文章 <a href="https://developer.mozilla.org/zh-CN/docs/Games/Anatomy">Anatomy of a video game</a>。</p>
</div>
<h2 id="太阳系的动画">太阳系的动画</h2>
<p>这个例子里面,我会做一个小型的太阳系模拟动画。</p>
<pre class="brush: js">var sun = new Image();
var moon = new Image();
var earth = new Image();
function init(){
sun.src = 'https://mdn.mozillademos.org/files/1456/Canvas_sun.png';
moon.src = 'https://mdn.mozillademos.org/files/1443/Canvas_moon.png';
earth.src = 'https://mdn.mozillademos.org/files/1429/Canvas_earth.png';
window.requestAnimationFrame(draw);
}
function draw() {
var ctx = document.getElementById('canvas').getContext('2d');
ctx.globalCompositeOperation = 'destination-over';
ctx.clearRect(0,0,300,300); // clear canvas
ctx.fillStyle = 'rgba(0,0,0,0.4)';
ctx.strokeStyle = 'rgba(0,153,255,0.4)';
ctx.save();
ctx.translate(150,150);
// Earth
var time = new Date();
ctx.rotate( ((2*Math.PI)/60)*time.getSeconds() + ((2*Math.PI)/60000)*time.getMilliseconds() );
ctx.translate(105,0);
ctx.fillRect(0,-12,50,24); // Shadow
ctx.drawImage(earth,-12,-12);
// Moon
ctx.save();
ctx.rotate( ((2*Math.PI)/6)*time.getSeconds() + ((2*Math.PI)/6000)*time.getMilliseconds() );
ctx.translate(0,28.5);
ctx.drawImage(moon,-3.5,-3.5);
ctx.restore();
ctx.restore();
ctx.beginPath();
ctx.arc(150,150,105,0,Math.PI*2,false); // Earth orbit
ctx.stroke();
ctx.drawImage(sun,0,0,300,300);
window.requestAnimationFrame(draw);
}
init();
</pre>
<div class="hidden">
<pre class="brush: html"><canvas id="canvas" width="300" height="300"></canvas></pre>
</div>
<p>{{EmbedLiveSample("太阳系的动画", "310", "310", "https://mdn.mozillademos.org/files/202/Canvas_animation1.png")}}</p>
<h2 id="动画时钟">动画时钟</h2>
<p>这个例子实现一个动态时钟, 可以显示当前时间。</p>
<pre class="brush: js">function clock(){
var now = new Date();
var ctx = document.getElementById('canvas').getContext('2d');
ctx.save();
ctx.clearRect(0,0,150,150);
ctx.translate(75,75);
ctx.scale(0.4,0.4);
ctx.rotate(-Math.PI/2);
ctx.strokeStyle = "black";
ctx.fillStyle = "white";
ctx.lineWidth = 8;
ctx.lineCap = "round";
// Hour marks
ctx.save();
for (var i=0;i<12;i++){
ctx.beginPath();
ctx.rotate(Math.PI/6);
ctx.moveTo(100,0);
ctx.lineTo(120,0);
ctx.stroke();
}
ctx.restore();
// Minute marks
ctx.save();
ctx.lineWidth = 5;
for (i=0;i<60;i++){
if (i%5!=0) {
ctx.beginPath();
ctx.moveTo(117,0);
ctx.lineTo(120,0);
ctx.stroke();
}
ctx.rotate(Math.PI/30);
}
ctx.restore();
var sec = now.getSeconds();
var min = now.getMinutes();
var hr = now.getHours();
hr = hr>=12 ? hr-12 : hr;
ctx.fillStyle = "black";
// write Hours
ctx.save();
ctx.rotate( hr*(Math.PI/6) + (Math.PI/360)*min + (Math.PI/21600)*sec )
ctx.lineWidth = 14;
ctx.beginPath();
ctx.moveTo(-20,0);
ctx.lineTo(80,0);
ctx.stroke();
ctx.restore();
// write Minutes
ctx.save();
ctx.rotate( (Math.PI/30)*min + (Math.PI/1800)*sec )
ctx.lineWidth = 10;
ctx.beginPath();
ctx.moveTo(-28,0);
ctx.lineTo(112,0);
ctx.stroke();
ctx.restore();
// Write seconds
ctx.save();
ctx.rotate(sec * Math.PI/30);
ctx.strokeStyle = "#D40000";
ctx.fillStyle = "#D40000";
ctx.lineWidth = 6;
ctx.beginPath();
ctx.moveTo(-30,0);
ctx.lineTo(83,0);
ctx.stroke();
ctx.beginPath();
ctx.arc(0,0,10,0,Math.PI*2,true);
ctx.fill();
ctx.beginPath();
ctx.arc(95,0,10,0,Math.PI*2,true);
ctx.stroke();
ctx.fillStyle = "rgba(0,0,0,0)";
ctx.arc(0,0,3,0,Math.PI*2,true);
ctx.fill();
ctx.restore();
ctx.beginPath();
ctx.lineWidth = 14;
ctx.strokeStyle = '#325FA2';
ctx.arc(0,0,142,0,Math.PI*2,true);
ctx.stroke();
ctx.restore();
window.requestAnimationFrame(clock);
}
window.requestAnimationFrame(clock);
</pre>
<div class="hidden">
<pre class="brush: html"><canvas id="canvas" width="150" height="150"></canvas></pre>
</div>
<p>{{EmbedLiveSample("动画时钟", "180", "180", "https://mdn.mozillademos.org/files/203/Canvas_animation2.png")}}</p>
<h2 id="循环全景照片">循环全景照片</h2>
<p>在这个例子中,会有一个自左向右滑动的全景图。我们使用了在维基百科中找到的<a href="https://mdn.mozillademos.org/files/4553/Capitan_Meadows,_Yosemite_National_Park.jpg">尤塞米提国家公园的图片</a>,当然你可以随意找一张任何尺寸大于canvas的图片。</p>
<pre class="brush: js">var img = new Image();
// User Variables - customize these to change the image being scrolled, its
// direction, and the speed.
img.src = 'https://mdn.mozillademos.org/files/4553/Capitan_Meadows,_Yosemite_National_Park.jpg';
var CanvasXSize = 800;
var CanvasYSize = 200;
var speed = 30; // lower is faster
var scale = 1.05;
var y = -4.5; // vertical offset
// Main program
var dx = 0.75;
var imgW;
var imgH;
var x = 0;
var clearX;
var clearY;
var ctx;
img.onload = function() {
imgW = img.width * scale;
imgH = img.height * scale;
if (imgW > CanvasXSize) {
// image larger than canvas
x = CanvasXSize - imgW;
}
if (imgW > CanvasXSize) {
// image width larger than canvas
clearX = imgW;
} else {
clearX = CanvasXSize;
}
if (imgH > CanvasYSize) {
// image height larger than canvas
clearY = imgH;
} else {
clearY = CanvasYSize;
}
// get canvas context
ctx = document.getElementById('canvas').getContext('2d');
// set refresh rate
return setInterval(draw, speed);
}
function draw() {
ctx.clearRect(0, 0, clearX, clearY); // clear the canvas
// if image is <= Canvas Size
if (imgW <= CanvasXSize) {
// reset, start from beginning
if (x > CanvasXSize) {
x = -imgW + x;
}
// draw additional image1
if (x > 0) {
ctx.drawImage(img, -imgW + x, y, imgW, imgH);
}
// draw additional image2
if (x - imgW > 0) {
ctx.drawImage(img, -imgW * 2 + x, y, imgW, imgH);
}
}
// image is > Canvas Size
else {
// reset, start from beginning
if (x > (CanvasXSize)) {
x = CanvasXSize - imgW;
}
// draw aditional image
if (x > (CanvasXSize-imgW)) {
ctx.drawImage(img, x - imgW + 1, y, imgW, imgH);
}
}
// draw image
ctx.drawImage(img, x, y,imgW, imgH);
// amount to move
x += dx;
}</pre>
<div class="hidden">
<pre class="brush: html"><canvas id="canvas" width="800" height="200"></canvas></pre>
</div>
<p>下方就是是图片在其中滑动的 {{HTMLElement("canvas")}}。需要注意的是这里定义的width和height必须与JavaScript代码中的变量值<code>CanvasXZSize</code>和<code>CanvasYSize</code>保持一致。 </p>
<pre><canvas id="canvas" width="800" height="200"></canvas></pre>
<p>{{EmbedLiveSample("循环全景照片", "830", "230")}}</p>
<h2 id="鼠标追踪动画">鼠标追踪动画</h2>
<pre class="brush: html"><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<script>
var cn;
//= document.getElementById('cw');
var c;
var u = 10;
const m = {
x: innerWidth / 2,
y: innerHeight / 2
};
window.onmousemove = function(e) {
m.x = e.clientX;
m.y = e.clientY;
}
function gc() {
var s = "0123456789ABCDEF";
var c = "#";
for (var i = 0; i < 6; i++) {
c += s[Math.ceil(Math.random() * 15)]
}
return c
}
var a = [];
window.onload = function myfunction() {
cn = document.getElementById('cw');
c = cn.getContext('2d');
for (var i = 0; i < 10; i++) {
var r = 30;
var x = Math.random() * (innerWidth - 2 * r) + r;
var y = Math.random() * (innerHeight - 2 * r) + r;
var t = new ob(innerWidth / 2,innerHeight / 2,5,"red",Math.random() * 200 + 20,2);
a.push(t);
}
//cn.style.backgroundColor = "#700bc8";
c.lineWidth = "2";
c.globalAlpha = 0.5;
resize();
anim()
}
window.onresize = function() {
resize();
}
function resize() {
cn.height = innerHeight;
cn.width = innerWidth;
for (var i = 0; i < 101; i++) {
var r = 30;
var x = Math.random() * (innerWidth - 2 * r) + r;
var y = Math.random() * (innerHeight - 2 * r) + r;
a[i] = new ob(innerWidth / 2,innerHeight / 2,4,gc(),Math.random() * 200 + 20,0.02);
}
// a[0] = new ob(innerWidth / 2, innerHeight / 2, 40, "red", 0.05, 0.05);
//a[0].dr();
}
function ob(x, y, r, cc, o, s) {
this.x = x;
this.y = y;
this.r = r;
this.cc = cc;
this.theta = Math.random() * Math.PI * 2;
this.s = s;
this.o = o;
this.t = Math.random() * 150;
this.o = o;
this.dr = function() {
const ls = {
x: this.x,
y: this.y
};
this.theta += this.s;
this.x = m.x + Math.cos(this.theta) * this.t;
this.y = m.y + Math.sin(this.theta) * this.t;
c.beginPath();
c.lineWidth = this.r;
c.strokeStyle = this.cc;
c.moveTo(ls.x, ls.y);
c.lineTo(this.x, this.y);
c.stroke();
c.closePath();
}
}
function anim() {
requestAnimationFrame(anim);
c.fillStyle = "rgba(0,0,0,0.05)";
c.fillRect(0, 0, cn.width, cn.height);
a.forEach(function(e, i) {
e.dr();
});
}
</script>
<style>
#cw {
position: fixed;
z-index: -1;
}
body {
margin: 0;
padding: 0;
background-color: rgba(0,0,0,0.05);
}
</style>
</head>
<body>
<canvas id="cw"></canvas>
qwerewr
</body>
</html>
</pre>
<h5 id="OutPut">OutPut</h5>
<table class="standard-table">
<tbody>
<tr>
<td>
<p><a href="https://kunalverma94.github.io/gallery/gags/beyblade.html"><img alt="beyblade" src="https://kunalverma94.github.io/gallery/beyblade.jpg" style="height: 298px; width: 399px;"></a></p>
</td>
</tr>
</tbody>
</table>
<h2 id="Snake_Game">Snake Game</h2>
<pre class="brush: html"><!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Nokia 1100:snake..Member berries</title>
</head>
<body>
<div class="keypress hide">
<div class="up" onclick="emit(38)">&#8593;</div>
<div class="right" onclick="emit(39)">&#8594;</div>
<div class="left" onclick="emit(37)">&#8592;</div>
<div class="down" onclick="emit(40)">&#8595;</div>
</div>
<div class="banner" id="selector">
<div>
Time :<span id="time">0</span>
</div>
<div>LousyGames ©</div>
<div>
Score :<span id="score">0</span>
</div>
<div class="touch off" onclick="touch(this)">touch</div>
</div>
<canvas id="main"></canvas>
</body>
<style>
body {
margin: 0;
overflow: hidden;
background: #000
}
.banner {
text-align: center;
color: #fff;
background: #3f51b5;
line-height: 29px;
position: fixed;
left: 0;
top: 0;
right: 0;
font-family: monospace;
height: 30px;
opacity: .4;
display: flex;
transition: .5s
}
.banner:hover {
opacity: 1
}
div#selector>div {
flex-basis: 30%
}
@keyframes diss {
from {
opacity: 1
}
to {
opacity: 0
}
}
.keypress>div {
border: dashed 3px #fff;
height: 48%;
width: 48%;
display: flex;
align-content: center;
justify-content: center;
align-self: center;
align-items: center;
font-size: -webkit-xxx-large;
font-weight: 900;
color: #fff;
transition: .5s;
opacity: .1;
border-radius: 7px
}
.keypress {
position: fixed;
width: 100vw;
height: 100vh;
top: 0;
left: 0;
display: flex;
flex-wrap: wrap;
justify-content: space-around;
opacity: 1;
user-select: none
}
.keypress>div:hover {
opacity: 1
}
.touch {
background: #8bc34a
}
.off {
background: #f44336
}
.hide {
opacity: 0
}
</style>
</html></pre>
<p>Javascript</p>
<pre class="brush: js">function tmz() {
var e = new Date(t),
i = new Date,
n = Math.abs(i.getMinutes() - e.getMinutes()),
o = Math.abs(i.getSeconds() - e.getSeconds());
return n + " : " + o
}
function coll(t, e) {
return t.x < e.x + e.w && t.x + t.w > e.x && t.y < e.y + e.h && t.h + t.y > e.y
}
function snake() {
this.w = 15, this.h = 15, this.dx = 1, this.dy = 1, this.xf = 1, this.yf = 1, this.sn = [];
for (var t = {
x: w / 2,
y: h / 2
}, e = 0; e < 5; e++) this.sn.push(Object.assign({}, t)), t.x += this.w;
this.draw = function () {
var t = d && d.search("Arrow") > -1,
e = -1;
if (t) {
var i = {
...this.sn[0]
};
if ("ArrowUp" == d && (i.y -= this.h), "ArrowDown" == d && (i.y += this.h), "ArrowLeft" == d && (i.x -= this.w), "ArrowRight" == d && (i.x += this.w), i.x >= w ? i.x = 0 : i.x < 0 && (i.x = w - this.w), i.y > h ? i.y = 0 : i.y < 0 && (i.y = h), e = fa.findIndex(t => coll({
...this.sn[0],
h: this.h,
w: this.w
}, t)), this.sn.unshift(i), -1 != e) return console.log(e), fa[e].renew(), void (document.getElementById("score").innerText = Number(document.getElementById("score").innerText) + 1);
this.sn.pop(), console.log(6)
}
this.sn.forEach((t, e, i) => {
if (0 == e || i.length - 1 == e) {
var n = c.createLinearGradient(t.x, t.y, t.x + this.w, t.y + this.h);
i.length - 1 == e ? (n.addColorStop(0, "black"), n.addColorStop(1, "#8BC34A")) : (n.addColorStop(0, "#8BC34A"), n.addColorStop(1, "white")), c.fillStyle = n
} else c.fillStyle = "#8BC34A";
c.fillRect(t.x, t.y, this.w, this.h), c.strokeStyle = "#E91E63", c.font = "30px serif", c.strokeStyle = "#9E9E9E", i.length - 1 != e && 0 != e && c.strokeRect(t.x, t.y, this.w, this.h), 0 == e && (c.beginPath(), c.fillStyle = "#F44336", c.arc(t.x + 10, t.y + 2, 5, 360, 0), c.fill()), c.arc(t.x + 10, t.y + 2, 5, 360, 0), c.fill(), c.beginPath()
})
}
}
function gc() {
for (var t = "0123456789ABCDEF", e = "#", i = 0; i < 6; i++) e += t[Math.ceil(15 * Math.random())];
return e
}
function food() {
this.x = 0, this.y = 0, this.b = 10, this.w = this.b, this.h = this.b, this.color = gc(), this.renew = function () {
this.x = Math.floor(Math.random() * (w - 200) + 10), this.y = Math.floor(Math.random() * (h - 200) + 30), this.color = gc()
}, this.renew(), this.put = (() => {
c.fillStyle = this.color, c.arc(this.x, this.y, this.b - 5, 0, 2 * Math.PI), c.fill(), c.beginPath(), c.arc(this.x, this.y, this.b - 5, 0, Math.PI), c.strokeStyle = "green", c.lineWidth = 10, c.stroke(), c.beginPath(), c.lineWidth = 1
})
}
function init() {
cc.height = h, cc.width = w, c.fillRect(0, 0, w, innerHeight);
for (var t = 0; t < 10; t++) fa.push(new food);
s = new snake(w / 2, h / 2, 400, 4, 4), anima()
}
function anima() {
c.fillStyle = "rgba(0,0,0,0.11)", c.fillRect(0, 0, cc.width, cc.height), fa.forEach(t => t.put()), s.draw(), document.getElementById("time").innerText = tmz(), setTimeout(() => {
requestAnimationFrame(anima)
}, fw)
}
function emit(t) {
key.keydown(t)
}
function touch(t) {
t.classList.toggle("off"), document.getElementsByClassName("keypress")[0].classList.toggle("hide")
}
var t = new Date + "",
d = void 0,
cc = document.getElementsByTagName("canvas")[0],
c = cc.getContext("2d");
key = {}, key.keydown = function (t) {
var e = document.createEvent("KeyboardEvent");
Object.defineProperty(e, "keyCode", {
get: function () {
return this.keyCodeVal
}
}), Object.defineProperty(e, "key", {
get: function () {
return 37 == this.keyCodeVal ? "ArrowLeft" : 38 == this.keyCodeVal ? "ArrowUp" : 39 == this.keyCodeVal ? "ArrowRight" : "ArrowDown"
}
}), Object.defineProperty(e, "which", {
get: function () {
return this.keyCodeVal
}
}), e.initKeyboardEvent ? e.initKeyboardEvent("keydown", !0, !0, document.defaultView, !1, !1, !1, !1, t, t) : e.initKeyEvent("keydown", !0, !0, document.defaultView, !1, !1, !1, !1, t, 0), e.keyCodeVal = t, e.keyCode !== t && alert("keyCode mismatch " + e.keyCode + "(" + e.which + ")"), document.dispatchEvent(e)
};
var o, s, h = innerHeight,
w = innerWidth,
fw = 60,
fa = [];
window.onkeydown = function (t) {
var e = t.key;
(e.search("Arrow") > -1 || "1" == e) && (d = t.key), "i" != e && "I" != e || (console.log("inc"), fw -= 10), "d" != e && "D" != e || (console.log("dec"), fw += 10)
}, init();
</pre>
<h5 id="Output">Output</h5>
<table class="standard-table">
<tbody>
<tr>
<td>
<h2 id="sect1"><a href="https://kunalverma94.github.io/pokemon/snake.html"><img alt="Snake game" src="https://kunalverma94.github.io/view/images/snake.jpg" style="height: 400px; width: 600px;"></a></h2>
</td>
</tr>
</tbody>
</table>
<h2 id="Other_examples" name="Other_examples">其它例子</h2>
<dl>
<dt><a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/A_basic_ray-caster" title="/zh-CN/docs/Web/Guide/HTML/A_basic_ray-caster">A basic ray-caster</a></dt>
<dd>一个关于如何使用键盘关联控制动画的优秀的案例。</dd>
<dt><a href="https://developer.mozilla.org/zh-CN/docs/Web/API/Canvas_API/Tutorial/Advanced_animations">Advanced animations</a></dt>
<dd>我们将在下一章看到一些先进的动画技术和物理现象。</dd>
</dl>
<p>{{PreviousNext("Web/API/Canvas_API/Tutorial/Compositing", "Web/API/Canvas_API/Tutorial/Advanced_animations")}}</p>
|