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按钮来留住它们。
文件下载(已下载 2268 次)发布时间:2013/3/20 下午2:34:18 阅读次数:8428
