万物皆有其美,但并非人人都能发现。——<安迪.沃霍尔>
用纯JavaScript
创建一个简单的2D游戏。作为第一步,展示如何使用canvas
元素对背景图像进行动画处理(平移或滚动)。
简单的2D游戏有两种常见方案:
整个关卡都有巨大的背景图片。所有活动都具有相同的背景图像,但是视口的位置在变化
随着播放器的前进,有一个小图像一直在滚动(通常从右向左滚动)
在背景图像内平移视口
演示代码如下(不支持请访问演示地址查看):
演示地址 http://cl9000.gitee.io/web-code/15_canvas元素平移滚动背景/
开始/停止 动画
这个怎么运作
我们有一个函数,在游戏绘制的每一帧中都会调用该函数。在这种方法中,我们计算视口的位置。对于这个基本示例,我选择从经过的时间中得出位置。因此,相机采取椭圆形路径。
1 2 3 4 5 6 7 function draw (delta ) { totalSeconds += delta; var x = -1 * (img.width - canvas.width) / 2 * (1 + Math .cos(totalSeconds / Math .PI)); var y = -1 * (img.height - canvas.height) / 2 * (1 + -Math .sin(totalSeconds / Math .PI)); context.drawImage(img, x, y); }
无限滚动背景图像
演示代码如下(不支持请访问演示地址查看):
演示地址 http://cl9000.gitee.io/web-code/15_canvas元素平移滚动背景/
开始/停止 动画
这个怎么运作
背景位置也从经过的时间(恒定速度)中得出。
我们计算需要多少图像才能覆盖视口: Math.ceil(canvas.width / img.width) + 1
我们计算当前的X位置:totalSeconds * vx % img.width
。请在这里注意模运算符。
我们存储当前的上下文状态并转换画布以使绘图更容易。
我们绘制图像-一个接一个地绘制。
我们恢复上下文的状态。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 function draw (delta ) { totalSeconds += delta; var vx = 100 ; var numImages = Math .ceil(canvas.width / img.width) + 1 ; var xpos = totalSeconds * vx % img.width; context.save(); context.translate(-xpos, 0 ); for (var i = 0 ; i < numImages; i++) { context.drawImage(img, i * img.width, 0 ); } context.restore(); }
所有调用我们draw()函数的代码
在这些示例中使用的设置代码。
用了一些基本的requestAnimationFramepolyfill
仅在成功加载图像(加载)后才开始动画。
一些启动/停止逻辑和按钮
loop()
在动画运行时,每一帧都会调用该函数。在这里我们需要requestAnimationFrame()
。
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 (function ( ) { window .requestAnimationFrame = window .requestAnimationFrame || window .webkitRequestAnimationFrame || window .mozRequestAnimationFrame || function (callback ) { window .setTimeout(callback, 1000 / 60 ); }; var canvas = document .getElementById('bg' ); var context = canvas.getContext('2d' ); var looping = false ; var totalSeconds = 0 ; var img = new Image(); img.onload = imageLoaded; img.src = 'IMG_SOURCE' ; function imageLoaded ( ) { draw(0 ); var btn = document .getElementById('btnStart' ); btn.addEventListener('click' , function ( ) { startStop(); }); } var lastFrameTime = 0 ; function startStop ( ) { looping = !looping; if (looping) { lastFrameTime = Date .now(); requestAnimationFrame(loop); } } function loop ( ) { if (!looping) { return ; } requestAnimationFrame(loop); var now = Date .now(); var deltaSeconds = (now - lastFrameTime) / 1000 ; lastFrameTime = now; draw(deltaSeconds); } function draw (delta ) { } }());
参考
关注【公众号】,了解更多。
赞赏一下 坚持原创技术分享,您的支持将鼓励我继续创作!