cocos 2d-x遊戲開發啓示錄(創世紀新篇)

   cocos 2d-x能夠在pc電腦window,mac操做系統上開發遊戲,也能夠在移動設備上開發遊戲,好比Android,windowphone等上開發,集成開發環境是:visual studio,eclipse,遊戲引擎包括:粒子場景,物理引擎,瓦片區域等等。 node

cocos 2d-x支持三種腳本語言:如c++,JavaScript,lua,你至少要熟悉一門腳本語言。 android

下面以cocos 2d-x的lua腳本語言開發一款《黑人當心》的遊戲。開發工具是cocos IDE c++

先看看效果圖: dom

一、項目結構 eclipse

二、編寫遊戲的開始場景 StartGame.lua 工具

開始場景只有一個開始按鈕和結束按鈕,比較簡單 開發工具

三、編寫遊戲中的小黑人精靈,小黑人精靈是一個精靈動畫,併爲小黑人建立一個矩形的剛體,用於碰撞檢測 動畫

hero lua ui

四、編寫遊戲中的障礙物 lua

五、編寫遊戲中的寶石精靈

gem lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264

--控制精靈的動做
Control=class("Control")
 
function Control:create(layer,positionY)
 
   local control=Control.new()
 
    control:init(layer,positionY)
 
return control
     
end
 
function Control:ctor()
 
self.size=nil
 
    self.layer = nil
    self.positionY=nil
     
    self.effectLabel=nil
 
    --移動的速度
    self.blockSpeed=2
--控制何時建立 障礙物精靈
self.createBlockHero=nil
self.nextBlockHero=nil
 
--控制何時建立寶石
self.createGem=nil
self.nextGem=nil
     
end
 
---
--@param cc.Layer layer
function Control:init(layer,positionY)
 
    self.size=cc.Director:getInstance():getWinSize()
 
   self.layer=layer
   self.positionY=positionY
     
    --建立一個英雄精靈
    local hero=Hero:createHero()
    print(self.positionY+hero:getContentSize().height / 2)
    hero:setPosition(50,self.positionY+hero:getContentSize().height / 2)
    self.layer:addChild(hero)
     
 
--跳躍按鈕
    local itemControl=cc.MenuItemImage:create(Res.control_n,Res.control_p)
    itemControl:setScale(0.35)
    itemControl:setPosition( self.size.width-40,30)
    itemControl:registerScriptTapHandler(function()
 
            if hero:getPositionY() < hero:getContentSize().height + self.positionY then
 
                hero:getPhysicsBody():setVelocity(cc.p(0, 500))
 
            end
            
 
    end)
 
    local menu=cc.Menu:create(itemControl)
    menu:setPosition(0,0)
    self.layer:addChild(menu)
     
     
    --速度變化特效
    self.effectLabel=cc.Label:createWithTTF("","fonts/Marker Felt.ttf", 32)
    self.effectLabel:setColor(cc.c3b(0,0,0))
    self.effectLabel:enableGlow(cc.c4b(0,0,0,0))
    self.effectLabel:setPosition(self.size.width-50,self.positionY+self.size.height/2-self.effectLabel:getContentSize().height/2)
    self.layer:addChild(self.effectLabel)
--    self.effectLabel:setVisible(false)
     
    --初始化計數參數
    self:reset()
     
end
 
 ---
    --@param touch cc.Touch
    --@param event cc.Event
--   function Control:r(touch, event)
--  
--   end
     
 
function Control:reset()
 
    self.createBlockHero=0
    self.nextBlockHero=math.random(0,99)+120
     
end
 
--建立障礙物精靈 score分數
function Control:updateBlock(score)
 
    --createBlockHero計數增長
    self.createBlockHero=self.createBlockHero+1
     
     
--  隨機時間生成障礙物
    if self.createBlockHero >= self.nextBlockHero then
     
        
        --控制障礙物移動的速度
        ---
        --@param cc.Sprite blockSprite
        local blockSprite=Block:createBlock(self.blockSpeed)
        
        if score >=20 and score < 50 then
            
            print("blockSpeed:",self.blockSpeed)
            if self.blockSpeed < 3 then
                 
                self:test("+3")
               self.blockSpeed=3
                 
            end
             
            
             
        elseif score >=50 and score < 80 then
 
 
            if self.blockSpeed < 3 then
                self:test("+5")
                self.blockSpeed=5
            end
           
             
        elseif score >=80 and score < 100 then
 
            if self.blockSpeed < 5 then
                self:test("+6")
                self.blockSpeed=6
            end
             
             
        elseif score >=100 and score < 150 then
 
            if self.blockSpeed < 6 then
                self:test("+7")
                self.blockSpeed=7
            end
             
        elseif score >=150 and score < 180 then
 
            if self.blockSpeed < 7 then
                self:test("+8")
                self.blockSpeed=8
            end
             
        elseif score >=180 and score < 250 then
         
            if self.blockSpeed < 8 then
                self:test("+10")
                self.blockSpeed=10
            end
         
        elseif score >= 250 and score < 320 then
         
            if self.blockSpeed < 10 then
                self:test("+12")
                self.blockSpeed=12
            end
             
        elseif score >= 320 and score < 400 then
 
            if self.blockSpeed < 12 then
                self:test("+15")
                self.blockSpeed=15
            end
             
        elseif score >= 400 then
 
            if self.blockSpeed < 15 then
                self:test("+18")
                self.blockSpeed=18
            end
         
        end
         
        --取整0、2
        math.randomseed(os.time())
        local index1=math.floor(math.random(0,1))
        local positionX1=self.size.width
        local positionY1=math.random(self.positionY+120+10,self.size.height-35)
         
         
if index1 >= 1 then
 
            for i=0 ,index1 do
 
                local gem=Gem:cretateGem()
                gem:setPosition(positionX1,positionY1)
                self.layer:addChild(gem)
 
                gem:setGemSpeed(1)
                positionX1=positionX1-25
 
            end
     
end
         
         
         
        --取整0、2
        math.randomseed(os.time())
        local index2=math.floor(math.random(0,2))
        local positionX2=self.size.width;
         
        if index2 >= 1 then
         
            for i=0,index2 do
 
                local gem=Gem:cretateGem()
                gem:setPosition(positionX2,self.positionY+gem:getContentSize().height / 5)
                self.layer:addChild(gem)
                gem:setGemSpeed(self.blockSpeed)
 
                positionX2=positionX2+25
 
            end
             
        end
        
         
        blockSprite:setPosition(positionX2+10,self.positionY+blockSprite:getContentSize().height / 2)
        self.layer:addChild(blockSprite)
         
         
        --從新計數
        self:reset()
         
    end
end
 
 
function Control:test(effectType)
    self.effectLabel:setString(effectType)
    self.effectLabel:setVisible(true)
    print("effectLabel")
    self.effectLabel:runAction(cc.Sequence:create(cc.ScaleTo:create(1,2),cc.CallFunc:create(function(sender)
        sender:setVisible(false)

    end)))


     
end
 
 
function Control:setBlockSpeed(speed)
    self.blockSpeed=speed
end
 
function Control:getBlockSpeed()
    return self.blockSpeed

end


 
 
return Control

七、編寫遊戲層 GameLayer.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
GameLayer=class("GameLayer",function ()
 
        return cc.LayerColor:create(cc.c4b(255,255,255,255))
     
end)
 
 
function GameLayer:ctor()
 
--控制類
self.control=nil
     
self.score=0
 
self.gem=0     
     
end
 
function GameLayer:createLayer()
    local layer=GameLayer.new()
     
    layer:bg()
     
    return layer
end
 
 
--遊戲背景圖
function GameLayer:bg()
 
    local size=cc.Director:getInstance():getWinSize()
 
    --建立一個圍繞屏幕四周的物理邊界
    local node=cc.Node:create()
    node:setPhysicsBody(cc.PhysicsBody:createEdgeBox(cc.size(size.width,size.height),cc.PHYSICSBODY_MATERIAL_DEFAULT,5))
    node:setPosition(size.width/2,size.height/2+50)
    self:addChild(node)
     
     
     
--  地面(一條線)
    local edgeSprite=cc.Sprite:create()
    edgeSprite:setTextureRect(cc.rect(0,0,size.width,2))
    edgeSprite:setColor(cc.c3b(125, 125, 0))
    edgeSprite:setPosition(size.width/2,50)
    self:addChild(edgeSprite)
     
    --分數
    local labelScore=cc.Label:createWithTTF("","fonts/Marker Felt.ttf", 20)
    labelScore:setColor(cc.c3b(0,0,0))
    labelScore:setString(self.score)
    labelScore:setPosition(size.width-80,size.height-35)
    self:addChild(labelScore)
     
    --寶石個數
    local labelGem=cc.Label:createWithTTF("","fonts/Marker Felt.ttf", 28)
    labelGem:setColor(cc.c3b(0,0,0))
    labelGem:setString(self.gem)
    labelGem:setPosition(size.width-180,size.height-35)
    self:addChild(labelGem)
     
    --寶石
    local cache=cc.SpriteFrameCache:getInstance()
    cache:addSpriteFrames(Res.gemPlist,Res.gemPng)
     
     
     
    self.control=Control:create(self,50)
     
    local spGem=cc.Sprite:createWithSpriteFrameName("green.png")
    spGem:setPosition(size.width-220,size.height-35)
    spGem:setScale(0.5)
    self:addChild(spGem)
     
    self:scheduleUpdateWithPriorityLua(function(dt)
     
    --分數
            self.score = self.score + dt
            labelScore:setString(string.format("%#.2f",self.score))
            
     
            self.control:updateBlock(self.score)
     
    end,0)
     
     
    --一個body的CategoryBitmask和另外一個body的ContactTestBitmask的邏輯與的結果不等於0時,接觸事件將被髮出,不然不發送。
    --一個body的CategoryBitmask和另外一個body的CollisionBitmask的邏輯與結果不等於0時,他們將碰撞,不然不碰撞
    --須要兩個body相互位與運算的值都是大於0時纔會發生碰撞檢測和發送接觸事件通知  
     
    --  碰撞監聽
    local conListener=cc.EventListenerPhysicsContact:create();
    conListener:registerScriptHandler(function(contact)
 
            print("---contact-碰撞了--")
             
            --    處理遊戲中精靈碰撞邏輯
            local node1=contact:getShapeA():getBody():getNode()
            local name1=node1:getName()
            local tag1=node1:getTag()
            print("name1:",name1)
           
 
            local node2=contact:getShapeB():getBody():getNode()
            local name2=node2:getName()
            local tag2=node2:getTag()
            print("name2:",name2)
             
            --英雄碰到寶石
            if name1 == "gem" then
             
            local x,y=node1:getPosition()
             
                self.gem=self.gem+1
                labelGem:setString(string.format("%s",self.gem))
                 
                labelGem:runAction(cc.Sequence:create(cc.ScaleTo:create(0.2,1.5),cc.CallFunc:create(
                function (sender)
                     
                        sender:runAction(cc.ScaleTo:create(0.1,1))
                     
                end)))
                 
                if nil ~= node1 then
                    self:removeChild(node1,true)
                end
               
             
--                node1:runAction(cc.Sequence:create(cc.Spawn:create(cc.MoveTo:create(0.1,cc.p(node1:getPositionX(),node1:getPositionY()+50)),cc.ScaleTo:create(0.1,0.5),cc.FadeOut:create(0.1)),
--                cc.CallFunc:create(function(sender)
--                    self:removeChild(sender,true)
--                    end)))
             
            --英雄碰到障礙物死亡
            elseif name1 == "hero" then
             
                local x,y=node2:getPosition()
                 
                cc.Director:getInstance():replaceScene(StartGame:createScene())
                 
            elseif name2 == "hero" then
 
                local x,y=node2:getPosition()
 
                cc.Director:getInstance():replaceScene(StartGame:createScene())
             
            end
             
            return true
    end,cc.Handler.EVENT_PHYSICS_CONTACT_BEGIN)
 
    cc.Director:getInstance():getEventDispatcher():addEventListenerWithSceneGraphPriority(conListener,self)
     
end
 
return GameLayer

八、編寫遊戲場景 GameScene.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
--遊戲場景
GameScene=class("GameScene",function ()
    return cc.Scene:createWithPhysics()
     
end)
 
function GameScene:createScene()
 
    local scene=GameScene.new()
 
    --  設置調試
--    scene:getPhysicsWorld():setDebugDrawMask(cc.PhysicsWorld.DEBUGDRAW_ALL)
    scene:getPhysicsWorld():setGravity(cc.p(0, -1000))
 
    local layer=GameLayer:createLayer()
 
    scene:addChild(layer)
    
    return scene
 
end
 
 
return GameScene

九、這裏我用類把圖片和加載的Lua文件封裝了

Require.lua 遊戲加載的Lua文件

1
2
3
4
5
6
7
8
9
10
11
12
13
--引入lua類
require("Cocos2d")
require("Cocos2dConstants")
require("bitExtend")
 
require("src/game/res/Res")
require("src/game/start/StartGame")
require("src/game/scene/GameScene")
require("src/game/scene/GameLayer")
require("src/game/sprite/Block")
require("src/game/sprite/Hero")
require("src/game/sprite/Control")
require("src/game/sprite/Gem")

Res.lua 遊戲用到的圖片資源

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
--圖片資源類
Res={}
 
--開始按鈕
Res.start_n="qq_n.png"
Res.start_p="qq_p.png"
 
Res.heroPng="hero.png"
Res.heroPlist="hero.plist"
 
Res.control_n="control_n.png"
Res.control_p="control_p.png"
 
Res.gemPlist="gem.plist"
Res.gemPng="gem.png"

十、修改main.lua

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
--引入lua文件
require "src/game/res/Require"
 
-- cclog
local cclog = function(...)
    print(string.format(...))
end
 
-- for CCLuaEngine traceback
function __G__TRACKBACK__(msg)
    cclog("----------------------------------------")
    cclog("LUA ERROR: " .. tostring(msg) .. "\n")
    cclog(debug.traceback())
    cclog("----------------------------------------")
    return msg
end
 
local function main()
    collectgarbage("collect")
    -- avoid memory leak
    collectgarbage("setpause", 100)
    collectgarbage("setstepmul", 5000)
     
    cc.FileUtils:getInstance():addSearchPath("src")
    cc.FileUtils:getInstance():addSearchPath("res")
     
    cc.FileUtils:getInstance():addSearchPath("src/game/res")
    cc.FileUtils:getInstance():addSearchPath("src/game/start")
    cc.FileUtils:getInstance():addSearchPath("src/game/scene")
    cc.FileUtils:getInstance():addSearchPath("src/game/sprite")
     
     
    cc.FileUtils:getInstance():addSearchPath("res/game")
    cc.FileUtils:getInstance():addSearchPath("res/game/hero")
    cc.FileUtils:getInstance():addSearchPath("res/game/gem")
         
    cc.Director:getInstance():getOpenGLView():setDesignResolutionSize(480, 320, 0)
    cc.Director:getInstance():setDisplayStats(false)
     
    --進入遊戲場景
    local scene = require("StartGame")
    local gameScene =scene:createScene()
 
     
    if cc.Director:getInstance():getRunningScene() then
        cc.Director:getInstance():replaceScene(gameScene)
    else
        cc.Director:getInstance():runWithScene(gameScene)
    end
 
end
 
 
local status, msg = xpcall(main, __G__TRACKBACK__)
if not status then
    error(msg)
end
十一、這裏發佈到android上,Cocos Code IDE提供了一鍵發佈,很是的好用,須要設置下環境

而後選擇項目打包

等待幾分鐘就會看到打包成功了

遊戲開發完畢。

end

相關文章
相關標籤/搜索