摩擦力是与物体运动方向相反的力。我们在处理物体运动时,常把物体分解水平(X轴)方向和竖直(Y轴)方向的运动(比如平抛运动),但在处理摩擦力时,如果把摩擦力分解为X轴和Y轴上的阻力,就会出现某条轴上速度为0,而另一条轴还在运动的奇怪现象。为此,处理摩擦力时应将物体最终运动的方向作为基准。

首先计算出合速度:

var speed = Math.sqrt(vx * vx + vy * vy);

分析后可知

夹角θ可通过Math.atan2算出:

var angle = Math.atan2(vy,vx);

接下就是由速度减去摩擦力,但要注意不能速度变为负值,这样会改变物体的运动状态:

if(speed > friction) {
speed -= friction;
} else {
speed = 0;
}

在得到中和了摩擦力的速度以后,再将速度分解为水平和竖直方向的运动:

vx = Math.cos(angle) * speed;
vy = Math.sin(angle) * speed;

// > 16 & 0xff,
g = color >> 8 & 0xff,
b = color >> 0xff,
a = (alpha 1) ? 1 : alpha);

if(a === 1) {
return 'rgb('+r+','+g+','+b+')';
} else {
return 'rgba('+r+','+g+','+b+','+a+')';
}
};

window.utils.parseColor = function (color, toNumber) {
if (toNumber === true) {
if (typeof color === 'number') {
return (color | 0); //chop off decimal
}
if (typeof color === 'string' && color[0] === '#') {
color = color.slice(1);
}
return window.parseInt(color, 16);
} else {
if (typeof color === 'number') {
color = '#' + ('00000' + (color | 0).toString(16)).substr(-6); //pad
}
return color;
}
};

window.utils.containsPoint = function (rect, x, y) {
return !(x rect.x + rect.width ||
y rect.y + rect.height);
};

window.utils.intersects = function (rectA, rectB) {
return !(rectA.x + rectA.width 0) {
ctx.stroke();
}
ctx.restore();
};

function Ship () {
this.x = 0;
this.y = 0;
this.width = 25;
this.height = 20;
this.rotation = 0;
this.showFlame = false;
}

Ship.prototype.draw = function (ctx) {
ctx.save();
ctx.translate(this.x, this.y);
ctx.rotate(this.rotation);

ctx.lineWidth = 1;
ctx.strokeStyle = "#ffffff";
ctx.beginPath();
ctx.moveTo(10, 0);
ctx.lineTo(-10, 10);
ctx.lineTo(-5, 0);
ctx.lineTo(-10, -10);
//ctx.lineTo(10, 0);
ctx.closePath();
ctx.stroke();

if (this.showFlame) {
ctx.beginPath();
ctx.moveTo(-7.5, -5);
ctx.lineTo(-15, 0);
ctx.lineTo(-7.5, 5);
ctx.stroke();
}
ctx.restore();
};
// ]]>

 

// friction) {
speed -= friction;
} else {
speed = 0;
}

vx = Math.cos(angle) * speed;
vy = Math.sin(angle) * speed;

ball.x += vx;
ball.y += vy;
ball.draw(ctx);
})();
})();
// ]]>

虽然上面是计算摩擦力的正确方法,但太过繁琐了,还有一个简便方法

(function() {
window.requestAnimFrame(arguments.callee,canvas);
ctx.clearRect(0,0,canvas.width,canvas.height); vx *= 0.9;
vy *= 0.9; ball.x += vx;
ball.y += vy;
ball.draw(ctx);
})();

就是将速度分量分别乘以一个摩擦力系数,这个方法的运动效果和之前没有差别,但这个方法永远不会停止,还需要做一些判断以减少运算量:

if(Math.abs(vx) > 0.001) {
vx *= friction;
ball.x += vx;
}

在了解了如何计算摩擦力后,再来看看它的应用。

 

// right) {
ship.x = left - ship.width / 2;
} else if(ship.x + ship.width / 2 bottom) {
ship.y = top - ship.height / 2;
} else if(ship.y + ship.height / 2

Canvas学习笔记——动画中摩擦力的运用的更多相关文章

  1. Canvas学习笔记——动画中的三角学

    示例1,跟随鼠标的键头:   需要掌握一个重要的公式,这个方法返回从 x 轴到点 (x,y) 之间的角度 Math.atan2(dy,dx); 关键代码: function Arrow() { thi ...

  2. Canvas学习笔记——动画环境中的边界

    在动画中经常要处理边界问题,比如一个物体运动到了边界,要怎么处理才合适呢?通常有几种以下几种方式: 让物体消失 // > 16 & 0xff, g = color >> 8 ...

  3. ArcGIS案例学习笔记-点集中最近点对和最远点对

    ArcGIS案例学习笔记-点集中最近点对和最远点对 联系方式:谢老师,135-4855-4328,xiexiaokui@qq.com 目的:对于点图层,查找最近的点对和最远的点对 数据: 方法: 1. ...

  4. canvas学习笔记、小函数整理

    http://bbs.csdn.net/topics/391493648 canvas实例分享 2016-3-16 http://bbs.csdn.net/topics/390582151 html5 ...

  5. 《Cocos2d-x游戏开发实战精解》学习笔记3--在Cocos2d-x中播放声音

    <Cocos2d-x游戏开发实战精解>学习笔记1--在Cocos2d中显示图像 <Cocos2d-x游戏开发实战精解>学习笔记2--在Cocos2d-x中显示一行文字 之前的内 ...

  6. canvas学习笔记,实用知识点总结(上)

    本博客是本人日常学习笔记,作为重要知识点的总结记录,随笔风格可能更倾向于个人的学习习惯和方式,若对您有帮助十分荣幸,若存在问题欢迎互相学习探讨,前端小白一枚在此恭候. 一.基本使用规则 1.创建画布 ...

  7. canvas学习笔记(下篇) -- canvas入门教程--保存状态/变形/旋转/缩放/矩阵变换/综合案例(星空/时钟/小球)

    [下篇] -- 建议学习时间4小时  课程共(上中下)三篇 此笔记是我初次接触canvas的时候的学习笔记,这次特意整理为博客供大家入门学习,几乎涵盖了canvas所有的基础知识,并且有众多练习案例, ...

  8. canvas学习笔记(中篇) -- canvas入门教程-- 颜色/透明度/渐变色/线宽/线条样式/虚线/文本/阴影/图片/像素处理

    [中篇] -- 建议学习时间4小时  课程共(上中下)三篇 此笔记是我初次接触canvas的时候的学习笔记,这次特意整理为博客供大家入门学习,几乎涵盖了canvas所有的基础知识,并且有众多练习案例, ...

  9. canvas学习笔记(上篇)-- canvas入门教程 -- canvas标签/方块/描边/路径/圆形/曲线

    [上篇] -- 建议学习时间4小时  课程共(上中下)三篇 此笔记是我初次接触canvas的时候的学习笔记,这次特意整理为博客供大家入门学习,几乎涵盖了canvas所有的基础知识,并且有众多练习案例, ...

随机推荐

  1. kb-01-d<poj3279>--深搜变种,二进制优化;

    poj--3279 题意: 给n*m的矩阵,0 1组成,每次翻转一个格子可以将上下左右的五个节点翻转,求,把所有的格子翻转成0:输出每个个字的翻转次数:最少字数: 做法: 从上到下,第一行翻转的情况确 ...

  2. 在 Ubuntu 16.04 上安装 Eclipse Oxygen

    2017 年 6 月 28 日,Eclipse 社区(the Eclipse Community)发布了 Eclipse Oxygen.本文记录了我在 Ubuntu 16.04 上安装 Eclipse ...

  3. NOJ——1274The battle of Red Cliff(并查集按秩合并)

    [1274] The battle of Red Cliff 时间限制: 1000 ms 内存限制: 65535 K 问题描述 Zero loves palying Sanguo game very ...

  4. HDU——2723Electronic Document Security(STL map嵌套set做法)

    Electronic Document Security Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K ( ...

  5. [HDU4362] Palindrome subsequence (区间DP)

    题目链接 题目大意 给你几个字符串 (1<len(s)<1000) ,要你求每个字符串的回文序列个数.对于10008取模. Solution 区间DP. 比较典型的例题. 状态定义: 令 ...

  6. 关于postman使用上发现的一点问题

    之前后台用的java,一直用的postman测试接口数据,之前不管是get.post.delete.put请求都是在param传递的数据,java下面是没问题可以测试的.但是今天自己写Node发现po ...

  7. svn的简单知识

    svn的简单知识 一.简介: SVN是Subversion的简称,是一个开放源代码的版本控制系统,相较于RCS.CVS,它采用了分支管理系统, 它的设计目标就是取代CVS.互联网上很多版本控制服务已从 ...

  8. indexOf()、includes()、startsWith()、endsWith()

    是否包含字符串三种新方法 传统上,JavaScript只有 indexOf 方法,可以用来确定一个字符串是否包含在另一个字符串中.ES6又提供了三种新方法. includes():返回布尔值,表示是否 ...

  9. 2017 [六省联考] T5 分手是祝愿

    4872: [Shoi2017]分手是祝愿 Time Limit: 20 Sec  Memory Limit: 512 MBSubmit: 458  Solved: 299[Submit][Statu ...

  10. layui-时间选择器-时间范围选择

    HTML: JS: layui.use(['laydate'],function{ }); start:就为你选择的开始日期; end:就为你选择的结束日期 此方式可选择任意范围的时间,时间格式可任意 ...