当前位置:嗨网首页>书籍在线阅读

18-简单重力

  
选择背景色: 黄橙 洋红 淡粉 水蓝 草绿 白色 选择字体: 宋体 黑体 微软雅黑 楷体 选择字体大小: 恢复默认

5.4.1 简单重力

可以通过对在矢量上移动的对象的y轴速度应用一个重力常数来实现简单而真实的重力效果。为此,选择一个重力值,比如.1,然后在每次调用drawScreen()函数的时候将它添加到对象的y轴速度中。

在这个例子中,模拟一个半径为15像素的球,从一个加农炮中发射出来落到画布底部附近。这个球将以每帧4像素的速度移动,发射角度为305°。这意味着,它将向画布的右上方移动。如果不添加重力,这个球将在移出画布前沿矢量移动(实际上,它将一直移动下去,只是看不见而已)。

创建类似效果的代码在前面曾经出现过了。在canvasApp()函数中,需要创建以下初始的变量。

var speed = 4;
var angle = 305;
var radians = angle * Math.PI/ 180;
var radius = 15;
var vx = Math.cos(radians)* speed;
var vy = Math.sin(radians)* speed;

下面,创建这个球的起始点p1,然后创建一个动态对象,控制为ball对象创建的所有数值。

var p1 = {x:20,y:theCanvas.height-radius};
var ball = {x:p1.x, y:p1.y, velocityx: vx, velocityy:vy, radius:radius};

如果要给应用程序增加重力,首先应该创建一个新的变量gravity并将其设为常数0.1。

var gravity = .1;

接下来,在drawScreen()函数中,在将其绘制到画布上时,为ball对象应用这个重力值(ball.velocityy += gravity)。当这个球碰到“地面”(画布底部)时应该停止,因此,就要测试ball对象y坐标加上球的半径(radius)是否已经超出了画布底部边界(ball.y + ball.radius <= theCanvas.height)。如果是,就让这个球停止运动。

if (ball.y + ball.radius <= theCanvas.height){
  ball.velocityy += gravity;
} else {
  ball.velocityx = 0;
  ball.velocityy = 0;
  ball.y = theCanvas.height - ball.radius;
}

下面,将x轴速度常数和新的y轴速度应用到ball对象中,并将其绘制到画布上。

ball.y += ball.velocityy;
ball.x += ball.velocityx;
context.fillStyle = "#000000";
context.beginPath();
context.arc(ball.x,ball.y,ball.radius,0,Math.PI*2,true);
context.closePath();
context.fill();

对球应用简单重力后,沿矢量的移动路径如图5-18所示。图中用点指示路径。

95.png

图5-18 应用简单重力的矢量移动对象

读者可以使用CH5EX14.html文件中的代码进行测试,也可以输入例5-14中的全部代码。

例5-14 简单重力

<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>CH5EX14: Simple Gravity</title>
<script src="modernizr.js"></script>
<script type="text/javascript">
window.addEventListener('load', eventWindowLoaded, false);
function eventWindowLoaded(){
  canvasApp();
}
function canvasSupport (){
   return Modernizr.canvas;
}
function canvasApp(){
  if (!canvasSupport()){
      return;
    }
 function drawScreen (){
   context.fillStyle = '#EEEEEE';
   context.fillRect(0, 0, theCanvas.width, theCanvas.height);
   //边框
   context.strokeStyle = '#000000';
   context.strokeRect(1, 1, theCanvas.width-2, theCanvas.height-2);
   if (ball.y + ball.radius <= theCanvas.height){
     ball.velocityy += gravity;
   } else {
     ball.velocityx = 0;
     ball.velocityy = 0;
     ball.y = theCanvas.height - ball.radius;
   }
   ball.y += ball.velocityy;
   ball.x += ball.velocityx;
   context.fillStyle = "#000000";
   context.beginPath();
   context.arc(ball.x,ball.y,ball.radius,0,Math.PI*2,true);
   context.closePath();
   context.fill();
  }
  var speed = 4;
  var gravity = .1;
  var angle = 305;
  var radians = angle * Math.PI/ 180;
  var radius = 15;
  var vx = Math.cos(radians)* speed;
  var vy = Math.sin(radians)* speed;
  theCanvas = document.getElementById("canvasOne");
  context = theCanvas.getContext("2d");
  var p1 = {x:20,y:theCanvas.height-radius};
  var ball = {x:p1.x, y:p1.y, velocityx: vx, velocityy:vy, radius:radius};
  function gameLoop() {
   window.setTimeout(gameLoop, 20);
   drawScreen()
  }
  gameLoop();
}
</script>
</head>
<body>
<div style="position: absolute; top: 50px; left: 50px;">
<canvas id="canvasOne" width="500" height="500">
 Your browser does not support HTML5 Canvas.
</canvas>
</div>
</body>
</html>