入門級--《見縫插針》遊戲開發
阿新 • • 發佈:2019-01-09
</pre>場景只用了一個MainScene,遊戲的介面轉換都是在層上實現的。<p></p><p></p><p>MainScene的內容:純色背景一個:<span style="white-space:pre"> </span></p><pre name="code" class="html"> display.newColorLayer(cc.c4b(225,225,225,225))
:addTo(self,-1)
然後有一個層放置文字,標籤等ui
uiPushButton的onButtonClicked函式來實現介面跳轉self.backLayer = --display.newColorLayer(cc.c4b(225,225,225,225)) display.newLayer() <span style="white-space:pre"> </span>:addTo(self,1) <span style="white-space:pre"> </span>--self.backLayer:setTouchEnabled(true) <span style="white-space:pre"> </span>self.level = 1; cc.ui.UILabel.new({ UILabelType = 2, text = "見縫插針", size = 64}) :align(display.CENTER, display.cx, display.height-150) :addTo(self.backLayer) self.start_bt = cc.ui.UIPushButton.new("frame.jpg") <span style="white-space:pre"> </span>:setButtonLabel(cc.ui.UILabel.new({text = "關卡"..self.level,size = 32})) <span style="white-space:pre"> </span>:onButtonClicked(function () <span style="white-space:pre"> </span>print("1") self.gameLayer = GameLayer.new():addTo(self)--切換到遊戲層 self.backLayer:removeFromParent()--把ui元件所在的層都移除 <span style="white-space:pre"> </span>end) <span style="white-space:pre"> </span>:align(display.CENTER, display.cx, display.height*2/3-40) <span style="white-space:pre"> </span>:addTo(self.backLayer)
接下來就跳轉到Gamelayer裡了,這個就是遊戲介面了,實現:首先用一個節點來放置需要轉動的大球和小球,然後通過幀定時器讓他們轉動;另外這個層是可觸控的,點選螢幕則將小球新增到轉動的節點上,並且將下方按序排列的待插入的小球整體上移。具體程式碼:
首先初始化函式實現兩個功能:一個是觸控事件監聽,一個是設定不同關卡的引數
self.levelTable = { [1] = {name ="第一關" , angle = 7 , startnum = 1 , waitnum = 10} , [2] = {name ="第二關" , angle = 3 , startnum = 2 , waitnum = 10}, [3] = {name ="第三關" , angle = 3.5, startnum = 3 , waitnum = 10}, [4] = {name ="第四關" , angle = 3.5 , startnum = 4 , waitnum = 10} , [5] = {name ="第五關" , angle = 3.5 , startnum = 4 , waitnum = 10} , [6] = {name ="第六關" , angle = 4 , startnum = 5 , waitnum = 10} , [7] = {name ="第七關" , angle = 4 , startnum = 5 , waitnum = 10} , [8] = {name ="第八關" , angle = 4.5, startnum = 6 , waitnum = 10} } self:addNodeEventListener(cc.NODE_TOUCH_EVENT,function () print("add Small boal") self:addBoal() end) --新增觸控事件監聽(為什麼touchnabale不在這裡寫呢,因為當從結果介面跳回遊戲介面時,要從不可觸控改為可觸控,此時是不執行ctor的所以不在這裡實現是否可觸控的設定)
self:onStart(1) --遊戲初始化函式
然後是進入onstart函式,這個函式裡實現了:首先生成空節點,用於把需要轉動的元素都新增上來,實現轉動,這個節點上有一個大球,以及遊戲開始時就有的小球;設定可觸控;設定定時器(實現轉動)
<span style="white-space:pre">function GameLayer:onStart(level)</span> --傳入進入遊戲時的關卡數
<span style="white-space: pre;"> </span>self.level = level
self.addboal_ ={} --已填加到轉動節點的小球
self.waitboal_ ={} --待新增的小球
if self.turnNode then --當從結果介面切迴游戲介面時,需要將轉動節點的內容清空
--self.turnNode:removeFromParent() --在callback裡已經移除了:self:removeAllChildren()
self.turnNode = nil
end
self.turnNode = display.newNode() --轉動節點
:align(display.CENTER,display.cx, display.height*2/3+30)
:addTo(self)
--旋轉角度
self.angle =self.levelTable[self.level].angle
--當前轉過的角度
self.turnangle=0
--初始化小球數
self.startnum = self.levelTable[self.level].startnum
self.waitnum = self.levelTable[self.level].waitnum
local bigboal = display.newSprite("boal1.png")
:addTo(self.turnNode)
print("大球位置:",bigboal:getPosition())
local R = 150 +48
for i =1 ,self.startnum do
--計算初始化的小球平均分配
local x = math.sin(math.rad(360/self.startnum*(i-1)))*R
local y = math.cos(math.rad(360/self.startnum*(i-1)))*R
local smboal = display.newSprite("s.png")
:pos(x, y)
:addTo(self.turnNode)
self.addboal_[smboal]= smboal
dump(self.addboal_)
end
for i =1 ,self.waitnum do --待插入的小球
local x = display.cx
local y = display.height/2-100-60*i
local smboal = display.newSprite("s.png")
:pos(x,y)
:addTo(self)
<pre name="code" class="html"><span style="font-family: Arial, Helvetica, sans-serif;"><span style="white-space:pre"> </span>--新增待插入小球上的數字</span>
local num = cc.ui.UILabel.new({text = self.waitnum-i+1,size= 30}):addTo(smboal)num:setPosition(-num:getContentSize().width/2+smboal:getContentSize().width/2,smboal:getContentSize().height/2)self.waitboal_[self.waitnum-i+1]
= smboalend---設定可觸控self:setTouchEnabled(true)--設定定時器,需要在最開頭新增 local scheduler = require(cc.PACKAGE_NAME .. ".scheduler")if self.timer thenscheduler.unscheduleGlobal(self.timer) ---停止上一關遊戲時的定時器self.timer = nilendself.timer = scheduler.scheduleGlobal(function()
每0.05秒執行一次self:update()函式self:update() end,0.05)
end
接下來實現update函式
function GameLayer:update()
if self.waitnum <= 0 then
scheduler.unscheduleGlobal(self.timer)
self:setTouchEnabled(false)
local param = {} ---傳入結果介面需要的引數,是否成功,當前關卡,以及當從結果介面切回時呼叫的函式
param.success = 1
param.level = self.level
param.callback = handler(self, self.callback)
local gameWin = gameWin.new(param) --切入結果介面
cc.Director:getInstance():getRunningScene():addChild(gameWin, 120)
return
end
self.turnNode:rotateBy(0,self.angle) --旋轉大球和小球
self.turnangle = math.mod(self.turnangle+self.angle,360)
end
實現觸控響應的函式
function GameLayer:addBoal()
if self.waitnum <= 0 then
-- scheduler.unscheduleGlobal(self.timer)
self:setTouchEnabled(false)
return
end
local x = math.sin(math.rad(self.turnangle )) * 200
local y = math.cos(math.rad(self.turnangle + 180)) * 200
local smboal = display.newSprite("s.png")
:pos(x , y)
:addTo(self.turnNode)
--判斷是否碰撞
for k,p in pairs(self.addboal_) do
local dx = p:getPositionX()-smboal:getPositionX()
local dy = p:getPositionY()-smboal:getPositionY()
local dist = math.sqrt(dx*dx+dy*dy)
if dist<48 then
--失敗處理
print("gameover")
scheduler.unscheduleGlobal(self.timer)
local param = {}
param.success = 0
param.level = self.level
param.callback = handler(self, self.callback)
local gameWin = gameWin.new(param)
cc.Director:getInstance():getRunningScene():addChild(gameWin, 120)
end
end
self.addboal_[smboal] = smboal
self.waitboal_[self.waitnum]:removeFromParent()
self.waitboal_[self.waitnum]=nil
self.waitnum= self.waitnum-1
for i =1 ,self.waitnum do
local x = display.cx
local y = display.height/2-100-60*i
self.waitboal_[self.waitnum-i+1]:setPosition(x,y)
end
print(self.waitnum)
end
結果層實現:
local gameWin = class("gameWin", function ( )
return display.newColorLayer(cc.c4b(225, 225, 225, 225))
end)
function gameWin:ctor(param)
self.success = param.success
self.callback = param.callback
self.level = param.level
local text1 = "text"
local text2 = "text"
if self.success ==1 then
text1 = "YOU WIN !!!"
text2 = "下一關"
self.level = self.level +1
else
text1 = "YOU LOSE !!!"
text2 = "重玩本關"
end
cc.ui.UILabel.new({
UILabelType = 2, text = text1, size = 64})
:align(display.CENTER, display.cx, display.height-150)
:addTo(self)
self.start_bt = cc.ui.UIPushButton.new("frame.jpg")
:setButtonLabel(cc.ui.UILabel.new({UILableType = 2 ,text = text2,size = 32}))
:onButtonClicked(handler(self, self.btnCallBack))
:align(display.CENTER, display.cx, display.height*2/3-40)
:addTo(self)
--self.start_bt:setButtonLabel(cc.ui.UILabel.new({
-- UILabelType = 2, text = "下一關", size = 30 }))
end
function gameWin:btnCallBack()
self.callback(self.level)
self:removeFromParent()
end