H5坦克大战之【画出坦克】

时间:2023-02-04 21:04:01
   具体步骤如下:
 
  1. 首先做出绘图区,作为坦克的战场
 
<canvas id="floor" width="800px" height="500px"></canvas>
  我们给一个黑色的背景色,并且让它居中(如果对居中的各种奇淫技巧感兴趣,欢迎访问我的第一篇博客——“CSS垂直居中的11种实现方式”,点击这里进行传送 http://www.cnblogs.com/zhouhuan/p/vertical_center.html)。
 
#floor {
background:#000;
position: absolute;
top: 50%;
left:50%;
transform:translate(-50%, -50%);
}
  结果如下:
H5坦克大战之【画出坦克】
  这里要说明一下,对于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();

  结果如下:

H5坦克大战之【画出坦克】

  第一步,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();

  结果如下:

H5坦克大战之【画出坦克】

  这里只有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();

  结果便是:

H5坦克大战之【画出坦克】

  fillStyle属性类似于前面用到过的strokeStyle,用来修改填充的颜色,这两者的默认值都是黑色;
  fill()方法用来填充当前路径的内部,也非常好理解,因为fill就是填充的意思。
 
  ③ 第三个例子是画矩形
  这里当然也可以像我们之前画三角形一样,自己一步一步地设置路径,设置好之后再画或者进行填充,但这种方法比较麻烦,也容易出错,不建议使用。CanvasRenderingContext2D对象有一个直接用来画矩形的方法,fillRect()和strokeRect():
var myCanvas = document.getElementById('floor');
var cxt = myCanvas.getContext('2d');
cxt.strokeStyle = "#fff";
cxt.strokeRect(20,20,50,100);
cxt.fillStyle = "#fff";
cxt.fillRect(80,20,50,100);

H5坦克大战之【画出坦克】

  这两个方法都有四个参数(x, y, width, height),前两个是矩形左上角点的坐标,后两个是矩形的宽和高。
  
  ④ 画圆
var myCanvas = document.getElementById('floor');
var cxt = myCanvas.getContext('2d');
cxt.fillStyle = "orange";
//第一个半圆
cxt.beginPath();
cxt.arc(100,100,50,0,Math.PI,true);
cxt.closePath();
cxt.fill();
//圆
cxt.beginPath();
cxt.arc(210,100,50,0,2*Math.PI,false);
cxt.closePath();
cxt.fill();
//第二个半圆
cxt.strokeStyle = "red";
cxt.beginPath();
cxt.arc(320,100,50,0,Math.PI,false);
cxt.closePath();
cxt.stroke();

  结果如下:

H5坦克大战之【画出坦克】

  arc()方法使用一个中心点和半径,为当前子路径添加一条弧,该方法传六个参数(x, y, radius, startAngle, endAngle, counterclockwise),分别表示圆心的x坐标,圆心的y坐标,圆的半径,开始的角度,结束的角度,顺时针还是逆时针。其中,两个角度采用弧度来衡量,最后一个参数true表示逆时针,false表示顺时针。
  这里给大家一个建议,在arc()方法之前加上beginPath(0开始路径,方法之后加上closePath()结束路径,否则可能会出现和其他图形互相影响的情况。画其它图形的时候也是,要注意这一点,只有矩形不用。
  关于角度的参数有几点说明:默认X轴正半轴的角度为0,沿着逆时针方向角度增加。上面使用到的Math.PI表示的就是数学当中的π,Math对象是ECMAScript为保存数学公式和信息提供的一个对象,该对象还有其它很多属性用起来也非常方便,比如Math.E表示自然对数的底数,也就是常量e的值。
 
  ⑤ 在画布上写字
var myCanvas = document.getElementById('floor');
var cxt = myCanvas.getContext('2d');
cxt.fillStyle = "#F21C9D";
cxt.font = "50px simhei";
cxt.fillText("圣诞快乐!",30,100);

  结果:

H5坦克大战之【画出坦克】

  fillText()方法用来在画布上写字,第一个参数传一个字符串,后两个参数便是左上角点的坐标;
  cxt.fillStyle用来给字体设置颜色;
  cxt.font用来设置大小和字体,大小的值和字体的值之间用空格隔开,二者只写一个时无效。
 
  ⑥ 画图片
var myCanvas = document.getElementById('floor');
var cxt = myCanvas.getContext('2d');
var myImg = new Image();
myImg.src = "images/soldier.png";
myImg.onload = function(){
cxt.drawImage(myImg,60,20,680,454);
};

  结果如下:

H5坦克大战之【画出坦克】

  画图片有几个步骤:
  var myImg = new Image(); 创建image对象;
  myImg.src = "images/soldier.png"; 指定图片的路径;
  myImg.onload = function(){
    cxt.drawImage(myImg,60,20,680,454);
  };
  加载完图片之后,使用drawImage()方法进行绘制,该方法传四个参数(x, y, width, height),分别为图片左上角的X坐标,Y坐标,图片的宽,图片的高,宽和高也可以不指定,不指定的话就会显示为图片的原始尺寸。
 
  3. 掌握了这些方法之后,我们就可以轻而易举地画出一个简单的坦克了,我们来以湖人队的主色画一个坦克:
var myCanvas = document.getElementById('floor');
var cxt = myCanvas.getContext('2d');
cxt.fillStyle = "#542174";
cxt.fillRect(350,400,20,65); //坦克左边的履带
cxt.fillRect(420,400,20,65); //右边的履带
cxt.fillRect(373,410,44,50); //中间的主体
cxt.fillStyle = "#FCB827";
cxt.beginPath();
cxt.arc(395,435,16,0,2*Math.PI,false); //主体上的圆盖
cxt.closePath();
cxt.fill();
cxt.strokeStyle = "#FCB827";
cxt.lineWidth = "8.0";
cxt.moveTo(395,435); //炮筒起点
cxt.lineTo(395,375); //炮筒终点
cxt.stroke(); //画炮筒
  结果如下:
H5坦克大战之【画出坦克】
  lineWidth属性用来设置画笔画出的线条宽度,默认值是1.0,设置的值必须大于0,较宽的线条在路径上居中,每边占线条宽度的一半。
  这里说明一下为什么不画一张坦克的图片上去,而要这样费尽周折结果还画了一个巨丑的坦克,这是因为如果直接使用图片的话会很耗CPU,性能不高,坦克跑起来的时候甚至可能会出现卡顿,但如果是自己画的坦克就不会有这样的问题。
  (注:暂未考虑对低版本IE及其它非主流浏览器的兼容) 

H5坦克大战之【画出坦克】的更多相关文章

  1. 《杜增强讲Unity之Tanks坦克大战》3-添加坦克

    3 添加坦克 3.1 本节效果预览   3.2 另存新场景 首先打开上次的场景s1,另存为s2,放到同一个文件夹下面.   3.3 添加坦克模型 在Model文件夹下面找到Tank模型   将Tank ...

  2. cocos2d-x游戏开发系列教程-坦克大战游戏之敌方坦克AI的编写

    在上篇我们完成了子弹和地图碰撞的检测,在这篇我们将完成敌方坦克AI的编写. 具体思路是屏幕中保持有四个敌方坦克,然后坦克随机方向运动,并且子弹消失后1秒发射一次 1.我们新建一个敌方坦克的AI类来控制 ...

  3. 【 java版坦克大战--事件处理】 让坦克动起来--事件处理的准备

    要能够控制坦克运动,必须用到事件处理的知识. 事件处理的一个demo. /** * 事件处理机制:委派事件模型.指当事件发生的时候,产生事件的对象(事件源),会把此 * "消息"传 ...

  4. cocos2d-x游戏开发系列教程-坦克大战游戏之所有坦克之间的碰撞检测

    上篇我们完成了简单的AI编写,但是各个坦克移动时之间是可以重合的, 这节课我们来完成坦克之间的碰撞检测,还是在上篇的EnemyAI中完成. 1.我先现在坦克类Tank中添加两个成员变量: CC_SYN ...

  5. &lbrack;置顶&rsqb; 小强的HTML5移动开发之路(9)——坦克大战游戏3

    上一篇我们创建了敌人的坦克和自己的坦克,接下来就应该让坦克发子弹了,我们下面来看一下如何让我们的坦克发出子弹. 前面我们用面向对象的思想对Tank进行了封装,又利用对象冒充实现了我们的坦克和敌人的坦克 ...

  6. 【java版坦克大战---准备篇】 java 绘图

    要写坦克大战当然要先画出坦克.java画图是基础. package com.game; import java.awt.*; import javax.swing.*; public class Pr ...

  7. Html 5 坦克大战(韩顺平县版本号)

    html 5例如,下面的代码段: <!DOCTYPE html> <html> <head> <meta charset="utf-8"/ ...

  8. 小强的HTML5移动开发之路(8)——坦克大战游戏2

    来自:http://blog.csdn.net/cai_xingyun/article/details/48629015 在上一篇文章中我们已经画出了自己的坦克,并且可以控制自己的坦克移动,我们继续接 ...

  9. 小强的HTML5移动开发之路(7)——坦克大战游戏1

    来自:http://blog.csdn.net/dawanganban/article/details/17693145 上一篇中我们介绍了关于Canvas的基础知识,用Canvas绘制各种图形和图片 ...

随机推荐

  1. 【matlab】libsvm-3&period;18安装与使用

    安装 1. 在http://www.csie.ntu.edu.tw/~cjlin/ 中下载libsvm 2. 按照http://zjhello123.blog.163.com/blog/static/ ...

  2. hdu 4699 Editor 模拟栈

    思路:刚开始用STL中的栈,一直RE……,之后改为手动模拟栈操作,在注意点细节就可以了!!! 代码如下: #include<cstdio> #include<cstring> ...

  3. 各种HTTP错误消息含义

    错误代码 错误消息 400 无法解析此请求. 401.1 未经授权:访问由于凭据无效被拒绝. 401.2 未经授权: 访问由于服务器配置倾向使用替代身份验证方法而被拒绝. 401.3 未经授权:访问由 ...

  4. hdu 3625 第一类striling 数

    /** 第一类Stirling数是有正负的,其绝对值是包含n个元素的集合分作k个环排列的方法数目. 递推公式为, S(n,0) = 0, S(1,1) = 1. S(n+1,k) = S(n,k-1) ...

  5. AUDIOqueue 为什么会播放一段时间就听不到声音

    转自简书:非常有用 AudioQueue缓冲区为空时,那么AudioQueueOutputCallback回调不会再调用 这个其实很好理解,AudioQueue的回调本事就是数据播完了才回调的 Aud ...

  6. WINDOWS资源编译器出错信息

    ACCELERATORS语句的type域应包含ASCⅡ值或VIRTKEY值.        BEGIN expected in table        BEGIN关键字应紧跟在ACCELERATOR ...

  7. MD5在线加密的应用

    MD5是message-digest algorithm 5(信息-摘要算法)的缩写.被广泛用于加密和解密技术上,是文件的“数字指纹”.可以对用户的密码进行加密操作,是不可逆的,所以用户输入的密码经过 ...

  8. 机器学习基石笔记:06 Theory of Generalization

    若H的断点为k,即k个数据点不能被H给shatter,那么k+1个数据点也不能被H给shatter,即k+1也是H的断点. 如果给定的样本数N是大于等于k的,易得mH(N)<2N,且随着N的增大 ...

  9. Java方法区

    方法区 在一个jvm实例的内部,类型信息被存储在一个称为方法区的内存逻辑区中.类型信息是由类加载器在类加载时从类文件中提取出来的.类(静态)变量也存储在方法区中. jvm实现的设计者决定了类型信息的内 ...

  10. C语言 指针数组 多维数组

    . 作者 : 万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/details/21402047 . 1. 地址算数运算示例 指针算数运算 ...