一,原理介绍

这回有点复杂,不过看懂了还是很好理解的。当然,我不敢保证这种算法在任何情况下都会起效果,如果有同学测试时,发现出现错误,请及时联系我。

我们首先来建立一个以圆心为原点的坐标系:

然后要检测碰撞就只有两种情况了。

情况一,矩形全部都在一个象限内,如图:

当然,图中只是举个例子,不一定是只在第二象限,任何一个象限都行,只要是矩形全在该象限。

这种情况比较好解决,首先,我们计算出矩形每个角的坐标,然后用勾股定律依次算出这个角到圆心的距离是否小于或者等于半径。设这个角与圆心横坐标之差为d1,纵坐标之差为d2,半径为r,公式表达如下:

如果有一个角满足要求说明产生碰撞,返回true。

但是有朋友懵了,怎么判断矩形是不是在一个象限内呢?很简单,只要判断这个矩形左上角和右下角是否在同一个象限内就可以了。于是我们得写个函数来实现判断某两个角是否在同一象限。

函数代码如下:

1. functionisSameQuadrant(cood,objA,objB){2. var coodX =cood.x;3. var coodY =cood.y;4. var xoA =objA.x5. ,yoA =objA.y6. ,xoB =objB.x7. ,yoB =objB.y;8.9. if(xoA-coodX>0 && xoB-coodX>0){10. if((yoA-coodY>0 && yoB-coodY>0) || (yoA-coodY<0 && yoB-coodY<0)){11. return true;12. }13. return false;14. }else if(xoA-coodX<0 && xoB-coodX<0){15. if((yoA-coodY>0 && yoB-coodY>0) || (yoA-coodY<0 && yoB-coodY<0)){16. return true;17. }18. return false;19. }else{20. return false;21. }22. }

这个函数原本是准备写到lufylegend中LMath静态类中的,参数原本是LPoint对象,但是这里可以用json,因为LPoint里的x,y属性可以写到json里,函数也就同样取得出值了。函数参数介绍:[cood创建的坐标系原点坐标, objA第一个点坐标, objB第二个点坐标] 这几个参数均为json对象,格式为:

{x:点的x坐标, y:点的y坐标}

函数中的代码还是很好理解的,就是判断一下两个点的x坐标都分别减去原点x坐标,看得出的数正负符号是否相同,然后又用同样的办法算出y轴上的符号是否相同,如果都相同就在同一象限。

有了这个函数,剩下得就好办了,直接代入开头给出的公式进行计算即可。

情况二,矩形跨度两个象限或者两个象限以上

这种情况更好办,我们就可以直接把圆看作一个边长为2r正方形,然后用矩形碰撞算法检测正方形和矩形的碰撞,如下图所示:

矩形碰撞的算法是什么呢?很easy,如图:

如果要横向判断碰撞的话,判断(x1-x2)的绝对值是否小于或者等于w1/2+w2/2,如果是则横向则有碰撞。纵向判断是一样的,判断(y1-y2)的绝对值是否小于或等于h1/2+h2/2即可。

有了这些算法,我们就可以实现情况2了。

二,Javascript版算法&测试代码

先上代码吧:

1. functionhitTestRectArc(rectObj,arcObj,rectVec,arcR){2. var rw =rectObj.getWidth()3. ,rh =rectObj.getHeight()4. ,ar = arcObj.getWidth()*0.5

5. ,rx =rectObj.x6. ,ry =rectObj.y7. ,ax =arcObj.x8. ,ay =arcObj.y;9.10. if(typeof rectVec !=UNDEFINED){11. rx += (rw - rectVec[0])*0.5;12. ry += (rh - rectVec[1])*0.5;13. rw = rectVec[0];14. rh = rectVec[1];15. }16. if(typeof arcR !=UNDEFINED){17. ax += (ar -arcR);18. ay += (ar -arcR);19. ar =arcR;20. }21.22. var rcx = rx+rw*0.5,rcy = ry+rh*0.5;23. var rltx =rx24. ,rlty =ry25. ,rlbx =rx26. ,rlby = ry+rh27. ,rrtx = rx+rw28. ,rrty =ry29. ,rrbx = rx+rw30. ,rrby = ry+rh;31.32. if(33. isSameQuadrant(34. {x:ax,y:ay},35. {x:rltx,y:rlty},36. {x:rrbx,y:rrby}37. )38. ){39. var dX1 = Math.abs(ax-rltx),dY1 = Math.abs(ay-rlty);40. var dX2 = Math.abs(ax-rlbx),dY2 = Math.abs(ay-rlby);41. var dX3 = Math.abs(ax-rrtx),dY3 = Math.abs(ay-rrty);42. var dX4 = Math.abs(ax-rrbx),dY4 = Math.abs(ay-rrby);43.44. if(45. (((dX1*dX1) + (dY1*dY1)) <= (ar*ar))46. ||(((dX2*dX2) + (dY2*dY2)) <= (ar*ar))47. ||(((dX3*dX3) + (dY3*dY3)) <= (ar*ar))48. ||(((dX4*dX4) + (dY4*dY4)) <= (ar*ar))49. ){50. return true;51. }52. return false;53. }else{54. var result = false;55. var squareX =ax56. ,squareY =ay57. ,squareW = ar*2

58. ,squareH =squareW;59. if(60. (Math.abs(squareX-rcx) <= (squareW+rw)*0.5)61. &&(Math.abs(squareY-rcy) <= (squareH+rh)*0.5)62. ){63. result = true;64. }65. returnresult;66. }67. }

由于是为lufylegend设计的函数,所以参数为 [ rectObj矩形对象(LSprite或者LShape对象), arcObj圆形对象(LSprite或者LShape对象), rectVec矩形规定大小(可不填), arcR圆形半径(可不填)] 当然,或许些朋友不懂这几行代码:

1. var rw =rectObj.getWidth()2. ,rh =rectObj.getHeight()3. ,ar = arcObj.getWidth()*0.5

4. ,rx =rectObj.x5. ,ry =rectObj.y6. ,ax =arcObj.x7. ,ay = arcObj.y;

好吧,我告诉你,这里用到的是lufylegend中LSprite和LShape,这两个类有x、y属性,还有获取宽度和高度的getWidth()和getHeight(),这里看不懂没关系,你知道是取高度和宽度还有x,y坐标的就行了。当然你要深究,那就看看lufylegend.js的API文档吧:http://lufylegend.com/lufylegend/api ,以下测试代码也用到了lufylegend.js,据说这个引擎是个不错的引擎,想了解的同学,去官方网站看看吧:http://lufylegend.com/lufylegend/ 或者看看我的文章,大多数是讲解有关lufylegend开发的。

示例代码:

1. init(50,"mylegend",500,250,main);2.3. functionmain(){4. LGlobal.setDebug(true);5.6. var back = newLSprite();7. back.graphics.drawRect(5,"green",[0,0,LStage.width,LStage.height],true,"lightblue");8. addChild(back);9.10. var cObj = newLSprite();11. cObj.x = 200;12. cObj.y = 120;13. cObj.graphics.drawArc(0,"",[0,0,50,0,2*Math.PI],true,"red");14. back.addChild(cObj);15.16. var rObj = newLSprite();17. rObj.x = 250;18. rObj.y = 70;19. rObj.alpha = 0.8;20. rObj.graphics.drawRect(0,"",[0,0,100,100],true,"green");21. back.addChild(rObj);22.23. trace(hitTestRectArc(rObj,cObj));24.25. back.addEventListener(LMouseEvent.MOUSE_DOWN,function(e){26. rObj.x = e.offsetX-rObj.getWidth()*0.5;27. rObj.y = e.offsetY-rObj.getHeight()*0.5;28. trace(hitTestRectArc(rObj,cObj));29. });30. }

测试链接:http://www.cnblogs.com/yorhom/articles/hitTestRectArc.html

2d游戏碰撞检测C语言,2D游戏中的碰撞检测:圆形与矩形碰撞检测(Javascrip版)...相关推荐

  1. 游戏开发- Python语言在游戏开发中的潜力

    PYTHON 是一种面向对象的通用高级编程语言,由 GUIDO VAN ROSSUM 于 1991 年开发.自发展以来,PYTHON 已成为世界上最流行的编程语言之一.它经常在流行度调查中排名靠前-- ...

  2. c语言小游戏代码(c语言小游戏代码简单)

    c语言编写小游戏请提供俄罗斯方块,坦克大战之类的小游戏的程序的c 应该是做出方块函数 然后以 这个方块 为单位 绘制 俄罗斯方块的 积木图形 ,在制作游戏界面的时候 也以方块长度为单位长度绘制 二维数 ...

  3. 2D游戏中的碰撞检测:圆形与矩形碰撞检测(JavascriptC++版)

    这几天放寒假了,时间也多了起来,当然又有时间搞搞程序了.哈哈~ 昨天在开发我的塔防游戏时突然发现人物实际攻击范围比规定的范围小,按理说应该是一样大的,但偏偏不是,我被这个问题搞得糊里糊涂的,一直没想出 ...

  4. c语言游戏菜单栏,C语言小游戏之打砖块

    //easyx图形库头文件 #include//控制台输入输出头文件 //宏定义:砖块为:5行10列 #define ROW 5 #define COL 10 //砖块数组 int ZhuanKuai ...

  5. c语言五子棋游戏报告,C语言五子棋游戏

    该楼层疑似违规已被系统折叠 隐藏此楼查看此楼 /* 初始化游戏界面: 1.绘图环境 2.背景图片 3.背景音乐 4.绘制格子 5.绘制边界线 6.显示黑棋为玩家1,白棋为玩家2 下棋: 1.while ...

  6. 细胞生命游戏一维c语言,生命游戏一维细胞自动机 笔记

    de 生命游戏是一种简单的聚合模型,展示了事物是如何聚合的,是自动机(CA)模型的一种.由剑桥大学约翰康威发明,其规则为: 1. 每个细胞拥有八个邻居,细胞状态只有存活(黑)和死亡(白)两种: 2.处 ...

  7. 细胞生命游戏一维c语言,生命游戏 细胞死亡问题

    [c]代码库#include #include #include #define MAXROW 10 #define MAXCOL 25 #define DEAD 0 #define ALIVE 1 ...

  8. 游戏服务器 c语言,C++游戏服务器编程从入门到掌握视频教程(全)

    资源介绍 任务1: 课程预览PPT 2-课程概述.mp4 3-IP详解第一部分.mp4 任务4: 预览IP详解PPT 5-IP详解第二部分.mp4 6-TCP详解第一部分(介绍 + 工作原理 + 头部 ...

  9. 组件分享之后端组件——基于Golang语言的游戏服务器框架leaf

    组件分享之后端组件--基于Golang语言的游戏服务器框架leaf 背景 近期正在探索前端.后端.系统端各类常用组件与工具,对其一些常见的组件进行再次整理一下,形成标准化组件专题,后续该专题将包含各类 ...

最新文章

  1. Linux系统函数之IO函数
  2. 当当网强烈谴责李国庆有关刘强东案言论
  3. MySQL学习之路:多实例无法启动排错
  4. php 接受数组_PHP接收前端发送的数组
  5. 1247 排排站 USACO(查分+hash)
  6. 野生前端的数据结构基础练习(7)——二叉树
  7. 在线Javascript压缩工具
  8. 将DEX反编译成Java源代码
  9. CCF201703-4 地铁修建(100分)【Kruskal算法+二分+最短路】
  10. Deeplabv3+ 环境配置-Anaconda3 + Pytorch1.8 + Cuda10.1 + opencv3.2.0
  11. 激光雷达lidar标定
  12. 游戏王抽卡模拟器(概率计算器)
  13. 安装配置fcitx输入法
  14. html5字幕提取软件,VideoSubFinder(提取视频字幕软件)
  15. C#获取当前桌面路径
  16. 使用流报错:stream has already been operated upon or closed
  17. Pap.er 3.5.4 中文版 (专为Mac设计的高清壁纸应用)
  18. 员工公寓楼建设项目电力监控系统的研究与应用
  19. oracle 批量列转行,oracle 批量列转行 逗号分隔
  20. 重庆计算机本科分数线是多少,重庆市2017年高考分数线公布

热门文章

  1. 国产ARM核心工控主板介绍
  2. Bootstrap 教程入门
  3. Java将查询到的List,list集合还嵌套一个list集合(把这个list集合和嵌套的list集合合并为一个list集合)
  4. 我设想的BI项目的实施过程
  5. JS: prompt() 输入框 confim()确认框 alert() 提示框
  6. MySQL中针对SQL语句优化
  7. 用select多路io复用实现简单聊天程序
  8. 5,uniapp功能之—打印机,打印文本和二维码等,(佳博的打印机)
  9. 面试官:策略模式和代理模式有什么区别?
  10. jquery 自动表单赋值