cocos2dx 实现gallery (三)

        我是lua的代码,呜啦啦啦啦~~不过不影响嘛。


        首先设置一些参数:

    self.r = 260/2     --滚轮半径
    self.vd = 330   --视点距离
    self.arcPos = {135,180,225,270,315,360,45,90}   --平铺放置节点的角度
        我是按45度分部的,所以上面的角度先预留出来。这里涉及一个问题,最后再说。


        触摸move的时候,move的距离,就是圆转过的弧长,那么这样就可以算出转动的角度arc

function AvatarGallery:move(distance,endMove)
    endMove = endMove or false
    local arc = distance/self.r
    local view
    for i = 1,#self.itemViews do
        view = self.itemViews[i]
        view.currentArc = self:trimArc(view.originArc + arc)
        if endMove then
            view.originArc = self:trimArc(view.currentArc)
        end
        local x,scale,zorder = self:get2dXScaleZorder(view.currentArc)

        view:setPosition(x,0)
        view:setScale(scale)
        view:setLocalZOrder(zorder)
    end
end

        trimArc又是个什么鬼呢。。。因为角度可以无限叠加嘛,361度不就是1度么,trim就是把角度规整为0~359的范围。

        这里需要第二个参数,是因为,如果在触摸过程中,arc是这次触摸变动的角度,那么现在所处的角度,就应该是触摸点加上当前点。所以当触摸完成之后,应该要设置一下状态,把当前状态设置成这次触摸结束时候的状态。


        然后就是要算,算X的距离,算scale,算Zorder。一个一个来

function AvatarGallery:get2dXScaleZorder(arc)
    local x,scale,zorder
    x = self.r*math.cos(arc)
    
    scale = self.vd / (self.vd + self.r + self.r*math.sin(arc))
    
    zorder = (arc - math.rad(270))/(math.pi/4)
    zorder = 0 - math.abs(zorder)
    local zorderI,zorderF = math.modf(zorder)
    zorderI = zorderI *2
    if math.abs(zorderF)<0.49 then
        zorderI = zorderI+1
    end
    
    return x,scale,zorderI
end
        x距离最简单,一个cos完事,因为原点取的是重点,所以正负什么的也完全不用管。。。

        对比x,y其实也就是sin, 正负也刚好合适,然后对比上一个里面的公式,scale也就算出来了。

        

        zorder稍微麻烦一点,正规来说,应该是把所有节点的y算出来,然后做一个排序,但是这么做略微麻烦了一点,本着有懒就偷的原则,我发现了这么一招。。。先看图

        cocos2dx 实现gallery (三)_第1张图片

        我是按45度分布的,那么每个节点之间的间距就是45度。上图的纵轴,就是zorder的分部,纵轴越往上,Zorder越小。所以我们把角度全部减掉一个270,再除以45度,就成了下图这样

        cocos2dx 实现gallery (三)_第2张图片

        现在看出来什么了么。。。只要取个绝对值,然后取负数,不就搞定了么!!!

        唯一的问题,-4和-5这2个点的zorder反了。但是这无所谓,因为这2个节点在后面,我们只看得到前面的一个半圆。啦啦啦啦啦

        但是这是一种特殊情况。。。当轮子转起来的时候,是不会刚好在这些点上的,一般除下来,会是一个小数,但是zorder只能是整数,小数会自动截取。所以我们需要把精度再提升一下。

   zorder = (arc - math.rad(270))/(math.pi/4)
    zorder = 0 - math.abs(zorder)

        zorder的值小数部分,小数绝对值越小,说明靠上图0越近,应该靠前显示。再把zorder精度提高一下

    local zorderI,zorderF = math.modf(zorder)
    zorderI = zorderI *2
    if math.abs(zorderF)<0.49 then
        zorderI = zorderI+1
    end
        取值0.49是因为浮点数啊,精度啊,反正各种奇奇怪怪的问题。其实就应该是0.5,按中点来分。

        (PS:有人说直接把小数乘以一个10,我不得不说这是一个好办法。。。。但是怎么没想到)



        然后还有一个问题,滑动完成了之后,应该做一次归位,就是把那些没对齐的对齐,不然滑到一个很诡异的角度,多么奇葩。。。点击什么的逻辑也不好做

        if endMove then
            local factor = arc / (math.pi/8)
            factor = math.floor(math.ceil(factor)/2)
            arc = math.pi/4 * factor
            view.currentArc = self:trimArc(view.originArc + arc)
            view.originArc = self:trimArc(view.currentArc)
        end

        这个和上面那个方法类似,因为我们是按45度分布的,所以就以22.5度为分界,大于22.5就加一个,小于22.5就少一个。

        (PS:突然发现上面的zorder好像也能这么做。。。。。。。。)




        再最开始,还提到一个问题,这是一个关于效率的问题,下班回家下次再说。。。



你可能感兴趣的:(cocos2dx 实现gallery (三))