分享一下自己在以前的工作中用到的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