碰撞检测关键步骤

碰撞检测需要处理经历下面两个关键的步骤:

  • 计算判断两个物体是否发生碰撞
  • 发生碰撞后,两个物体的状态和动画效果的处理

计算碰撞

只要两个物体相互接触,它们就会发生碰撞。

矩形物体碰撞检测

假设检测发生碰撞的物体是 矩形1 和 矩形2 时,我们只需检测 矩形1 的上下左右四侧的和 矩形2 是否存在着距离。我们可以看看下面的图:

我们可以看到 矩形2 和 矩形1 之间没有发生碰撞共有四种可能的情况:

  • 矩形2的右侧 离 矩形1的左侧有一段距离
  • 矩形2的左侧 离 矩形1的右侧有一段距离
  • 矩形2的底部 离 矩形1的顶部有一段距离
  • 矩形2的顶部 离 矩形1的底部有一段距离

当符合上面其中一种情况,则两个矩形没有发生碰撞。

因此通过逆向推导我们可以得出:当上面四种情况都不满足的时候,则代表两个矩形碰撞了。在代码中,我们可以这样写:

// 判断四边是否都没有空隙
if (!(rect2.x + rect2.width < rect1.x) &&
!(rect1.x + rect1.width < rect2.x) &&
!(rect2.y + rect2.height < rect1.y) &&
!(rect1.y + rect1.height < rect2.y)) {
// 物体碰撞了
}

圆形物体碰撞检测

假设发生碰撞的物体是 圆形 时,检测碰撞则变得比较复杂了,前面矩形所使用的碰撞检测,并不能判断圆形物体的情况。如下图的情况:

那么如何检测两圆是否碰撞了呢?这个时候又到了考验我们数理化的知识了。

检测两圆是否相交:当两个圆心之间的距离是否小于两个圆的半径之和。这是已经被证实的数学运算。如下图所示:

其中 dx 和 dy 分别表示两个圆之间的横坐标和纵坐标的差值。 即 dx = x2 - x1; dy = y2 - y1;

然后我们需要通过 勾股定理 计算两个圆心之间的距离。如下图:

因此我们碰撞检测的代码可以这样写:

var dx = circle2.x - circle1.x;
var dy = circle2.y - circle1.y;
var distance = Math.sqrt((dx * dx) * (dy * dy));
if (distance < circle1.radius + circle2.radius) {
// 两个圆形碰撞了
}

前面讲解了怎么检测矩形和圆形是否碰撞,基本已经可以适用大部分场景。对于特殊的场景,则需要大家自己去思考如何检测了。

碰撞后的处理

当检测到碰撞后,则可以对碰撞的物体进行状态设置了,可以是相互毁灭,或者是反弹等。这里大家可以根据场景来决定。

canvas游戏和动画中的碰撞检测(2种简单方式)的更多相关文章

  1. spring 整合 mybatis 中数据源的几种配置方式

    因为spring 整合mybatis的过程中, 有好几种整合方式,尤其是数据源那块,经常看到不一样的配置方式,总感觉有点乱,所以今天有空总结下. 一.采用org.mybatis.spring.mapp ...

  2. Django中提供的6种缓存方式

    由于Django是动态网站,所有每次请求均会去数据进行相应的操作,当程序访问量大时,耗时必然会更加明显,最简单解决方式是使用: 缓存,缓存将一个某个views的返回值保存至内存或者memcache中, ...

  3. 【温故知新】——原生js中常用的四种循环方式

    一.引言 本文主要是利用一个例子,讲一下原生js中常用的四种循环方式的使用与区别: 实现效果: 在网页中弹出框输入0   网页输出“欢迎下次光临” 在网页中弹出框输入1   网页输出“查询中……” 在 ...

  4. Springboot中IDE支持两种打包方式,即jar包和war包

    Springboot中IDE支持两种打包方式,即jar包和war包 打包之前修改pom.xml中的packaging节点,改为jar或者war    在项目的根目录执行maven 命令clean pa ...

  5. JAVA高级架构师基础功:Spring中AOP的两种代理方式:动态代理和CGLIB详解

    在spring框架中使用了两种代理方式: 1.JDK自带的动态代理. 2.Spring框架自己提供的CGLIB的方式. 这两种也是Spring框架核心AOP的基础. 在详细讲解上述提到的动态代理和CG ...

  6. Vue中常用的几种传值方式

    Vue中常用的几种传值方式 1. 父传子 父传子的实现方式就是通过props属性,子组件通过props属性接收从父组件传过来的值,而父组件传值的时候使用 v-bind 将子组件中预留的变量名绑定为da ...

  7. 【翻译】CEDEC2013 BANDAI NAMCO 了解游戏格斗动画中的身体运动结构和原理

    CEDEC搬运工程开始~   这篇会议PPT的作者 元梅幸司曾经就职在TECMO参与开发了死或生2,3[ DEAD OR ALIVE],忍龙「NINJA GAIDEN」后来加入NAMCO(现在是BAN ...

  8. Android中BroadcastReceiver的两种注册方式(静态和动态)详解

    今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来 ...

  9. JAVA中单例模式的几种实现方式

    1 线程不安全的实现方法 首先介绍java中最基本的单例模式实现方式,我们可以在一些初级的java书中看到.这种实现方法不是线程安全的,所以在项目实践中如果涉及到线程安全就不会使用这种方式.但是如果不 ...

随机推荐

  1. 关于display:none;和id特性的一些需要注意的地方

    关注点一: display:none;一旦用于某个元素,那个这个元素在页面中就不再占据位置. visibility:hidden;用于某个元素时,这个元素还会占据位置. 关注点二: 即使使用了disp ...

  2. loadView 与 viewDidLoad 和 didReceiveMemoryWarning与viewDidUnload 详解

    首先试验下:viewController初始化 分两个支路:initWithNibName加载初始化 及 init 直接初始化: <1>调用initWithNibName加载一个xib界面 ...

  3. 4、在Shell程序中的使用变量

    学习目标变量的赋值变量的访问变量的输入 12-4-1 变量的赋值在Shell编程中,所有的变量名都由字符串组成,并且不需要对变量进行声明.要赋值给一个变量,其格式如下:变量名=值.注意:等号(=)前后 ...

  4. poj 2954 Triangle

    pick公式+gcd公式 #include<iostream> #include<map> #include<string> #include<cstring ...

  5. python风味之list创建

    单重for循环 >>> [x * x for x in xrange(10)] [0, 1, 4, 9, 16, 25, 36, 49, 64, 81] 单重for循环+if条件 & ...

  6. Python对列表中字典元素排序

    问题起源 json对象a,b a = '{"ROAD": [{"id": 123}, {"name": "no1"}]} ...

  7. [转载+补充][PY3]——环境配置(2)——windows下安装pycharm并连接Linux的python环境

    原文地址:<你所会用到的Python学习环境和工具> 1. 下载安装Pycharm专业版 具体方法略.Pycharm5激活方法参考http://www.cnblogs.com/snsdzj ...

  8. Appium移动端自动化测试-安卓真机+模拟器启动

    一.环境准备 appium-pythin-client版本(0.17),selenium版本(2.53.6)(版本需对应,否则执行脚本可能出错,我用的是这两个版本) macOs版本10.14.1(ap ...

  9. 判断img图片是否加载成功

    上班之余,记录一下工作中遇到的有趣问题... 事情是这样的...在做一个内嵌H5的app时,有一个“个人名片”页面...要求:如果后台接口有给头像的图片链接就用他们给的,如果没给,前端给个默认头像.. ...

  10. AtCoder Regular Contest 059 F Unhappy Hacking

    Description 题面 Solution 我们发现如果一个位置需要被退掉,那么是 \(0\) 或 \(1\) 都没有关系 于是我们想到把 \(0,1\) 归为一类 问题转化为每一次可以添加和删除 ...