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

先看看效果图:

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

---

[email protected] 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

---

[email protected] touch cc.Touch

[email protected] 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

--控制障碍物移动的速度

---

[email protected] 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提供了一键发布,非常的好用,需要设置下环境

然后选择项目打包

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

游戏开发完毕。

end

时间: 2024-10-12 21:21:24

cocos 2d-x游戏开发启示录(创世纪新篇)的相关文章

c#项目开发启示录(创世纪新篇)

网站管理员下个月就要去进行Java开发了,以后C#碰的就少了,平时一些经验都记在OneNote里面,现在收集整理出来,因为只能利用交接工作的打酱油的时间,...... C#开发: 1.目标平台的选择:32位操作系统在编译VS里的程序时,根据需要设置项目属性的"目标平台"为x86.如果设置为AnyCPU,则在VS 2005里面是不能"编辑并继续"的. 在选择x86和AnyCPU都可以在32位操作系统上使用. --选择x86在64位服务器上运行,可能会造成类库无法加载的

HTML5 2D平台游戏开发——地图绘制篇

此前已经完成了一部分角色的动作,现在还缺少可以交互的地图让游戏看起来能玩.不过在开始之前应当考虑清楚使用什么类型的地图,就2D平台游戏来说,一般有两种类型的地图,Tile-based和Art-based,即基于瓦片风格和美术风格两种.Tile-based的典型代表是<Super Mario>(超级马里奥),Art-based记不太清楚了,能够回想起来的是去年出的一款叫做<Owlboy>(猫头鹰男孩)的游戏.      Super Mario  Owlboy 由于Art-based的

开发者必须mark的一款2D移动游戏开发工具

摘要:灸热的夏季渐行渐远,凉爽的秋季迈着轻盈的脚步悄悄来到我们身边.站在初秋的窗前,凝望着远山.白云,总会心生很多遐想,总会有百感交集的情愫浮上心头.我想我是喜欢这个季节的."早上好"."今天又堵车了",伴随着同事们的说话声,突然意识到,额.我神游了--咳咳.步入正题,小编今天跟大家分享一款轻轻松松便能够实现2D画面动态光影的开发工具--Sprite Lamp. 何为Sprite Lamp? 开门见山,Sprite Lamp是一款能够帮助游戏开发者将2D画面与动态光

Canvas 2D小游戏开发总结-1

由于需要快速开发 在拿到需求时,并没有时间去学习Cocos2d-JS\Egret\lufy legend这样的H5游戏引擎 于是硬着头皮直接用js建模.响应用户.渲染画面 在此要感谢这篇文章http://www.lostdecadegames.com/how-to-make-a-simple-html5-canvas-game/给我的启发 然后我罗列一下开发过程中遇到的问题,以便更好地完善自己的游戏框架 1.按钮问题dom vs canvas 有时候有代码洁癖,会觉得用canvas做代码看起来干

MFC建立应用程序启示录(创世纪新篇)

MFC是vc+的核心部分,需要一定的编程功底. Windows编程基础 编制一个功能强大和易操作的Windows应用程序所需要的代码肯定会比一般的C++程序要多得多,但并不是所有的代码都需要自己从头开始编写,因为Visual C++不仅提供了常用的Windows应用程序的基本框架,而且可以在框架程序中直接调用Win32 API(Application Programming Interface, 应用程序接口)函数.这样,用户仅需要在相应的框架位置中添加自己的代码或修改部分代码就可实现Windo

Unity3d/2d手机游戏开发第二版 (金玺曾) 随书资源

http://pan.baidu.com/s/1c0xpn4s Unity3d2d手机游戏开发配书资源文件.rar 1.36G 书上的链接坏掉了,我在论坛上面买了一份,放这分享给买了书找不到资源的同学.

HTML5 2D平台游戏开发——角色动作篇之蓄力技

在很多动作游戏中,玩家操控的角色可以施放出比普通攻击更强力的蓄力技,一般操作为按住攻击键一段时间然后松开,具体效果像下面这张图: 要实现这个操作首先要记录下按键被按住的时间,初始是0: this.sabreChargeTime = 0; 接下来是能够施放技能所需要的时间,超过这个时间后松开按键,即可施放出技能,否则无效: this.MAX_SABRE_CHARGE_TIME = 150; 代码结构如下: if (key[74]) {//攻击 this.updateSabreCharge(); /

HTML5 2D平台游戏开发——角色动作篇之指令技

一般在动作游戏中,玩家可以通过对输入设备输入一系列的指令让角色完成某个或多个特定的动作.以格斗游戏<拳皇>为例,键入↓→↓← + A or C可以触发IORI的必杀技八稚女: 通过一系列输入最终让角色完成某个动作,就是指令技.其原理是通过将玩家的键入与指令技列表中的键位进行比对,如果一致,就匹配成功.以下是JavaScript的简单实现: class Instruct { constructor(callback) { this.instructs = {}; this.MAX_INTERVA

HTML5 2D平台游戏开发——角色动作篇之斩击

目前为止,角色除了基本的移动外还什么都不能做,于是我打算先实现角色的攻击动画.角色的普通攻击一共可以分为三个阶段: 一段斩 二段斩 三段斩 触发方式为角色站立时按下J(攻击)键,角色开始攻击,在此期间连续快速敲打J键,可继续触发后续攻击.最终效果如下: (AD移动,K跳跃,J攻击,U冲刺) 之前已经使用了状态机来控制角色的行为,现在再用它来分析角色攻击阶段所发生的事情: 这里把攻击分为三种状态,目的是为了方便控制和在状态间转化,以下是updateIdle中的部分代码,用于站立过渡到攻击状态: u