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