cocos 2d-x可以在pc电脑window,mac操作系统上开发游戏,也可以在移动设备上开发游戏,比如Android,windowphone等上开发,集成开发环境是:visual studio,eclipse,游戏引擎包括:粒子场景,物理引擎,瓦片区域等等。
cocos 2d-x支持三种脚本语言:如c++,JavaScript,lua,你至少要熟悉一门脚本语言。
下面以cocos 2d-x的lua脚本语言开发一款《黑人小心》的游戏。开发工具是cocos IDE
先看看效果图:
1、项目结构
2、编写游戏的开始场景 StartGame.lua
开始场景只有一个开始按钮和结束按钮,比较简单
3、编写游戏中的小黑人精灵,小黑人精灵是一个精灵动画,并为小黑人创建一个矩形的刚体,用于碰撞检测
hero lua
4、编写游戏中的障碍物
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
|
然后选择项目打包
等待几分钟就会看到打包成功了
游戏开发完毕。
end