第5章 碰撞检测
几乎所有的游戏都需要碰撞检测。比如《贪吃蛇》,你需要检测蛇的前端是不是已经碰到了它的尾巴;比如《俄罗斯方块》,你需要检查方块是不是已经碰到了底部;比如《英雄联盟》,你需要判断adc的子弹或魔法是不是已经碰到了对方。
其实要做好碰撞检测是很难的,尤其是对于3d游戏或者图形复杂的2d游戏来说。
当然,对于简单图形来说,碰撞检测还是比较容易的,本章将分别介绍圆形的碰撞检测,矩形的碰撞检测,以及逻辑碰撞检测。
一,圆形碰撞检测
圆形间碰撞检测的原理是最简单的,只要判断2个圆的圆心间距离是不是小于等于她们的半径之和就可以了。如果是,我们就认为这两个圆发生了碰撞,如果不是,我们就认为没有碰撞。
这里我们需要用到以前中学里学过的勾股定理来计算两个圆的圆心间距离。
代码如下:
<html> <head> <script> function distance(x1,y1,x2,y2) {var dis=Math.sqrt(Math.pow((x2-x1),2)+Math.pow((y2-y1),2)); return dis; } function collision() {if (dis<=(r1+r2)) return true; else return false; } script> head> html>
二,方块的碰撞检测
方块的碰撞检测不能用两个方块的中心之间的距离来判断。因为矩形和圆不一样,中心到边缘的距离不是等长的,所以,同样的距离,有的时候是碰到了,有的时候是没有碰到。圆不会出现这种问题。所以,方块的碰撞检测一般是用它的四条边的位置来判断。
上次看到有人在做矩形的碰撞检测时,用她的四个角来做,分别判断她的4个角的坐标是不是在另一个矩形内。这其实是不正确的,而且要判断4次,比较复杂。
其实矩形的碰撞检测只要判断一次就可以了。原理是两个矩形碰撞时,一个矩形的右边界的x坐标减去另一矩形的左边界x坐标必然小于等于她们的宽度之和,同时大于等于0。同理,下边界的y坐标减去另一个矩形的上边界的y坐标,必然小于等于她们的高度之和,同时大于等于0。
<html> <head> <script> function collision() {if ((x2+w2-x1<=w1+w2)&&(x2+w2-x1>=0)&&(y2+h2-y1<=h1+h2)&&(y2+h2-y1>=0)) return true; else return false; } script> head> html>
三,逻辑碰撞检测
其实碰撞检测是比较消耗系统资源的,尤其对于一些运算能力较低的设备而言。比如20世纪末很流行的“小霸王”或“任天堂”游戏机,或者一些早期的手机。大家可以设想一下,假如做一个常见的《打飞机》类游戏,屏幕上敌方飞机有几十架,各种子弹有上百枚在飞,假设每秒刷新20次,那么每秒就要进行好几千次碰撞检测的运算。这对于早期设备是相当吃力的。于是,在很多游戏中,她们采用了一种更加简单的碰撞检测方式——逻辑碰撞检测。这类游戏包括《坦克大战》、《俄罗斯方块》、《推箱子》等等。
逻辑碰撞检测的原理是,把屏幕划分成很多方格,比如200格,每一个格只有2钟状态,有东西(true)或者没东西(false)。当你试图前进到一个新的格子时,系统会判断,如果已经有东西的,就判断为发生了碰撞,如果没东西的,就认为没发生碰撞。
可见,逻辑碰撞检测极大地减少了运算量,很适合用来做一些类似《俄罗斯方块》的游戏。下一章我计划讲一下《贪吃蛇》的做法,就会用到逻辑碰撞检测,所以这一章就不放逻辑碰撞检测的例子了,下一章一起讲好了。
另外,我发现有几个网站转载了本教程的前面几章。只是希望转载的时候能够注明一下出处,包含我的下面3个博客地址就算是注明出处了
新浪微博:地球生活eev http://weibo.com/u/5274447427/
CSDN博客: http://blog.csdn.net/trackstatic/
博客园博客: http://www.cnblogs.com/phyy/
大家知道原创很累的,一般程序猿有多余时间的话,要么去做赚钱的项目,要么出去玩。能够静下心来一章章写这些无聊的教程的人不多。所以希望大家支持原创(把这段一起复制就算注明出处了)。