cocos2d 3.10 + lua 黃金礦工實現

又寫了一個小遊戲,黃金礦工,這裏記錄下關鍵片段代碼
--創建物理場景
cc.Scene:createWithPhysics()

-- 加載金幣類的道具,(金幣,鑽石,遊動的魚,道具袋,石頭,魚骨頭)

-- 輔助行數,隨機返回一個行數
function LakeTreasureView:getHangIdx()
    local temp = self.HangIdx[math.random(1,#self.HangIdx)]
    for k,v in pairs(self.HangIdx) do
        if v == temp then
            table.remove(self.HangIdx,k)
            break
        end
    end    
    return temp
end

-- 給出金幣的隨機地址,返回Pos,要求固定行數,所以限制了邊界
function LakeTreasureView:getCellPos(idx)
    --x,x,y,y
    local hangPos = {{50,1200,50,100},
                    {50,1200,150,200},
                    {50,1200,250,300},
                    {50,1200,350,400},
                    {50,1200,410,450}}
    local temp = {}
    for i=1,9 do
        local ct = {}
        if 1 == i then
            ct.x = math.random(50*i,i*138)
        else
            ct.x = math.random((i-1)*138+30,i*138-30)
        end

        ct.y = math.random(hangPos[idx][3],hangPos[idx][4])

        table.insert(temp,ct)
    end
    return temp
end

--既然有屏幕地址了,加載資源,設置位置,略

-- 設置繩子和鉤子
function LakeTreasureView:hookFun()
    local speed = 2
    local ltcsv = {}
    -- local temp = getCsvDataForPath("temp.csv")
    -- for k,v in pairs(temp) do
    --     ltcsv[v.id] = v.reward
    -- end

    --繩子
    local rope = g_getChildNodeByName(self.csbNode,"Image_5")
    --鉤子
    local hook = g_getChildNodeByName(self.csbNode,"Image_3")
    --觸碰層
    local hookTouch = g_getChildNodeByName(self.csbNode,"Image_1")

    --給鉤子一個特殊標籤
    hook:setTag(999)
    --設置物理特性
    self:setBody(hook)

    local startPosX = rope:getPositionX()
    local startPosY = rope:getPositionY()

    --讓鉤子擺動
    local shakeAction = cc.RepeatForever:create(cc.Sequence:create(cc.RotateTo:create(speed,-30),cc.RotateTo:create(speed,-140)))
    --爲了讓鉤子擺動更自然
    local beging = cc.Sequence:create(cc.RotateTo:create(-1,-90))
    rope:runAction(beging)
    rope:runAction( shakeAction )
    --觸碰事件
    hookTouch:setTouchEnabled(true)
    hookTouch:addClickEventListener(function(sender,event)
        --哨兵判斷,鉤子被操作後,未歸零前不能再次操作
        if 0 == self.hookgoing then
            --鉤子是繩子的子節點,所以這裏只要停止繩子的擺動,就可以把鉤子的擺動一起停止
            rope:stopAllActions()
            -- 這一套動作,讓繩子朝當前方向發射指定長度,然後執行回收操作,包括所有的子節點,注意,這裏只管發射和回收,下面這行代碼非常關鍵,控制了繩子朝當前方向發射的角度計算
            local tempAction = cc.Sequence:create(cc.MoveBy:create(speed,cc.p(-550*math.tan(math.pi/180*(0-90)),-550)),cc.CallFunc:create(function()
                rope:runAction(cc.Sequence:create(cc.MoveTo:create(speed, cc.p(startPosX,startPosY)),cc.CallFunc:create(function()
                    self.hookgoing = 0
                    rope:runAction(cc.RepeatForever:create(cc.Sequence:create(cc.RotateTo:create(speed,-30),cc.RotateTo:create(speed,-140))))
                    end)))
                end))
            rope:runAction(tempAction)
            self.hookgoing = 1
        end
    end)

    --上面那裏只管發射回收,這裏纔是碰撞事件監測
    local conListener=cc.EventListenerPhysicsContact:create()  
    conListener:registerScriptHandler(function(contact)    
        --哨兵判斷,如果鉤子抓住一個東西之後,忽略所有的碰撞事件
        if 0 == self.ongoing then

            local node1=contact:getShapeA():getBody():getNode()    
            local node2=contact:getShapeB():getBody():getNode()  
            if not node1 or not node2 then return end   
            --沒錯,這個特殊標籤就是鉤子,如果兩個碰撞體,沒有一個是鉤子,就不處理,(比如遊動的魚碰到金幣)
            if node1:getTag() ~= 999 and node2:getTag() ~= 999 then return end

            --還是老套路,如果碰到東西,首先停止鉤子的發射(父節點是繩子)
            rope:stopAllActions()
            local returnAction = cc.Sequence:create(cc.MoveTo:create(speed, cc.p(startPosX,startPosY)),cc.CallFunc:create(function()
                    self.ongoing = 0
                    self.hookgoing = 0
                    --回到鉤子的起始地址,鉤子上的物品隱藏起來
                    self.tempNode:setVisible(false)
                    --播放一些收穫動畫之類的
                    -- self.scoreAnimation:play("animation0", false)
                    rope:runAction(cc.RepeatForever:create(cc.Sequence:create(cc.RotateTo:create(speed,-30),cc.RotateTo:create(speed,-140))))

                    -- 一些業務邏輯
                    -- for k,v in pairs(self.scoreData) do
                    --     if tonumber(k) == self.tempNode:getTag() then
                    --         self.scoreNum = self.scoreNum + ltcsv[v]
                    --     end
                    -- end                   
                    -- self.score:setString(self.scoreNum)
                    -- end))
            rope:runAction(returnAction)

            self.tempNode = nil
            local parNode = nil
            --判斷碰撞的兩個誰是鉤子
            if node1:getTag() == 999 then
                self.tempNode = node2
                parNode = node1
            else
                self.tempNode = node1
                parNode = node2
            end

            --將被碰撞的物品,加載到鉤子上,這樣上面的鉤子動作回拉的時候,就會帶着這個物品一起回拉
            self.tempNode:retain()
            self.tempNode:removeFromParent()
            self.tempNode:addTo(parNode)
            self.tempNode:setPosition(cc.p(40,-10))
            self.ongoing = 1
            return true    
        end
    end,cc.Handler.EVENT_PHYSICS_CONTACT_BEGIN)    
    cc.Director:getInstance():getEventDispatcher():addEventListenerWithSceneGraphPriority(conListener,self) 
end

-- 設置物理特性
function LakeTreasureView:setBody(tNode,pos,idx,i)
    if tNode == nil then return end
    local pos = pos or nil
    local idx = idx or 0

    if pos ~= nil and idx ~= 0 then 
        tNode:setPosition(cc.p(pos[idx].x,pos[idx].y))
        tNode:setTag(tonumber(i..idx))
    end

    -- 一些API 兩個碰撞體設置成同一個,就可以被監測到碰撞
    local box = cc.PhysicsBody:createCircle(tNode:getContentSize().width/3)  
    if box then
        -- box:setDynamic(true)  
        box:setCategoryBitmask(1)    
        box:setContactTestBitmask(1)    
        box:setCollisionBitmask(2)  
        box:setGravityEnable(false)
        tNode:setPhysicsBody(box) 
    end
end

不過遇到一個問題,每次在Windows上打開的時候,都會出現下圖的這個問題,在手機上打開就不會出現,很費解



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章