您的位置:首页 > 移动开发 > Cocos引擎

Cocos2dx 多边形碰撞检测

2014-03-27 12:33 441 查看
ContactListen = ObjClass("ContactListen")

-- 创建layer
function ContactListen:createLayer(layer)
    local contactListen = self:new();
    contactListen.maxnum = 0
    return contactListen;
end

-- 创建时候调用的方法 相当于init
function ContactListen:ctor()

   
end

-- 初始化
function ContactListen:init(birdlayer,rankLayer,gameScene)
    self.gameScene = gameScene;
    self.birdlayer = birdlayer;
    self.rankLayer = rankLayer;

end

-- 监听
function ContactListen:listenContact()
    -- 开始监听
    local function contactSp()
        -- 判断碰撞
        table.foreach(self.rankLayer.spriteArray, function(i, v) 
             v = tolua.cast(v,"CCSprite")
             local barBoundingbox = CCRectMake(0,0,0,0);
             local barTempArray = {}
             self:getPositions(v,barTempArray,barBoundingbox)

             if barBoundingbox.origin.y < 350 then

                --local yellowRect = self.birdlayer.yellowbird:boundingBox();
                local yellowPoint = self.birdlayer.yellowbird:getParent():convertToWorldSpace(ccp(self.birdlayer.yellowbird:getPositionX(),self.birdlayer.yellowbird:getPositionY()));                
                
                --local redRect = self.birdlayer.RedBird:boundingBox();
                local redWordPoint = self.birdlayer.RedBird:getParent():convertToWorldSpace(ccp(self.birdlayer.RedBird:getPositionX(),self.birdlayer.RedBird:getPositionY()));

                -- 判断该sp是不是选中中得
                if v:getRotation() ==0 then

                    if barBoundingbox:containsPoint(yellowPoint) then

                        --_director:pause()
                        -- 碰撞了黄色鸟
                        _director:getScheduler():unscheduleScriptEntry(self.schId);
                        self:boump(yellowPoint,v,barTemp,self.birdlayer.yellowbird);
                        return;
                    elseif barBoundingbox:containsPoint(redWordPoint) then
                        -- 碰撞了红色的鸟
                   
                        --_director:pause()
                        _director:getScheduler():unscheduleScriptEntry(self.schId);
                        self:boump(redWordPoint,v,barTemp,self.birdlayer.RedBird);
                        return;
                    end

                else
                   
                     -- 判断碰撞检测
                    if self:checkBox(yellowPoint,barTempArray) then
                       
                        --_director:pause()
                        -- 碰撞了黄色鸟
                        _director:getScheduler():unscheduleScriptEntry(self.schId);
                        self:boump(yellowPoint,v,barTemp,self.birdlayer.yellowbird);
                       
                        return;
                    elseif self:checkBox(redWordPoint,barTempArray) then
                        -- 碰撞了红色的鸟
                      
                        --_director:pause()
                        _director:getScheduler():unscheduleScriptEntry(self.schId);
                        self:boump(redWordPoint,v,barTemp,self.birdlayer.RedBird);
                        
                        return;
                    end
                end
                barTempArray = nil
             end
        end) ;
    end
    
    -- 开启定时器
    self.schId = _director:getScheduler():scheduleScriptFunc(contactSp,1/30.0, false);
end

-- 获取4个点
function ContactListen:getPositions(barsp,barTempArray,barBoundingbox)
    barsp = tolua.cast(barsp,"CCSprite")
    barBoundingbox = tolua.cast(barBoundingbox,"CCRect")
    local rect = CCRectMake(0,0,barsp:getContentSize().width,barsp:getContentSize().height)
    local top    = rect:getMinY();
    local left   = rect:getMinX();
    local right  = rect:getMaxX();
    local bottom = rect:getMaxY();
    local anAffineTransform = barsp:nodeToParentTransform()

    local topLeft = CCPointApplyAffineTransform(CCPointMake(left, top), anAffineTransform);
    local topRight = CCPointApplyAffineTransform(CCPointMake(right, top), anAffineTransform);
    local bottomLeft = CCPointApplyAffineTransform(CCPointMake(left, bottom), anAffineTransform);
    local bottomRight = CCPointApplyAffineTransform(CCPointMake(right, bottom), anAffineTransform);

    local minX = math.min(math.min(topLeft.x, topRight.x), math.min(bottomLeft.x, bottomRight.x));
    local maxX = math.max(math.max(topLeft.x, topRight.x), math.max(bottomLeft.x, bottomRight.x));
    local minY = math.min(math.min(topLeft.y, topRight.y), math.min(bottomLeft.y, bottomRight.y));
    local maxY = math.max(math.max(topLeft.y, topRight.y), math.max(bottomLeft.y, bottomRight.y));
        
    barBoundingbox.origin = barsp:getParent():convertToWorldSpace(ccp(minX,minY));
    barBoundingbox.size = CCSizeMake((maxX - minX), (maxY - minY))
   if barsp:getRotation() ~=0 then
    table.insert(barTempArray,0,barsp:getParent():convertToWorldSpace(ccp(topLeft.x,topLeft.y)));
    table.insert(barTempArray,1,barsp:getParent():convertToWorldSpace(ccp(topRight.x,topRight.y)));
    table.insert(barTempArray,2,barsp:getParent():convertToWorldSpace(ccp(bottomRight.x,bottomRight.y)));
    table.insert(barTempArray,3,barsp:getParent():convertToWorldSpace(ccp(bottomLeft.x,bottomLeft.y)));
    --table.insert(barTempArray,4,barsp:getParent():convertToWorldSpace(ccp(topLeft.x,topLeft.y)));
    end
    

end

-- 爆炸效果
function ContactListen:boump(point,sp,barTemp,bird)

    --播放音效
    playEffect("bounding.mp3")

    bird = tolua.cast(bird,"CCSprite")
    point = tolua.cast(point,"CCPoint")
    barTemp = tolua.cast(barTemp,"CCRect")
    -- 鸟小时
    bird:setVisible(false)
    -- 先暂停
    self.gameScene:cancelTouch()
    -- 执行帧动画
    local redAry = CCArray:create()
    for i=1,6 do
        local str = string.format("boump%d.png", i);
        redAry:addObject(CCSpriteFrameCache:sharedSpriteFrameCache():spriteFrameByName(str))
    end
    local redAnimation = CCAnimation:createWithSpriteFrames(redAry,0.05);
    local redAnimate = CCAnimate:create(redAnimation);
    local boumpSp = CCSprite:createWithSpriteFrameName("boump1.png")
    boumpSp:setPosition(ccp(point.x,point.y))
    self.gameScene:addChild(boumpSp);
    -- 回调函数
    local function callFunc()
        boumpSp:removeFromParentAndCleanup(true)
       self.gameScene:resumeTouch()
       self.gameScene:gameOver();
    end
    local callFunc = CCCallFunc:create(callFunc);
    boumpSp:runAction(CCSequence:createWithTwoActions(redAnimate, callFunc));
end

-- 判断是否碰撞
function ContactListen:checkBox(p,pointArray)
    p = tolua.cast(p,"CCPoint")
    local nCross = 0;
    local nCount = table.maxn(pointArray);
    local cosin = 0
    for i=0,nCount do
        local p1 = pointArray[i];
        p1 = tolua.cast(p1,"CCPoint")
        local p2 = pointArray[(i+1)%(nCount+1)];
        p2 = tolua.cast(p2,"CCPoint")
        -- 求解 y=p.y 与 p1p2
的交点
        local x1 = (p1.x-p.x)
        local y1 = (p1.y-p.y)
        local x2 = (p2.x-p.x)
        local y2 = (p2.y-p.y)
        local temp = (x1*x2+y1*y2)/ math.sqrt((x1*x1+y1*y1)*(x2*x2+y2*y2))

        cosin =  cosin + math.deg(math.acos(temp))
        
    end
    
    
    if cosin>=355 then

        return true;
    end

    -- 单边交点为偶数,点在多边形之外 ---
    return false;
end

-- 释放
function ContactListen:deleteSelf()
    if self.schId then
        _director:getScheduler():unscheduleScriptEntry(self.schId);
    end
    self.birdlayer = nil;
    self.rankLayer = nil;
    self = nil
end
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: