2.游戏中的数学知识
在游戏的开发中,数学知识特别是其中的三角函数使用特别广泛
2.1 角度
在使用canvas来制作动画的过程中,我们使用到的角度都是以弧度为单位的,角度与弧度之间的换算单位如下:
radians=degrees*Math.PI/180
同时,在canvas中的坐标系是以右上角为原点(0,0),向左为x轴增加方向,向下为y轴增加方向。因此,需要特别注意canvas中角度是以顺时针为方向的,这与我们在生活中角度为逆时针相反。如下图:
在三角函数中,最常用的有三个,Math.cos,Math.sin与Math.atan2,注意计算反正切的有两个函数Math.atan与Math.atan2,后者需要传入对边dy与邻边dx来求得精确的角度(在[-180,180]中正切值相同的角度会有两个)。如下:
可以看出,对D角使用Math.atan2来得到的值将为-153.43。因此,如果我们需要求得任意一点P(x,y)与原点连线的角度,使用Math.atan2(y,x)即可。
2.2 旋转
在游戏开发中,我们经常会碰到对于画布中对象的旋转,即使用到context.rotate方法,而其角度大多数情况下通过上述的Math.atan2(dy,dx)获得。计算一个动点与一个静点之间的实时角度,假设静点为originX,originY,动点为x,y. 则
α=Math.atan2(y-originY,x-originX)
如果给静点的rotation方法传入α后重绘,就会出现实时地让静点指向动点。如下即为一个随着鼠标移动而随时指向鼠标的箭头实现。
//箭头类
function Arrow(){
//定义位置属性
this.x=0;
this.y=0;
//定义旋转角度及缩放
this.rotation=0;
this.scaleX=1;
this.scaleY=1;
//定义填充色及画笔宽度
this.color='#00ff00';
this.lineWidth=1;
}
//绘制方法
Arrow.prototype.paint=function(context){
//保存场景
context.save();
//坐标系转换,缩放及旋转
context.translate(this.x,this.y);
context.scale(this.scaleX,this.scaleY);
context.rotate(this.rotation);
//定义填充色及画笔
context.fillStyle=this.color;
context.lineWidth=1;
//绘制箭头
context.beginPath();
context.moveTo(-50,-25);
context.lineTo(0,-25);
context.lineTo(0,-50);
context.lineTo(50,0);
context.lineTo(0,50);
context.lineTo(0,25);
context.lineTo(-50,25);
context.closePath();
//填充
context.fill();
if(context.lineWidth>0){
context.stroke();
}
context.restore();
}
2.3 波动
正弦与余弦的曲线都是一条规律性的波动曲线,游戏中很多对象的往复运动就是按正余弦规律来进行的。使用canvas我们很容易就能绘制出一条正弦曲线。如下:
//绘制Sin曲线,给定起始点坐标及波动高与宽
function getSinWave(context,x,y,width,height){
context.save();
context.translate(x,y);
context.beginPath();
for(var i=0;i<360;i+=0.1){ context.lineTo(i*width,Math.sin(i*width*Math.PI/180)*height);
context.stroke();
context.restore();
}
弹簧振子往复运动
对于物理学中的弹簧振子来说,其在一个坐标轴中的运动就是正余弦曲线在Y轴上的投影。如下为一个小球的运动。
//小球类,给定半径及填充色
function Ball(radius,color){
//设置球心及缩放,边缘线宽
this.x=0;
this.y=0;
this.radius=radius||20;
this.color=color||'#ffff00';
this.scaleX=1;
this.scaleY=1;
this.lineWidth=1;
}
//定义绘制方法
Ball.prototype.paint=function(context){
context.save();
//坐标转换
context.translate(this.x,this.y);
context.scale(this.scaleX,this.scaleY);
context.fillStyle=this.color;
context.lineWidth=this.lineWidth;
context.beginPath();
//绘制球
context.arc(0,0,this.radius,0,Math.PI*2,true);
context.closePath();
context.fill();
if(context.lineWidth>0){
context.stroke();
}
context.restore();
};
如下为具体的呈现HTML文档,在utils.js中定义了window.requestAnimFrame的实现类(详见分享一).
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Ball</title>
</head>
<body>
<canvas id="canvas" width="400" height="400"></canvas>
<script type="text/javascript" src="utils.js"></script>
<script type="text/javascript" src="ball.js"></script>
<script type="text/javascript">
window.onload=function(){
//获取canvas标签引用及canvas绘图上下文context
var canvas=document.getElementById("canvas");
var context=canvas.getContext("2d");
//实例化小球
var ball=new Ball();
ball.x=canvas.width/2;
ball.y=canvas.height/2;
//初始化角度及角度增加系数
var angle=0;
var vr=1*Math.PI/180;
(function animationLoop(){
window.requestAnimFrame(animationLoop,canvas);
context.clearRect(0,0,canvas.width,canvas.height);
//以60帧的速度来绘制弹簧振子小球的运动
ball.x=canvas.width/2*(1-Math.cos(angle));
angle+=vr;
ball.paint(context);
})();
};
</script>
</body>
</html>
线性垂直波动
如果给以正余弦方式垂直运动的对象加上一个横向的线速度,那就会动态地绘制出一个正余弦曲线。我们为ball添加vx,vy属性。
(function aniamtionLoop(){
window.requestAnimation(animationLoop,canvas);
context.clearRect(0,0,canvas.width,canvas.height);
ball.x+=ball.vx;
angle+=ball.vy*Math.PI/180;
ball.y=Math.cos(angle)*canvas.height/2;
ball.paint(context);
})();
脉冲效果
除了为对象在X与Y轴方向上添加正余弦变化的速度外,也可以为对象的其它属性, 如尺寸添加一个按正弦变化的值,这将会产生一种脉冲效果。
ball.scaleX=ball.scaleY=Math.PI*angle/180;
此处使用的是同一个变化量,其实也可以为不同的属性指定不同的角度。
圆周运动
对一个圆周上运动的对象来说,其任意时刻在圆周上的位置可以使用半径与三角函数来表示。即P(x,y)=P(r1*cosα,r2*sinα)。如果r1=r2,则运动对象的轨迹为一个正圆,否则其轨迹为一个椭圆。
ball.x=canvas.width/2+Math.cos(angle)*radiusX;
ball.y=canvas.height/2+Math.sin(angle)*radiusY;
三角函数在动画中计算坐标,最常见的一定是使用余弦Math.cos来计算横坐标x,使用正弦Math.sin来计算纵坐标y。
勾股定理及距离计算
距离的计算相当常见,我们只需要在坐标系中使用勾股定理,即A(x0,y0)到B(x1,y1)之间的距离为
var dx=B.x-A.x;
var dy=B.y-A.y;
var distance=Math.sqrt(dx*dx+dy*dy);
- 大小: 5.1 KB
- 大小: 3.2 KB
分享到:
相关推荐
canvas拼图游戏,基于html + canvas画布实现
H5 canvas 实现小游戏 H5 canvas 实现小游戏 H5 canvas 实现小游戏 H5 canvas 实现小游戏
HTML5 Canvas 赛车游戏动画DEMO演示 键盘控制车的方向
canvas端午节小游戏
利用canvas画布,进行撞击,消除操作的小游戏
canvas拼图小游戏
html5 开发技术 游戏.很好玩的html5+canvas技术实现的拼图游戏
试验性质的一个微信小程序,用canvas做的一个类似flappy-bird的小游戏。 包含一些基本的功能:躲避障碍物、计分、排行榜等等。后端的工程也一并上传了,在java目录中,很简单的一个SpringMVC工程。 游戏原型见这里。...
通过一个简单的例子,讲解如何在HTML5 canvas中开发游戏,主要是定时器的用法值得大家借鉴
canvas端午节吃粽子小游戏,兼容移动端
canvas 飞机大战小游戏
canvas 实现2d 简单小游戏,点击出现蓝色攻击方块,攻击黑色方块得分,触碰红色方块游戏结束,黑色方块想灭完,游戏等级提升
HTML5 Canvas赛车游戏动画,赛车游戏动画演示。
HTML 5 CANVAS游戏开发实战HTML 5 CANVAS游戏开发实战HTML 5 CANVAS游戏开发实战
canvas-弹珠游戏
HTML 5 CANVAS游戏开发实战
canvas打砖块小游戏
1.open-type=“share”,onShareAppMessage实现分享微信功能。2.canvas绘制分享海报。
HTML5+CANVAS游戏开发实战,很值得学习,就算不是做游戏,但是对js的进阶也很有好处。
canvas版的2048小游戏,canvas版的2048小游戏,canvas版的2048小游戏,canvas版的2048小游戏,canvas版的2048小游戏