碰撞检测关键步骤

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

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

计算碰撞

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

矩形物体碰撞检测

假设检测发生碰撞的物体是 矩形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. unittest之装饰器

    前面讲到 unittest 里面 setUp 可以在每次执行用例前执行,这样有效的减少了代码量,但是有个弊端,比如打开浏览器操作,每次执行用例时候都会重新打开,这样就会浪费很多时间.于是就想是不是可以 ...

  2. selenium+Python(表单、多窗口切换)

    1.多表单切换 在Web应用中经常会遇到frame/iframe表单嵌套页面的应用,WebDriver只能在一个页面上对元素识别与定位,对于frame/iframe表单内嵌页面上的元素无法直接定位.这 ...

  3. Java万年历,输入年月获取该年月日历表

    //输入年份和月份,打印出这个月的日历表 /* 1.1900年1月1日是星期一 2.计算输入的年份距离1900年有多少天再计算当年1月1日距这个月有多少天 1) 3.总天数%7得出从星期几开始 注:计 ...

  4. 在Eclipse添加Android兼容包( v4、v7 appcompat )[转]

    昨天添加Android兼容包,碰到了很多问题,在这里记录一下,让后面的路好走. 如何选择兼容包, 请参考Android Support Library Features(二) 一.下载Support ...

  5. CCF 出现次数最多的数 201312-1

    出现次数最多的数 问题描述 试题编号: 201312-1 试题名称: 出现次数最多的数 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 给定n个正整数,找出它们中出现次数最多的 ...

  6. 计算F1Score

    计算F1Score predictions = pval < epsilon fp = sum((predictions == 1) & (y == 0)) fn = sum((pred ...

  7. PostgreSQL PARTITION 分区表

    PostgreSQL 分区表,操作性相当便捷. 但只能在创建时决定是否为分区表,并决定分区条件字段,普通表创建后,不能在修改为分区表. Note:通过其他方法也可转化为分区表. 和其他数据库一样,分区 ...

  8. Vue生命周期整理

    这篇博客将会从下面四个常见的应用诠释组件的生命周期,以及各个生命周期应该干什么事 单组件的生命周期 父子组件的生命周期 兄弟组件的生命周期 宏mixin的生命周期 生命周期:Vue 实例从开始创建.初 ...

  9. 怎么让textarea的光标靠左对齐

    1.怎么让textarea的光标靠左对齐: 把<textarea></textarea>之间空隙去掉就可以了. 2.怎么限制textarea的字数,利用maxlength属性限 ...

  10. Csharp: speech to text, text to speech in win

    using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; usin ...