当前位置: 代码迷 >> Web前端 >> Canvas干游戏实践分享(七)
  详细解决方案

Canvas干游戏实践分享(七)

热度:90   发布时间:2012-11-19 10:18:51.0
Canvas做游戏实践分享(七)

4.2 加速度

??? 加速度是改变速度大小及方向的一个属性,在物体受力的过程中,会产生加速度来改变速度的大小及方向。加速度的处理与速度的处理非常类似。

一维坐标系统下的加速度

??? 一维坐标系统下加速度的实现很简单,我们仍然使用小球系统来模拟,为小球对象添加X轴与Y轴上的加速度属性。实现起来有两步:初始化加速度值,在每一帧开始时为速度增加加速度的值。如下:

ball.ax=INITIAL_ACCELERATE_VELOCITY;
ball.vx+=ball.ax;    //将此句放置于animationLoop中

?二维坐标系统下的加速度

?? ?与二维坐标系统下的速度处理方式相同,二维坐标系统下的加速度处理如下:

ball.ax=INITIAL_ACCELERATE_VELOCITY_X;
ball.ay=INITIAL_ACCELERATE_VELOCITY_Y;
ball.vx+=ax;     //将此两句放置于animationLoop中
ball.vy+=ay;  
?

重力加速度

?? ?重力加速度是一种特殊的加速度。对其的处理可以当作一维坐标(Y轴)系统下的加速度来处理:

ball.vy+=gravity;       //gravity是重力加速度常量
?

已知初始方向及大小的加速度

????? 前面我们实现的都是已知两个正交坐标轴方向加速度大小的运动,但在实际应用中,这种情况很少见,更多的是已知加速度的大小及方向的运动。此时,我们就需要使用之前介绍的三角函数。常见的变换如下:

ax=Math.cos(angle)*A;
ay=Math.sin(angle)*A;

?

我们对之前在速度处理中实现的鼠标跟随效果进行改进,在其中引入加速度处理,核心代码实现如下:

                 window.onload=function(){
                               //初始化变量
                               ?var canvas=document.getElementById("canvas");
				var context=canvas.getContext("2d");
				var mouse=utils.captureMousePosition(canvas);
				var accelerateSpeed=1;
                                //绘制箭头
				var arrow=new Arrow();
				arrow.x=canvas.width/2;
				arrow.y=canvas.height/2;

				(function animationLoop(){
					window.requestAnimFrame(animationLoop,canvas);
			                context.clearRect(0,0,canvas.width,canvas.height);
                                        //取得由箭头中心指向鼠标位置的向量方向,并旋转箭头
					var dx=mouse.x-arrow.x;
					var dy=mouse.y-arrow.y;
					var angle=Math.atan2(dy,dx);
					arrow.rotation=angle;
                                        //通过三角函数求得加速度,并对应改变速度及位置
                                       ?arrow.vx+=Math.cos(angle)*accelerateSpeed;
					arrow.vy+=Math.sin(angle)*accelerateSpeed;
					arrow.x+=arrow.vx;
					arrow.y+=arrow.vy;

					arrow.paint(context);
				})();
			};

?运行代码,会发现效果很像一个水平摆。

加速度实例――宇宙飞船

?? ?加速度一个很好的实例就是飞船的起飞和降落。我们会逐渐实现一个简易的飞船。如下,是一个用三角形构成的飞船模型:

function Ship(){
        //定义飞船属性
       ?this.x=0;
	this.y=0;
        this.vx=0;
        this.vy=0;
       ?this.rotation=0;
	this.width=25;
	this.height=20;
	this.showFlame=false;
}

Ship.prototype.paint=function(context){
	context.save();
        //定义画面属性
       ?context.translate(this.x,this.y);
	context.rotate(this.rotation);
	context.lineWidth=1;
	context.strokeStyle='#ffffff';
        //绘制飞船
       ?context.beginPath();
	context.moveTo(10,0);
	context.lineTo(-10,10);
	context.lineTo(-5, 0);
	context.lineTo(-10, -10);
	context.lineTo(10, 0);
	context.stroke();
        //绘制喷火   
       ?if(this.showFlame){
		context.beginPath();
		context.moveTo(-7.5, -5);
		context.lineTo(-15, 0);
		context.lineTo(-7.5, 5);
		context.stroke();
	}
	context.restore();	
};

?以上代码实现了一个简单的飞船模型,飞船在加速时会喷火,如下图:


?

<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8" />
        <title>Arrow</title>
        <style type="text/css">
            #canvas {
                border-bottom: 1px solid #ffffff;
                background-color: #000000;
            }
        </style>
    </head>
    <body>
        <canvas id="canvas" width="400" height="400"></canvas>
        <script type="text/javascript" src="utils.js"></script>
        <script type="text/javascript" src="ship.js"></script>
        <script type="text/javascript">
            window.onload=function(){
                var canvas=document.getElementById("canvas");
                var context=canvas.getContext("2d");

                var ship=new Ship();
                ship.x=canvas.width/2;
                ship.y=canvas.height/2;

                var vr=0;
                var f=0;
                //处理键盘事件
                window.addEventListener("keydown",function(event){
                    console.log(event.keyCode);
                    switch(event.keyCode){
                        case 37:  //左,逆时针转
                            vr=-3;
                            break;
                        case 39:  //右,顺时针转
                            vr=3;
                            break;
                        case 38:  //上,加速
                            f=0.05;
                            ship.showFlame=true;
                            break;
                    }
                });
               //按键松开时恢复相关属性为默认值
                window.addEventListener("keyup",function(event){
                    ship.showFlame=false;
                    vr=0;
                    f=0;
                },false);
               
                (function animationLoop(){
                    window.requestAnimFrame(animationLoop,canvas);
                    context.clearRect(0,0,canvas.width,canvas.height);
                    //通过角度和大小来确定加速度,从而确定飞船的速度与位置
                   ?ship.rotation+=vr*Math.PI/180;
                    ship.vx+=Math.cos(ship.rotation)*f;
                    ship.vy+=Math.sin(ship.rotation)*f;
                    ship.x+=ship.vx;
                    ship.y+=ship.vy;
                    ship.paint(context);
                })();
            };
        </script>
    </body>
</html>
?

如此,实现了一个利用加速度的飞船模型,左右箭头是用来控制旋转方向的,上箭头是用来加速的。但很快飞船就跑出画布了,之后我们会介绍如何来进行边界控制。