《HTML5 Canvas游戏开发实战》——2.4 图片操作

本节书摘来自华章计算机《HTML5 Canvas游戏开发实战》一书中的第2章,第2.4节,作者:张路斌著, 更多章节内容可以访问云栖社区“华章计算机”公众号查看。

2.4 图片操作

无论我们开发的是应用程序还是游戏软件,都是离不开图片,没有图片就无法让整个页面漂亮起来。开发游戏的时候,游戏中的地图、背景、人物、物品等都是由图片组成的,所以图片的显示和操作非常重要。Canvas中提供了drawImage函数和putImageData函数来绘制图片,在本节中将一一讲解。
2.4.1 利用drawImage绘制图片
drawImage函数有3种函数原型,其语法如下:

drawImage(image, dx, dy); 
drawImage(image, dx, dy, dw, dh); 
drawImage(image, sx, sy, sw, sh, dx, dy, dw, dh);

第一个参数image是要绘制的对象,这个参数可以是HTMLImageElement、HTML-CanvasElement或者HTMLVideoElement,dx、dy是image在Canvas中定位的坐标值,dw、dh表示image在Canvas中即将绘制区域(相对dx和dy坐标的偏移量)的宽度和高度值,sx、sy是image所要绘制的起始位置,sw、sh表示image所要绘制区域(相对image的sx和sy坐标的偏移量)的宽度和高度值。
关于第一个参数,我们先使用HTML的标签来得到将要绘制的图片的数据。首先准备一张图片face.jpg,然后看代码清单2-23。
代码清单 2-23

<!DOCTYPE HTML>
<html>
<head>
  <meta charset="utf-8" />
</head>
<body>
img标签<br />
<img id="face" src="face.jpg" alt="The Face" width="240" height="240" /><br />
canvas画板<br />
<canvas id="myCanvas" width="500" height="350">
你的浏览器不支持HTML5
</canvas>
<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");

var img=document.getElementById("face");
ctx.drawImage(img,10,10);
</script>
</body>
</html>

代码解析
首先在html中加入标签。

<img id="face" src="face.jpg" alt="The Face" width="240" height="240" /><br />

然后在Canvas中通过< img>标签的id取得图片数据。

var img=document.getElementById("face");

最后用drawImage函数将图片绘制到画板上。

ctx.drawImage(img,10,10);

运行效果如图2-26所示。
上面的代码是通过标签来获取的,我们也可以通过JavaScript的Image对象来获取。具体使用方法如代码清单2-24所示。
代码清单 2-24

<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var img=document.getElementById("face");
img.onload = function(){    
   ctx.drawImage(img,10,10);   
};   
</script>

image

代码解析
首先建立Image对象。

var image = new Image();

然后通过设置src属性,来载入图片。

image.src = "face.jpg";

接着添加onload事件侦听,当图片载入完成时将其绘制到画板上。

image.onload = function(){    
   ctx.drawImage(image,10,10);   
};

运行效果如图2-27所示。

image

下面具体看一下drawImage函数的3种函数原型的用法与区别,如代码清单2-25所示。
代码清单 2-25

<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var image = new Image();    
image.src = "face.jpg";  
image.onload = function(){    
   ctx.drawImage(image,10,10);  
   ctx.drawImage(image,260,10,100,100); 
   ctx.drawImage(image,50,50,100,100,260,130,100,100);   
};    
</script>

代码解析
下面的代码表示从坐标(10,10)开始绘制整张图片。

ctx.drawImage(image,10,10);

下面的代码表示从坐标(260,10)开始绘制整张图片到长100、宽100的矩形区域内。

ctx.drawImage(image,260,10,100,100);

下面的代码表示截取图片从 (50,50)到(100,100)的部分,从坐标(260,130)开始绘制,放到长100、宽100的矩形区域内。

ctx.drawImage(image,50,50,100,100,260,130,100,100);

运行效果如图2-28所示。

image

2.4.2 利用getImageData和putImageData绘制图片
将图片绘制到Canvas画板上还有另一种方法,就是使用putImageData(imgdata,dx,dy,sx,sy,sw,sh)函数。putImageData函数有7个参数,其中imgdata为像素数据,dx、dy是绘制图片的定位坐标值, sx、sy是imgdata所要绘制图片的起始位置,sw、sh是imgdata所要绘制区域(相对imgdata的sx和sy坐标的偏移量)的宽度和高度值。值得一提的是,这里面第4个参数以及其后的所有参数都可以省略,如果这些参数都省略了,则表示绘制整个imgdata。
在使用putImageData函数前,需要先用getImageData(x,y,w,h)函数得到像素数据,这里指的是从Canvas画板上取得所选区域的像素数据,它的4个参数分别是选择区域起点的坐标x和坐标y,选择区域的长和宽。putImageData(imgdata,dx,dy,x,y,w,h)函数则表示将所得到的像素数据描画到Canvas画板上形成图形。
下面是putImageData函数的使用过程,如代码清单2-26所示。
代码清单 2-26

<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var image = new Image();    
image.src = "face.jpg";  
image.onload = function(){    
    ctx.drawImage(image,10,10);  
    var imgData=ctx.getImageData(50,50,200,200);
    ctx.putImageData(imgData,10,260); 
     ctx.putImageData(imgData,200,260,50,50,100,100);
};    
</script>

代码解析
图片数据读取完成后,首先将图片数据绘制到Canvas画板上。

ctx.drawImage(image,10,10);

然后用getImageData函数从画板上取得像素数据。

var imgData=ctx.getImageData(50,50,200,200);

将所取得的整个像素数据画到Canvas画板上。

ctx.putImageData(imgData,10,260);

将所取得的像素数据的一部分画到Canvas画板上。

ctx.putImageData(imgData,200,260,50,50,100,100);

运行效果如图2-29所示。

image

注意 代码清单2-26中使用了getImageData函数获取图片数据,此函数在Google Chrome等浏览器中会涉及跨域问题,所以无法直接在浏览器中浏览,必须通过服务器来访问。我们在第1章配置环境的时候已经安装了本地服务器,参照1.5节的内容,将本地的代码文件放到本地服务器上,就可以看到测试结果了。以后凡是用到getImageData函数的地方,一定要使用此方法进行测试,此处不赘述。
2.4.3 利用createImageData新建像素
createImageData函数有两种函数原型,其语法分别如下所示:
createImageData(sw, sh);
其一,返回指定大小的imageData对象。
createImageData(imagedata);
其二,返回与指定对象相同大小的imageData对象。
首先需要知道的是,通过createImageData返回的是一个空的imageData对象,必须要针对其像素进行赋值才能显示到Canvas画板上。下面我们通过例子来看看这两种原型的使用方法与区别,如代码清单2-27所示。
代码清单 2-27

<script type="text/javascript">
var c=document.getElementById("myCanvas");
var ctx=c.getContext("2d");
var image = new Image();    
image.src = "face.jpg";  
image.onload = function(){    
    ctx.drawImage(image,10,10);  
    var imgData=ctx.getImageData(50,50,200,200);
    
    var imgData01=ctx.createImageData(imgData);
    for (i=0; i<imgData01.width*imgData01.height*4;i+=4){
        imgData01.data[i+0]=255;
        imgData01.data[i+1]=0;
        imgData01.data[i+2]=0;
        imgData01.data[i+3]=255;
    }
    ctx.putImageData(imgData01,10,260); 
    
    var imgData02=ctx.createImageData(100,100);
    for (i=0; i<imgData02.width*imgData02.height*4;i+=4){
        imgData02.data[i+0]=255;
        imgData02.data[i+1]=0;
        imgData02.data[i+2]=0;
        imgData02.data[i+3]=155;
    }
    ctx.putImageData(imgData02,220,260); 
};    
</script>

代码解析
图片数据读取完成后,首先将图片数据绘制到Canvas画板上。

ctx.drawImage(image,10,10);

然后用getImageData函数从画板上取得像素数据。

var imgData=ctx.getImageData(50,50,200,200);

使用createImageData返回与imgData相同大小的ImageData对象。

var imgData01=ctx.createImageData(imgData);

下面imgData01进行赋值。

for (i=0; i<imgData01.width*imgData01.height*4;i+=4){
    imgData01.data[i+0]=255;
    imgData01.data[i+1]=0;
    imgData01.data[i+2]=0;
    imgData01.data[i+3]=255;
}

利用putImageData将imgData01画到Canvas画板上。

ctx.putImageData(imgData01,10,260);

使用createImageData返回一个大小为100×100的ImageData对象。

var imgData02=ctx.createImageData(100,100);

对imgData02进行赋值。

for (i=0; i<imgData02.width*imgData02.height*4;i+=4){
    imgData02.data[i+0]=255;
    imgData02.data[i+1]=0;
    imgData02.data[i+2]=0;
    imgData02.data[i+3]=155;
}

利用putImageData将imgData02画到Canvas画板上。

ctx.putImageData(imgData02,220,260);

运行效果如图2-30所示。

image

第一部分 准备工作篇 第1章 准备工作 / 2 1.1 html5介绍 / 2 1.1.1 什么是html5 / 2 1.1.2 html5的新特性 / 2 1.2 canvas简介 / 5 1.2.1 canvas标签的历史 / 5 1.2.2 canvas的定义和用法 / 6 1.2.3 如何使用canvas来绘图 / 6 1.2.4 canvas的限制 / 7 1.3 开发与运行环境的准备 / 7 1.3.1 浏览器的支持 / 7 1.3.2 准备一个本地的服务器 / 8 1.4 开发工具的选择 / 8 1.5 测试与上传代码 / 12 1.6 javascript中的面向对象 / 13 1.6.1 类 / 13 1.6.2 静态类 / 16 .1.6.3 继承 / 16 1.7 小结 / 17 第二部分 基础知识篇 第2章 canvas基本功能 / 20 2.1 绘制基本图形 / 20 2.1.1 画线 / 20 2.1.2 画矩形 / 22 2.1.3 画圆 / 24 2.1.4 画圆角矩形 / 26 2.1.5 擦除canvas画板 / 27 2.2 绘制复杂图形 / 28 2.2.1 画曲线 / 28 2.2.2 利用clip在指定区域绘 图 / 30 2.2.3 绘制自定义图形 / 31 2.3 绘制文本 / 32 2.3.1 绘制文字 / 32 2.3.2 文字设置 / 33 2.3.3 文字的对齐方式 / 38 2.4 图片操作 / 41 2.4.1 利用drawimage绘制图片 / 41 2.4.2 利用getimagedata和putimagedata绘制图片 / 45 2.4.3 利用createimagedata新建像素 / 47 2.5 小结 / 49 第3章 canvas高级功能 / 50 3.1 变形 / 50 3.1.1 放大与缩小 / 50 3.1.2 平移 / 53 3.1.3 旋转 / 54 3.1.4 利用transform矩阵实现多样化的变形 / 56 3.2 图形的渲染 / 65 3.2.1 绘制颜色渐变效果的图形 / 65 3.2.2 颜色合成之globalcompositeoperation属性 / 67 3.2.3 颜色反转 / 69 3.2.4 灰度控制 / 70 3.2.5 阴影效果 / 71 3.3 自定义画板 / 72 3.3.1 画板的建立 / 72 3.3.2 canvas画布的导出功能 / 79 3.4 小结 / 81 第4章 lufylegend开源库件 / 82 4.1 lufylegend库件简介 / 82 4.1.1 工作原理 / 82 4.1.2 库件使用流程 / 83 4.2 图片的加载与显示 / 84 4.2.1 图片显示举例 / 84 4.2.2 lbitmapdata对象 / 86 4.2.3 lbitmap对象 / 87 4.3 层的概念 / 88 4.4 使用lgraphics对象绘图 / 90 4.4.1 绘制矩形 / 90 4.4.2 绘制圆 / 91 4.4.3 绘制任意多边形 / 92 4.4.4 使用canvas的原始绘图函数进行绘图 / 93 4.4.5 使用lsprite对象进行绘图 / 94 4.4.6 使用lgraphics对象绘制图片 / 95 4.5 文本 / 101 4.5.1 文本属性 / 101 4.5.2 输入框 / 102 4.6 事件 / 103 4.6.1 鼠标事件 / 103 4.6.2 循环事件 / 104 4.6.3 键盘事件 / 105 4.7 按钮 / 106 4.8 动画 / 108 4.9 小结 / 113 第三部分 开发实战篇 第5章 从简单做起—“石头剪子布”游戏 / 116 5.1 游戏分析 / 116 5.2 必要的javascript知识 / 117 5.2.1 随机数 / 117 5.2.2 条件分支 / 117 5.3 分层实现 / 117 5.4 各个层的基本功能 / 119 5.4.1 基本画面显示 / 119 5.4.2 结果层的显示 / 126 5.4.3 控制层的显示 / 127 5.5 出拳 / 129 5.6 结果判定 / 131 5.7 小结 / 137 第6章 开发“俄罗斯方块”游戏 / 138 6.1 游戏分析 / 138 6.2 必要的javascript知识 / 138 6.3 游戏标题画面显示 / 139 6.4 向游戏里添加方块 / 141 6.5 控制方块的移动 / 152 6.5.1 键盘事件 / 152 6.5.2 触屏事件 / 155 6.6 方块的消除和得分的显示 / 157 6.7 小结 / 160 第7章 开发“是男人就下一百层”游戏 / 161 7.1 游戏分析 / 161 7.2 游戏标题画面显示 / 161 7.3 读取图片与背景显示 / 162 7.4 添加一个静止的地板 / 167 7.5 添加游戏主角 / 170 7.5.1 让游戏主角出现在画面上 / 170 7.5.2 通过键盘事件来控制游戏主角的移动 / 177 7.5.3 通过触屏事件来控制游戏主角的移动 / 178 7.6 添加多种多样的地板 / 179 7.6.1 会消失的地板 / 179 7.6.2 带刺的地板 / 181 7.6.3 带有弹性的地板 / 182 7.6.4 向左和向右移动的地板 / 184 7.7 游戏数据的显示 / 187 7.8 游戏结束与重开 / 190 7.9 小结 / 192 第8章 开发射击类游戏 / 193 8.1 游戏分析 / 193 8.2 添加一架可控飞机 / 194 8.2.1 添加一个飞机类 / 194 8.2.2 可控飞机类 / 197 8.3 为飞机添加多样化的子弹 / 203 8.3.1 建立一个子弹类 / 203 8.3.2 单发子弹 / 205 8.3.3 多发子弹 / 207 8.3.4 环形子弹 / 208 8.3.5 反向子弹 / 209 8.4 添加敌机 / 209 8.4.1 建立一个敌机类 / 210 8.4.2 建立一个敌机boss类 / 214 8.5 碰撞检测 / 217 8.5.1 飞机与子弹的碰撞 / 217 8.5.2 我机与敌机的碰撞 / 220 8.6 子弹的变更 / 221 8.6.1 建立一个弹药类 / 222 8.6.2 弹药与我机的碰撞 / 223 8.7 飞机生命值的显示 / 225 8.8 游戏胜利与失败判定 / 226 8.9 小结 / 228 第9章 开发物理游戏 / 229 9.1 box2d简介 / 229 9.2 box2dweb在lufylegend库件中的使用 / 229 9.3 创建各种各样的物体 / 234 9.3.1 矩形物体 / 234 9.3.2 圆形物体 / 237 9.3.3 多边形物体 / 239 9.4 响应鼠标拖拽物体 / 242 9.5 关节(joint) / 243 9.5.1 距离关节(b2distancejointdef) / 243 9.5.2 旋转关节(b2revolutejointdef) / 245 9.5.3 滑轮关节(b2pulleyjointdef) / 247 9.5.4 移动关节(b2prismaticjoint) / 248 9.5.5 齿轮关节(b2gearjoint) / 250 9.5.6 悬挂关节(b2linejoint) / 252 9.5.7 焊接关节(b2weldjoint) / 253 9.5.8 鼠标关节(mouse joint) / 254 9.6 力 / 254 9.7 碰撞检测 / 256 9.8 镜头移动 / 260 9.9 做一个简单的物理游戏 / 263 9.10 小结 / 267 第10章 开发网络游戏 / 268 10.1 http通信 / 268 10.1.1 如何实现http通信 / 268 10.1.2 http通信的弊端 / 275 10.2 socket通信 / 275 10.2.1 区分socket通信和http通信 / 276 10.2.2 服务器端 / 276 10.2.3 客户端 / 281 10.3 利用websocket实现简单的聊天室 / 283 10.4 做一款多人在线的坦克大战 / 293 10.4.1 服务器 / 293 10.4.2 客户端 / 293 10.5 小结 / 307 第四部分 技能提高篇 第11章 提高效率的分析 / 310 11.1 绘图时使用小数的影响 / 310 11.2 drawimage和putimagedata的效率比较 / 311 11.3 区域更新和图片大小对绘图效率的影响 / 311 11.4 图片格式对绘图效率的影响 / 313 11.5 优化代码以提高整体效率 / 314 11.5.1 使用位运算 / 314 11.5.2 少用math静态类 / 316 11.5.3 优化算法 / 319 11.6 小结 / 322 · · · · · · (收起)
HTML5 Canvas游戏开发实战》主要讲解使用HTML5 Canvas开发和设计各类常见游戏的思路和技巧,在介绍HTML5 Canvas相关特性的同时,还通过游戏开发实例深入剖析了其内在原理,让读者不仅知其然,而且知其所以然。在本书中,除了介绍了HTML5 Canvas的基础API之外,还重点阐述了如何在JavaScript中运用面向对象的编程思想来进行游戏开发。   《HTML5 Canvas游戏开发实战》在介绍每个游戏开发的过程时,都会包括游戏分析、开发过程、代码解析和小结等相关内容,以帮助读者了解每种类型游戏开发的详细步骤,让读者彻底掌握各种类型游戏开发思想。最后,还通过数据对比分析,指导读者提升程序的性能,写出高效的代码,从而开发出运行流畅的游戏。   《HTML5 Canvas游戏实战》主要讲解使用HTML5 Canvas来发和设计各类常见游戏的思路和技巧,在介绍HTML5 Canvas相关特性的同时,还通过游戏发实例深剖析了其内在原理,让读者不仅知其然,而且知其所以然。在本书中,除了介绍了HTML5 Canvas的基础API之外,还重阐述了如何在JavaScript中运用面向对象的编程思想来行游戏发。   《HTML5 Canvas游戏实战》在介绍每个游戏发的过程时,都会包括游戏分析、发过程、代码解析和小结等相关内容,以帮助读者了解每种类型游戏发的详细步骤,让读者彻底掌握各种类型游戏的发思想。最后,还通过数据对比分析,指导读者提升程序的性能,写出高效的代码,从而发出运行流畅的游戏。 【推荐语】   系统讲解HTML 5 Canvas的基础知识和高级技巧,深剖析源库件lufylegend的原理与使用   以实例为向导,详细讲解射游戏、物理游戏、网络游戏、页面游戏等各类游戏的发思路和技巧 【作者】   张路斌,资深前端发工程师和游戏发工程师,从事Web发和游戏发多年,精通HTML5和Flash等技术。HTML5游戏引擎lufylegend.js的发者,利用HTML5和Flash等技术独立发了大型网页游戏、Flash、多平台游戏三国记系列,以及数十款手机小游戏游戏发经验十分丰富。 前言 为什么要写这本书 读者对象 如何阅读本书 勘误和支持 致谢 第一部分 准备工作篇 第1章 准备工作 第二部分 基础知识篇 第2章 Canvas基本功能 第3章 Canvas高级功能 第4章 lufylegend开源库件 第三部分 开发实战篇 第5章 从简单做起—“石头剪子布”游戏 第6章 开发“俄罗斯方块”游戏 第7章 开发“是男人就下一百层”游戏 第8章 开发射击类游戏 第9章 开发物理游戏 第10章 开发网络游戏 第四部分 技能提高篇 第11章 提高效率的分析 。。。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值