javascript开发游戏(游戏开发之旅-JavaScript绘制图形)

本节是第四讲的第二十二小节,上一节课为大家介绍了Ajax技术,包括XmlHttpRequest对象和FetchAPI的基本用法,本节为大家继续介绍JavaScript绘制图形的方法(Canvas API),有关WebGL的实例请参见视频课程的内容。

网络图形

我们来讨论 HTML 的 多媒体和嵌入式 模块,早先的网页只有单调的文字,后来才引入了图像,起初是通过 <img> 元素的方式,后来出现了类似于 background-image 的 CSS 属性和 SVG 图像等方式。然而,这还不够好。当你能够使用 CSS 和 JavaScript 让 SVG 矢量图动起来时,位图却依然没有相应的支持。同时 SVG 动画的可用工具也少得可怜。有效地生成动画、游戏画面、3D场景和其他的需求依然没有满足,而这些在诸如 C 或者 Java 等低级语言中却司空见惯。当浏览器开始支持 HTML 画布元素 <canvas> 和相关的 Canvas API(由苹果公司在 2004 年前后发明,后来其他的浏览器开始跟进)时,形势开始改善。下面你会看到,canvas 提供了许多有用的工具,特别是当捆绑了由网络平台提供的一些其他的 API 时。它们用来生成 2D 动画、游戏画面和数据分析图,以及其他类型的 app。

2D画布基础

以下是绘制图形的基础代码:

<canvas class="myCanvas"></canvas>

var canvas = document.querySelector('.myCanvas');

var width = canvas.width = window.innerWidth;

var height = canvas.height = window.innerHeight;

var ctx = canvas.getContext('2d');

ctx.fillStyle = 'rgb(0, 0, 0)';

ctx.fillRect(0, 0, width, height);

所有绘画操作都离不开 CanvasRenderingContext2D 对象(这里叫做 ctx)。许多操作都需要提供坐标来指示绘图的确切位置,如下图所示,画布左上角的坐标是(0, 0),横坐标(x)轴向右延伸,纵坐标(y)轴向下延伸。

javascript开发游戏(游戏开发之旅-JavaScript绘制图形)(1)

简单矩形

ctx.fillStyle = 'rgb(255, 0, 0)';

ctx.fillRect(50, 50, 100, 150);

画布上将出现一个红色的矩形。其左边和顶边与画布边缘距离均为 50 像素(由前两个参数指定),宽 100 像素、高 150 像素(由后两个参数指定)。

ctx.fillStyle = 'rgba(255, 0, 255, 0.75)';

ctx.fillRect(25, 100, 175, 50);

通过指定半透明的颜色来绘制半透明的图形,比如使用 rgba()。 a 指定了“α 通道”的值,也就是颜色的透明度。值越高透明度越高,底层的内容就越清晰。

描边(stroke)和线条宽度

ctx.strokeStyle = 'rgb(255, 255, 255)';

ctx.strokeRect(25, 25, 175, 200);

ctx.lineWidth = 5;

目前我们绘制的矩形都是填充颜色的,我们也可以绘制仅包含外部框线(图形设计中称为描边)的矩形。你可以使用 strokeStyle 属性来设置描边颜色,使用 strokeRect 来绘制一个矩形的轮廓。默认的描边宽度是 1 像素,可以通过调整 lineWidth 属性的值来修改。

绘制路径

ctx.fillStyle = 'rgb(255, 0, 0)';

ctx.beginPath();

ctx.moveTo(50, 50);

// 绘制路径

ctx.fill();

可以通过绘制路径来绘制比矩形更复杂的图形。路径中至少要包含钢笔运行精确路径的代码以确定图形的形状。画布提供了许多函数用来绘制直线、圆、贝塞尔曲线等等。

一些通用的方法和属性将贯穿以下全部内容:

beginPath():在钢笔当前所在位置开始绘制一条路径。在新的画布中,钢笔起始位置为 (0, 0)。

moveTo():将钢笔移动至另一个坐标点,不记录、不留痕迹,只将钢笔“跳”至新位置。

fill():通过为当前所绘制路径的区域填充颜色来绘制一个新的填充形状。

stroke():通过为当前绘制路径的区域描边,来绘制一个只有边框的形状。

路径也可和矩形一样使用 lineWidth 和 fillStyle / strokeStyle 等功能。

等边三角形

function degToRad(degrees) {

return degrees * Math.PI / 180;

};

ctx.fillStyle = 'rgb(255, 0, 0)';

ctx.beginPath();

ctx.moveTo(50, 50);

ctx.lineTo(150, 50);

var triHeight = 50 * Math.tan(degToRad(60));

ctx.lineTo(100, 50 triHeight);

ctx.lineTo(50, 50);

ctx.fill();

首先绘制一条直线,终点坐标为 (150, 50)。此时路径沿 x 轴向右行走 100 像素。然后利用三角函数来计算等边三角形的高。这里我们要绘制的三角形是朝下的。等边三角形每个角均为 60°,为计算高的值,我们可以将三角形从正中心分割为两个直角三角形,每个直角三角形的三个角分别为 90°、60°、30°。

javascript开发游戏(游戏开发之旅-JavaScript绘制图形)(2)

通过基本三角函数可得:临边长度乘以角的正切等于对边长度。于是可得三角形的高为 50 * Math.tan(degToRad(60))。由于 Math.tan() 接受数值的单位为弧度,于是我们用刚才的 degToRad() 函数将 60° 换算为弧度。有了三角形的高,我们来绘制另一条线,终点坐标为 (100, 50 triHeight)。

画圆

ctx.fillStyle = 'rgb(0, 0, 255)';

ctx.beginPath();

ctx.arc(150, 106, 50, degToRad(0), degToRad(360), false);

ctx.fill();

arc() 函数有六个参数。前两个指定圆心的位置坐标,第三个是圆的半径,第四、五个是绘制弧的起、止角度(给定 0° 和 360° 便能绘制一个完整的圆),第六个是绘制方向(false 是顺时针,true 是逆时针)。

ctx.fillStyle = 'yellow';

ctx.beginPath();

ctx.arc(200, 106, 50, degToRad(-45), degToRad(45), true);

ctx.lineTo(200, 106);

ctx.fill();

将 arc() 的最后一个参数设置为 true,意味着弧将逆时针绘制,也就意味着即使起、止角度分别设置为 -45°、45°,我们还是得到了区域外的一条 270° 的弧。

文本

ctx.strokeStyle = 'white';

ctx.lineWidth = 1;

ctx.font = '36px arial';

ctx.strokeText('Canvas text', 50, 50);

ctx.fillStyle = 'red';

ctx.font = '48px georgia';

ctx.fillText('Canvas text', 50, 150);

fillText() :绘制有填充色的文本。

strokeText():绘制文本外边框(描边)。

这两个函数有三个基本的参数:需要绘制的文字、文本框(顾名思义,围绕着需要绘制文字的方框)左上顶点的X、Y坐标。

还有一系列帮助控制文本渲染的属性:比如用于指定字体族、字号的 font,它的值和语法与 CSS 的 font 属性一致。

在画布上绘制图片

var image = new Image();

image.src = 'flower.png';

ctx.drawImage(image, 20, 20, 185, 175, 50, 50, 185, 175);

第一个参数为图片引用。参数 2、3 表示裁切部分左上顶点的坐标,参考原点为原图片本身左上角的坐标。原图片在该坐标左、上的部分均不会绘制出来。参数 4、5 表示裁切部分的长、宽。参数 6、7 表示裁切部分左上顶点在画布中的位置坐标,参考原点为画布左上顶点。参数 8、9 表示裁切部分在画布中绘制的长、宽。

创建一个循环

ctx.translate(width/2, height/2);

function degToRad(degrees) {

return degrees * Math.PI / 180;

};

var length = 250;

var moveOffset = 20;

for(var i = 0; i < length; i ) {

ctx.fillStyle = 'rgba(' (255-length) ', 0, ' (255-length) ', 0.9)';

ctx.beginPath();

ctx.moveTo(moveOffset, moveOffset);

ctx.lineTo(moveOffset length, moveOffset);

var triHeight = length/2 * Math.tan(degToRad(60));

ctx.lineTo(moveOffset (length/2), moveOffset triHeight);

ctx.lineTo(moveOffset, moveOffset);

ctx.fill();

length--;

moveOffset = 0.7;

ctx.rotate(degToRad(5));

}

translate(),可用于移动画布的原点,将 canvas 按原始 x点的水平方向、原始的 y点垂直方向进行平移变换。

在每次迭代中:设置 fillStyle 为略透明的紫色渐变色。渐变由每次迭代时 length 值的改变实现。随着循环的运行, length 值逐渐变小,从而使连续的三角形颜色逐渐变亮。

开始路径。

将钢笔移动至坐标 (moveOffset, moveOffset);该变量定义了每次要绘制新三角形时需要移动的距离。

画一条直线,终点坐标为 (moveOffset length, moveOffset)。即一条长度为 length 与 X 轴平行的线。

计算三角形的高,方法同上。

向三角形底部顶点方向绘制一条直线,然后向三角形的起始点绘制一条直线。

调用 fill() 为三角形填充颜色。

更新次序变量,准备绘制下一个三角形。length 的值减一,使三角形每次迭代都变小一些;小幅增加 moveOffset 的值,使得下一个三角形略微错位;用一个新函数 rotate() 来旋转整块画布,在绘制下个三角形前画布旋转 5°。

以上内容部分摘自视频课程04网页游戏编程JavaScript-22绘制图形,更多示例请参见网站示例。跟着张员外讲编程,学习更轻松,不花钱还能学习真本领。

,

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。文章投诉邮箱:anhduc.ph@yahoo.com

    分享
    投诉
    首页