1. 程式人生 > >入門級--《見縫插針》遊戲開發

入門級--《見縫插針》遊戲開發

</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
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)
uiPushButton的onButtonClicked函式來實現介面跳轉
 

接下來就跳轉到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