今天是个特殊的日子,圣诞节,也是周末,在这里先祝大家圣诞快乐!喜庆的日子,我们可以稍微放松一下,扯一扯昨天雷霆对战凯尔特人的比赛,这场比赛大威少又双叒叕拿下三双,而且是一个45+11+11的超级三双,其实小托马斯的表现也不遑多让,拿下31分9个助攻,末节一开始便带队打出一波小高潮反超比分,无奈威少爷最后几分钟暴走直接带走比赛,让人直呼精彩。好了,扯完之后我们进入正题。
今天给大家带来的是一个比较好玩的东西——H5坦克大战。这个东西的实现主要用到了H5的canvas以及原生的js,如果你已经是大牛,那笔者建议现在开始可以隔五行一看,毕竟笔者也才入行不久还在奔往大牛村的路上,如果你是个新手基础薄弱,那么也请不要离开,笔者会很啰嗦,尽量写成初学者也看得懂的代码(哈哈如此心机的一个伏笔,谁还敢说代码水平不够!)。
1. 首先做出绘图区,作为坦克的战场
我们给一个黑色的背景色,并且让它居中(如果对居中的各种奇淫技巧感兴趣,欢迎访问我的第一篇博客——“CSS垂直居中的11种实现方式”,点击这里进行传送 )。
#floor { background:#000; position: absolute; top: 50%; left:50%; transform:translate(-50%, -50%); }
结果如下:
这里要说明一下,对于canvas画布,写在样式里的宽高和写在属性里的宽高是不等价的,写在样式里的宽高是实际显示在页面里的像素宽高,而写在属性里的宽高是context的环境宽高(有些小伙伴可能暂时对context还没有概念,没关系,这里如果不能理解可以暂时先这样做,跟着笔者的思路走,待会讲了context之后再回来自己试一下便会有所体会),这二者的默认值都是300px 150px,如果将样式的宽高改为800px 500px,那么其实是相当于将context环境内的300px 150px画在了现实中的800px 500px,会导致画的东西变得模糊,并且可能出现变形,所以一般要保持样式宽高与属性宽高的一致,其实一般做的话设置个属性宽高确定一下画布的大小就可以了。
2. 接下来就要在画布上绘制图形了
canvas元素自身是没有绘图能力的,所有的绘制工作必须通过JavaScript来完成。
① 这里我们先给出一个画直线的demo,然后做以解释:
var myCanvas = document.getElementById('floor'); var cxt = myCanvas.getContext('2d'); cxt.moveTo(50,50); cxt.lineTo(50,200); cxt.strokeStyle = '#fff'; cxt.stroke();
结果如下:
第一步,var myCanvas = document.getElementById('floor'); 这个大家应该都明白,拿到canvas元素,拿到canvas元素是因为第二步里需要使用到它。
第二步,var cxt = myCanvas.getContext('2d'); 这一步的作用是创建一个在绘图区作图的环境(我一般形象地理解为在当前画布上创建一个画笔),文档里的定义是:getContext()方法返回一个用于在画布上绘图的环境。我们来看看文档里进一步的解释:该方法里的参数指定了想要在画布上绘制的类型,当前唯一的合法值是 "2d",它指定了二维绘图,并且导致这个方法返回一个环境对象,该对象导出一个二维绘图 API,在未来,如果 <canvas> 标签扩展到支持 3D 绘图,getContext() 方法可能允许传递一个 "3d" 字符串参数。getContext()方法返回的是一个 CanvasRenderingContext2D 对象,使用它可以绘制图形到 Canvas 元素中。
第三步,cxt.moveTo(50,50); 这一步就已经开始在画直线了,moveTo()方法用于设置当前位置(50,50)并开始一条新的子路径。
第四步,cxt.lineTo(50,200); 为当前的子路径添加一条直线线段。这里的解释可能有点绕,大家看单词的字面意思可能会更清楚些:moveTo就是将子路径的起点移到某个位置,lineTo就是子路径要一直达到某个位置那当然就是终点咯。
第五步,cxt.strokeStyle = '#fff'; 设置画笔的颜色为白色,这里没有多余要解释的地方。
第六步,cxt.stroke(); 按照前几步的设置来绘制一条直线,这一步也比较好理解。
OK,那到这一步,我们的第一条直线便绘制成功了!撒花撒花!
② 接下来,我们再看一个画三角形的例子,仍然是先给出代码和结果,再来给大家解释:
var myCanvas = document.getElementById('floor'); var cxt = myCanvas.getContext('2d'); cxt.beginPath(); cxt.moveTo(50,50); cxt.lineTo(50,200); cxt.lineTo(200,200); cxt.closePath(); cxt.strokeStyle = '#fff'; cxt.stroke();
结果如下:
这里只有beginPath()和closePath()前面没有用到过。
beginPath()方法:丢弃任何当前定义的路径并且开始一条新的路径;
closePath()方法:如果画布的子路径是打开的,那么closePath()方法通过添加一条线段连接当前点和子路径起始点来关闭它,但如果子路径已经闭合,该方法便不做任何事情。一旦子路径闭合,就不能再为其添加更多的直线或曲线了。
上面的代码也可以修改成这样:
var myCanvas = document.getElementById('floor'); var cxt = myCanvas.getContext('2d'); cxt.beginPath(); cxt.moveTo(50,50); cxt.lineTo(50,200); cxt.lineTo(200,200); cxt.closePath(); cxt.fillStyle = '#fff'; cxt.fill();
结果便是:
fillStyle属性类似于前面用到过的strokeStyle,用来修改填充的颜色,这两者的默认值都是黑色;
fill()方法用来填充当前路径的内部,也非常好理解,因为fill就是填充的意思。
③ 第三个例子是画矩形