26.运用物理知识创建动画(1)
本节将创建一个简单的太空场景,其中在太空深处有一个动态的小行星群。
1、准备工作
本节开头的JavaScript代码并没有什么特别之处,实际上,它与上一章使用的代码几乎完全相同。主要的不同之处在于,上一章使用的对象是形状,而本章使用的对象是小行星。
将以下代码添加到一个外部JavaScrit文件中,并用一个可读性强的名称为其命名,如astcroids.js:
$(document).ready(function() { var canvas = $("#myCanvas"); var context = canvas.get(0).getContext("2d"); var canvasWidth = canvas.width(); var canvasHeight = canvas.height(); $(window).resize(resizeCanvas); function resizeCanvas() { canvas.attr("width", $(window).get(0).innerWidth); canvas.attr("height", $(window).get(0).innerHeight); canvasWidth = canvas.width(); canvasHeight = canvas.height(); }; resizeCanvas(); var playAnimation = true; var startButton = $("#startAnimation"); var stopButton = $("#stopAnimation"); startButton.hide(); startButton.click(function() { $(this).hide(); stopButton.show(); playAnimation = true; animate(); }); stopButton.click(function() { $(this).hide(); startButton.show(); playAnimation = false; }); var Asteroid = function(x, y, radius) { this.x = x; this.y = y; this.radius = radius; }; var asteroids = new Array(); for (var i = 0; i < 10; i++) { var x = 20+(Math.random()*(canvasWidth-40)); var y = 20+(Math.random()*(canvasHeight-40)); var radius = 5+Math.random()*10; asteroids.push(new Asteroid(x, y, radius)); }; function animate() { context.clearRect(0, 0, canvasWidth, canvasHeight); context.fillStyle = "rgb(255, 255, 255)"; var asteroidsLength = asteroids.length; for (var i = 0; i < asteroidsLength; i++) { var tmpAsteroid = asteroids[i]; context.beginPath(); context.arc(tmpAsteroid.x, tmpAsteroid.y, tmpAsteroid.radius, 0, Math.PI*2, false); context.closePath(); context.fill(); }; if (playAnimation) { setTimeout(animate, 33); }; }; animate(); });
下一步就是构造CSS文件,让画布的尺寸与浏览器窗口同宽。另外,还要使用CSS来移动Start和Stop按钮,因为如果不这样做,当画布占据整个窗口时,这些按钮将位于浏览器之外。
将包含以下代码的外部CSS文件和JavaScript文件放在相同的目录下,并用一个可读性强的名称为其命名,如canvas.css:
* { margin: 0; padding: 0; } html, body { height: 100%; width: 100%; } canvas { display: block; } #myCanvas { background: #001022; } #myButtons { bottom: 20px; left: 20px; position: absolute; } #myButtons button { padding: 5px; }
最后,你需要建立一个HTML文件将所有文件整合到一起。这与上一章建立的HTML文件完全相同,不过文件要小得多,因为所有的JavaScript代码都在一个外部文件中。注意这里新加了一个script元素调用JavaScript文件。如果你的文件名不叫asteroids.js,就需要更改调用文件的名称。
将包含以下代码的HTML文件和其他文件放在相同的目录下,并命名为index.html:
<!DOCTYPE html> <html> <head> <title>Implementing advanced animation</title> <meta charset="utf-8"> <link href="canvas.css" rel="stylesheet" type="text/css"> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script> <script type="text/javascript" src="asteroids.js"></script> </head> <body> <canvas id="myCanvas" width="500" height="500"> <!-- Insert fallback content here --> </canvas> <div id="myButtons"> <button id="startAnimation">Start</button> <button id="stopAnimation">Stop</button> </div> </body> </html>
如果使用现代浏览器加载该html页面,应该会看到一个蓝色的宽大背景(画布),在其左下角有一个Stop接钮和一群四散分布的小行星(Animating with physics_1.html)。单击Stop按钮可以让背景中的动画停下来。
2、速度
前面的教程介绍过通过增加或减少形状的x和y位置来移动形状,同样的方法也可以赋予每个形状速度。速度包括物体的速率和方向。速率是指像素移动的数目,方向是指向左和向右(x)、向上和向下(y)。
上一章中的速度存在的问题是,它们要么是完全随机的,要么是完全相同的。因此,我们可以将这两种情况中和一下,让每颗小行星采用不同的飞行速度。为此,你需要在Asteroid类中定义两个新属性,代码如下:
var Asteroid = function(x, y, radius, vX, vY) { this.x = x; this.y = y; this.radius = radius; this.vX = vX; this.vY = vY; };
适过添加vX和vY属性,现在每颗小行星可以拥有各自不同的速度.注意类函数中参数vX和vY的设置方法,当你创建一颗新的小行星时,可以通过这两个参数来设置速度。那么,接下来需要为每颗小行星设置不同的速度,速度定义了每个动画循环中小行星移动的像素数目。
为了在循环中创建所有的小行星,需要在radius变量下面添加以下代码:
var vX = Math.random()*4-2; var vY = Math.random()*4-2;
另外,还需要使用以下代码替换radius变量下一行的代码,以便把新的速度作为参数传递给Asteroid类:
asteroids.push(new Asteroid(x, y, radius, vX, vY));
在本示例中,在x轴和y轴上同时将速度设置为一个介于-2到2之间的随机数。Math.random方法将会产生一个介于0到1之间的小数。因此,为了得到一个介于-2到2之间的数,需要分两步完成。第一步,将随机数乘以4,得到一个介于0到4之间的随机数。第二步非常简单,只需将该随机数减去2,这样将得到一个介于-2(0减2)到2(4减2)之间的数。你可以使用该方法计算介于任意范围内的随机数。
仅对代码进行这些修改,还不能改变小行星的速度。你还需要使用新的速度属性来更新每颗小行星的x和y位置。在动画循环中的tmpAsteroid变量声明下面添加以下代码:
tmpAsteroid.x += tmpAsteroid.vX; tmpAsteroid.y += tmpAsteroid.vY;
小行星的当前位置增加了一个确定的像素数。现在每颗小行星各自有了不同的速度,这说明它们将会以不同的速率(每个循环的像素数)和方向运动。有些动画看上去非常自然和流畅,其秘诀就在于实现了这种不同速度的运动。
刷新或加载该HTML文件,你应该会看到一群类似于小行星的物体在画布上运动(Animating with physics_2.html)。继续刷新页面,可以看到这些小行星将从不同的位置出发,并以不同的速度运动。目前画布中还没有边界,当小行星运动到屏幕的边界快要消失时,你可以单击Stop按钮来留住它们。
文件下载(已下载 2265 次)发布时间:2013/3/20 下午2:34:18 阅读次数:7580