《切水果》03-碰撞检测

第一次写教程多多包涵

问题:如何判断刀光跟水果发生碰撞关系?
思路:1、记录鼠标移动的点,把每个点连接起来,两个点组成一条线段,线段设想它有生命周期会随着时间而消逝,2、把每个水果看成一个圆形,这样一来就不用管水果在空中各种旋转的问题了,圆形再怎么旋转也还是圆形。
3、把记录下来的线段数据跟飞行池中的水果进行碰撞检测

代码如下:

----------------------鼠标移动过程中记录线段数据保存在全局数组中
function MouseLayer:_onTouchFunc(event)
    if(event.name=="began")then
        self.m_down=true
        self.tempx,self.tempy=event.x,event.y
        return true
    elseif(event.name=="ended")then
        self.m_down=false
    elseif(event.name=="moved") then
        if(self.m_down==true)then
            self.streak:setPosition(event.x,event.y)
            ---------------记录线段数据
            local line = SLine.new(self.tempx, self.tempy, event.x, event.y)
            dis=math.sqrt((self.tempx-event.y)*(self.tempx-event.x),(self.tempy-event.y)*(self.tempy-event.y))
            self.tempx=event.x
            self.tempy=event.y
            if(dis>=60) then
                local par=cc.ParticleSystemQuad:create("particles/exp.plist"):addTo(self):pos(event.x,event.y)
                par:setAutoRemoveOnFinish(true)
            end
        end
    end
end

```


线段数据类内部实现
local SLine=class("SLine")
local lines=G_Lines
local table=table
function SLine:ctor(startx,starty,endx,endy,life)
    self.startx=startx
    self.starty=starty
    self.endx=endx
    self.endy=endy
    self.life=life or 10
    table.insert(lines,self)
end

function SLine:update()
    self.life=self.life-1
    if(self.life<=0)then
        table.removebyvalue(lines,self)
    end
end

return SLine

```

-------------------------碰撞检测
function MainScene:_checkCollide()
    for k,v in pairs(lines) do
        for kk,vv in pairs(self.emitter.flyPool) do
            if(vv.canSplit==true)then
                local xpos=vv:getPositionX()
                local ypos=vv:getPositionY()
                local hitResult=self:_lineHitCircle(v.startx,v.starty,v.endx,v.endy,vv.r,xpos,ypos)
                local isHit=(vv.isDie==false and hitResult~=nil)
                if(isHit)then
                    self.emitter:doHit(vv,hitResult.angle);
                    self:_handleResult(vv,xpos,ypos)
                end
            end
        end
    end
end

--------------线段与圆碰撞检测 
-----------------这个是核心 ,具体要问我原理的话,请wiki百科 (圆与线段碰撞检测)
function MainScene:_lineHitCircle(x1,y1,x2,y2,r,xc,yc)
    local dx_2_1 = x2 - x1
    local dy_2_1 = y2 - y1
    local xd=0
    local yd=0
    local d=0
    local t = ((yc - y1) * dy_2_1 + (xc - x1) * dx_2_1) / (dy_2_1 * dy_2_1 + dx_2_1 * dx_2_1)
    if(t>=0 and t<=1)then
        xd = x1 + t * dx_2_1
        yd = y1 + t * dy_2_1
        d = math.sqrt((xd - xc) * (xd - xc) + (yd - yc) * (yd - yc))
    else
        d = math.sqrt((xc - x1) * (xc - x1) + (yc - y1) * (yc - y1))
        if(d >4)then
            d = math.sqrt((xc - x2) * (xc - x2) + (yc - y2) * (yc - y2))
        end
    end
    if(d>r)then return nil end
    local lineDis=math.sqrt((y2-y1)*(y2-y1)+(x2-x1)*(x2-x1))
    if(lineDis>=10)then
        local obj={}
        obj.angle=math.atan2(y2-y1,x2-x1)
        return obj
    end
    return nil
end

```

wiki百科没有搜索到 (圆与线段碰撞检测),请lz指点。这里圆和线段的碰撞检测确实没看懂

http://yehar.com/blog/?p=2926

http://www.openprocessing.org/sketch/65771

搜索:line segment circle collision