又寫了一個小遊戲,黃金礦工,這裏記錄下關鍵片段代碼
--創建物理場景
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上打開的時候,都會出現下圖的這個問題,在手機上打開就不會出現,很費解