分享一下自己在以前的工作中用到的cocos2dx 多边形碰撞的代码,供大家学习交流,如果有更好地方法来完善这个代码,希望能发到社区里面和大家多交流一下,社区里面不光有新手,也有大神,大家可以到社区里面去提问。
ContactListen = ObjClass("ContactListen")
-- 创建layer
1. function ContactListen:createLayer(layer)
2. local contactListen = self:new();
3. contactListen.maxnum = 0
4. return contactListen;
5. end
-- 创建时候调用的方法 相当于init
1. function ContactListen:ctor()
2.
3. end
4.
5. -- 初始化
6. function ContactListen:init(birdlayer,rankLayer,gameScene)
7. self.gameScene = gameScene;
8. self.birdlayer = birdlayer;
9. self.rankLayer = rankLayer;
10.
11. end
12.
13. -- 监听
14. function ContactListen:listenContact()
15. -- 开始监听
16. local function contactSp()
17. -- 判断碰撞
18. table.foreach(self.rankLayer.spriteArray, function(i, v)
19. v = tolua.cast(v,"CCSprite")
20. local barBoundingbox = CCRectMake(0,0,0,0);
21. local barTempArray = {}
22. self:getPositions(v,barTempArray,barBoundingbox)
23.
24. if barBoundingbox.origin.y < 350 then
25.
26. --local yellowRect = self.birdlayer.yellowbird:boundingBox();
27. local yellowPoint = self.birdlayer.yellowbird:getParent():convertToWorldSpace(ccp(self.birdlayer.yellowbird:getPositionX(),self.birdlayer.yellowbird:getPositionY()));
28.
29. --local redRect = self.birdlayer.RedBird:boundingBox();
30. local redWordPoint = self.birdlayer.RedBird:getParent():convertToWorldSpace(ccp(self.birdlayer.RedBird:getPositionX(),self.birdlayer.RedBird:getPositionY()));
31.
32.
33. -- 判断该sp是不是选中中得
34. if v:getRotation() ==0 then
35.
36. if barBoundingbox:containsPoint(yellowPoint) then
37.
38. --_director:pause()
39. -- 碰撞了黄色鸟
40. _director:getScheduler():unscheduleScriptEntry(self.schId);
41. self:boump(yellowPoint,v,barTemp,self.birdlayer.yellowbird);
42. return;
43. elseif barBoundingbox:containsPoint(redWordPoint) then
44. -- 碰撞了红色的鸟
45.
46. --_director:pause()
47. _director:getScheduler():unscheduleScriptEntry(self.schId);
48. self:boump(redWordPoint,v,barTemp,self.birdlayer.RedBird);
49. return;
50. end
51.
52. else
53.
54. -- 判断碰撞检测
55. if self:checkBox(yellowPoint,barTempArray) then
56.
57. --_director:pause()
58. -- 碰撞了黄色鸟
59. _director:getScheduler():unscheduleScriptEntry(self.schId);
60. self:boump(yellowPoint,v,barTemp,self.birdlayer.yellowbird);
61.
62. return;
63. elseif self:checkBox(redWordPoint,barTempArray) then
64. -- 碰撞了红色的鸟
65.
66. --_director:pause()
67. _director:getScheduler():unscheduleScriptEntry(self.schId);
68. self:boump(redWordPoint,v,barTemp,self.birdlayer.RedBird);
69.
70. return;
71. end
72. end
73. barTempArray = nil
74. end
75. end) ;
76. end
-- 开启定时器
1. self.schId = _director:getScheduler():scheduleScriptFunc(contactSp,1/30.0, false);
2. end
3.
4. -- 获取4个点
5. function ContactListen:getPositions(barsp,barTempArray,barBoundingbox)
6. barsp = tolua.cast(barsp,"CCSprite")
7. barBoundingbox = tolua.cast(barBoundingbox,"CCRect")
8. local rect = CCRectMake(0,0,barsp:getContentSize().width,barsp:getContentSize().height)
9. local top = rect:getMinY();
10. local left = rect:getMinX();
11. local right = rect:getMaxX();
12. local bottom = rect:getMaxY();
13. local anAffineTransform = barsp:nodeToParentTransform()
14.
15. local topLeft = CCPointApplyAffineTransform(CCPointMake(left, top), anAffineTransform);
16. local topRight = CCPointApplyAffineTransform(CCPointMake(right, top), anAffineTransform);
17. local bottomLeft = CCPointApplyAffineTransform(CCPointMake(left, bottom), anAffineTransform);
18. local bottomRight = CCPointApplyAffineTransform(CCPointMake(right, bottom), anAffineTransform);
19.
20. local minX = math.min(math.min(topLeft.x, topRight.x), math.min(bottomLeft.x, bottomRight.x));
21. local maxX = math.max(math.max(topLeft.x, topRight.x), math.max(bottomLeft.x, bottomRight.x));
22. local minY = math.min(math.min(topLeft.y, topRight.y), math.min(bottomLeft.y, bottomRight.y));
23. local maxY = math.max(math.max(topLeft.y, topRight.y), math.max(bottomLeft.y, bottomRight.y));
24.
25. barBoundingbox.origin = barsp:getParent():convertToWorldSpace(ccp(minX,minY));
26. barBoundingbox.size = CCSizeMake((maxX - minX), (maxY - minY))
27. if barsp:getRotation() ~=0 then
28. table.insert(barTempArray,0,barsp:getParent():convertToWorldSpace(ccp(topLeft.x,topLeft.y)));
29. table.insert(barTempArray,1,barsp:getParent():convertToWorldSpace(ccp(topRight.x,topRight.y)));
30. table.insert(barTempArray,2,barsp:getParent():convertToWorldSpace(ccp(bottomRight.x,bottomRight.y)));
31. table.insert(barTempArray,3,barsp:getParent():convertToWorldSpace(ccp(bottomLeft.x,bottomLeft.y)));
32. --table.insert(barTempArray,4,barsp:getParent():convertToWorldSpace(ccp(topLeft.x,topLeft.y)));
33. end
34.
35.
36. end
-- 爆炸效果
1. function ContactListen:boump(point,sp,barTemp,bird)
--播放音效
1. playEffect("bounding.mp3")
2.
3.
4. bird = tolua.cast(bird,"CCSprite")
5. point = tolua.cast(point,"CCPoint")
6. barTemp = tolua.cast(barTemp,"CCRect")
7. -- 鸟小时
8. bird:setVisible(false)
9. -- 先暂停
10. self.gameScene:cancelTouch()
11. -- 执行帧动画
12. local redAry = CCArray:create()
13. for i=1,6 do
14. local str = string.format("boump%d.png", i);
15. redAry:addObject(CCSpriteFrameCache:sharedSpriteFrameCache():spriteFrameByName(str))
16. end
17. local redAnimation = CCAnimation:createWithSpriteFrames(redAry,0.05);
18. local redAnimate = CCAnimate:create(redAnimation);
19. local boumpSp = CCSprite:createWithSpriteFrameName("boump1.png")
20. boumpSp:setPosition(ccp(point.x,point.y))
21. self.gameScene:addChild(boumpSp);
22. -- 回调函数
23. local function callFunc()
24. boumpSp:removeFromParentAndCleanup(true)
25. self.gameScene:resumeTouch()
26. self.gameScene:gameOver();
27. end
28. local callFunc = CCCallFunc:create(callFunc);
29. boumpSp:runAction(CCSequence:createWithTwoActions(redAnimate, callFunc));
30. end
-- 判断是否碰撞
1. function ContactListen:checkBox(p,pointArray)
2. p = tolua.cast(p,"CCPoint")
3. local nCross = 0;
4. local nCount = table.maxn(pointArray);
5. local cosin = 0
6. for i=0,nCount do
7. local p1 = pointArray[i];
8. p1 = tolua.cast(p1,"CCPoint")
9. local p2 = pointArray[(i+1)%(nCount+1)];
10. p2 = tolua.cast(p2,"CCPoint")
11. -- 求解 y=p.y 与 p1p2 的交点
12. local x1 = (p1.x-p.x)
13. local y1 = (p1.y-p.y)
14. local x2 = (p2.x-p.x)
15. local y2 = (p2.y-p.y)
16. local temp = (x1*x2+y1*y2)/ math.sqrt((x1*x1+y1*y1)*(x2*x2+y2*y2))
17.
18. cosin = cosin + math.deg(math.acos(temp))
19.
20. end
21.
22.
23. if cosin>=355 then
24.
25. return true;
26. end
27.
28. -- 单边交点为偶数,点在多边形之外 ---
29. return false;
30. end
31.
32.
33. -- 释放
34. function ContactListen:deleteSelf()
35. if self.schId then
36. _director:getScheduler():unscheduleScriptEntry(self.schId);
37. end
38. self.birdlayer = nil;
39. self.rankLayer = nil;
40. self = nil
41. end