cocos 2d-x游戏开发启示录(创世纪新篇)

   cocos 2d-x可以在pc电脑window,mac操作系统上开发游戏,也可以在移动设备上开发游戏,比如Android,windowphone等上开发,集成开发环境是:visual studio,eclipse,游戏引擎包括:粒子场景,物理引擎,瓦片区域等等。

cocos 2d-x支持三种脚本语言:如c++,JavaScript,lua,你至少要熟悉一门脚本语言。

下面以cocos 2d-x的lua脚本语言开发一款《黑人小心》的游戏。开发工具是cocos IDE

先看看效果图:

cocos 2d-x游戏开发启示录(创世纪新篇)

1、项目结构

cocos 2d-x游戏开发启示录(创世纪新篇)

2、编写游戏的开始场景 StartGame.lua

cocos 2d-x游戏开发启示录(创世纪新篇)

cocos 2d-x游戏开发启示录(创世纪新篇)

开始场景只有一个开始按钮和结束按钮,比较简单

cocos 2d-x游戏开发启示录(创世纪新篇)

3、编写游戏中的小黑人精灵,小黑人精灵是一个精灵动画,并为小黑人创建一个矩形的刚体,用于碰撞检测

hero lua

cocos 2d-x游戏开发启示录(创世纪新篇)cocos 2d-x游戏开发启示录(创世纪新篇)

4、编写游戏中的障碍物

cocos 2d-x游戏开发启示录(创世纪新篇)cocos 2d-x游戏开发启示录(创世纪新篇)

5、编写游戏中的宝石精灵

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

7、编写游戏层 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

8、编写游戏场景 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

9、这里我用类把图片和加载的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"

10、修改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
11、这里发布到android上,Cocos Code IDE提供了一键发布,非常的好用,需要设置下环境

cocos 2d-x游戏开发启示录(创世纪新篇)

然后选择项目打包

cocos 2d-x游戏开发启示录(创世纪新篇)

等待几分钟就会看到打包成功了

cocos 2d-x游戏开发启示录(创世纪新篇)

游戏开发完毕。

end

你可能感兴趣的:(cocos 2d-x游戏开发启示录(创世纪新篇))