小游戏中背景动画
上一章节我们已经学会了如何绘制背景,包括平铺背景图片占满图片
很多游戏,背景是运动的,就像打飞机里的小游戏一样,背景会一直向着屏幕下方运动
但是,当我们将背景整体移动的时候,顶部就会出现空白
这时候最简单的方案当然是顶部的空白区域再添中一张图片,当然,填充方法是有要求的,就是只填充图片底部区域,因为填充图片顶部区域就不对对称了不是
背景移动填充方法
所以我们可以将背景移动填充的方式归纳为以下几个流程
-
将绘制点
(0,0)
向下移动一段距离y
,那么起始绘制点为(0,y)
-
使用背景填充绘制点以上区域,重新设置变量
yy=y
- 判断偏移高度是否大于要绘制的图片高度 ( h )
- 如果大于,那么先在点
(0,yy-h)
处绘制一张图片,yy = yy-h
- 重复
[1-2]
步骤,直至yy < 0
且Math.abs(yy) > h
停止
-
使用背景填充绘制点以下区域,重新设置变量
yyy=y
- 判断剩余高度是否大于要绘制的图片高度 ( h )
- 如果大于,那么先在点
(0,yyy)
处绘制一张图片,yyy = yyy+h
- 重复
[1-2]
步骤,直至yyy >= screenHeight
停止
当然了,这种编辑方法实在太绕口,我们改良下,先看下图
当使用上面的方法填充的时候,我们发现,不管向下移动了多少距离,那么,最后总有那么一张图片,刚好在屏幕上边附近 (0,0)
这张图片在屏幕上显示出来的高度为 y % h
,而未显示出来的高度为 h-(y%h)
所以,我们只要把初始的绘制点向上偏移 h-(y%h)
就可以了,也就是绘制点为 (0,-(h-(y%h))
即 (0,(y%h)-h)
代码演示如下
var screenHeight = ctx.canvas.height; var screenWidth = ctx.canvas.width; var w = screenWidth > img.width ? img.width : screenWidth; var h = img.height * (w / img.width); var y = (offsetY % h) - h ; var x = 0; while (y < screenHeight) { x = 0; while (x < screenWidth) { ctx.drawImage(img, x, y, w, h); x+= w; } y += h; }
范例
我们以偏移点 (0,30)
绘制背景图片
game.js
function reset(ctx) { ctx.save(); ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, c.width, c.height); ctx.restore(); } function draw_copy() { ctx.save(); ctx.textAlign = "center" // 居中对齐 ctx.textBaseline = "middle" //垂直居中绘制 ctx.fillStyle = "#aaa"; ctx.font = "16px Arial" // 字体大小 16 像素 ctx.fillText("简单教程,简单编程", c.width / 2, (c.height - 36)) ctx.fillText(" © 2015-2018 www.twle.cn", c.width / 2, (c.height - 18)); ctx.restore(); } function draw_bg(img,offsetY,ctx) { var screenHeight = ctx.canvas.height; var screenWidth = ctx.canvas.width; var w = screenWidth > img.width ? img.width : screenWidth; var h = img.height * (w / img.width); var y = (offsetY % h) - h ; var x = 0; while (y < screenHeight) { x = 0; while (x < screenWidth) { ctx.drawImage(img, x, y, w, h); x+= w; } y += h; } } var c = wx.createCanvas(); var ctx = c.getContext('2d'); reset(ctx); var img = wx.createImage(); img.onload = function () { ctx.save(); reset(ctx); var yy = 30; draw_bg(img,30,ctx); draw_copy(); ctx.restore(); } img.src = "images/bg.jpg";
在微信中显示如下
背景动画
因此,如果要让背景动起来,只要不断的改变偏移量就可以了,就不介绍了,直接上代码
var c = wx.createCanvas(); var ctx = c.getContext('2d'); reset(ctx); var img = wx.createImage(); var offset = 0; var screenHeight = c.height; var screenWidth = c.width; var w = 0; var h = 0; function reset(ctx) { ctx.save(); ctx.fillStyle = "#fff"; ctx.fillRect(0, 0, c.width, c.height); ctx.restore(); } function draw_copy() { ctx.save(); ctx.textAlign = "center" // 居中对齐 ctx.textBaseline = "middle" //垂直居中绘制 ctx.fillStyle = "#aaa"; ctx.font = "16px Arial" // 字体大小 16 像素 ctx.fillText("简单教程,简单编程", c.width / 2, (c.height - 36)) ctx.fillText(" © 2015-2018 www.twle.cn", c.width / 2, (c.height - 18)); ctx.restore(); } function draw_bg(img, offsetY, ctx) { var y = (offsetY % h) - h; var x = 0; while (y < screenHeight) { x = 0; while (x < screenWidth) { ctx.drawImage(img, x, y, w, h); x += w; } y += h; } } function animate_it() { reset(ctx); draw_bg(img, offset, ctx); draw_copy(); offset++; if (offset >= ctx.canvas.height && (offset % h == 0)) { offset = 0; } requestAnimationFrame(animate_it); } img.onload = function () { w = screenWidth > img.width ? img.width : screenWidth; h = img.height * (w / img.width); requestAnimationFrame(animate_it); } img.src = "images/bg.jpg";
运行演示如下
因为移动距离不是刚好等于图片高度,所以会闪屏
要特别注意下面的代码
if (offset >= ctx.canvas.height && (offset % h == 0)) { offset = 0; }
如果只是简单的判断 offset >= ctx.canvas.height
你会发现会闪屏,为什么呢?
因为图片的高度不等于屏幕的高度,可能滚动的距离为屏幕高度时,最后一张图片只显示了一半,所以要等滚动高度超出屏幕,且滚动的距离刚好为图片高度的倍数的时候,才重置
其实还有一个更简单的判断方法,就是
if ( offset % h == 0) { offset = 0; }
只要滚动超过图片的高度,那么立刻重置,因为接下来没啥意义,只是循环循环循环而已
其它
如果图片小于屏幕宽度,那么水平也要平铺,大家可以自己动手,看看
这个就作为大家的课后作业吧