本篇博客打算从研究Cocos2d-x引擎提供的测试例子来写起,笔者针对Cocos2d-x 3.1.1这个版本来介绍如何来学习它给我们提供的例子,通过这些例子来深入学习Cocos2d-x核心API的使用。在学习过程中,笔者同样跟很多初学者一样有很多疑惑,为了能帮助到更多初学者,笔者会提出自己的疑惑然后进行解决,笔者会把每一个例子都进行详细说明,对相关代码进行注释,那么以后初学者就可以对照笔者的博客来学习Cocos2d-x的使用,我想会事半功倍的。对笔者来说,什么版本并不重要,重要的是学习的思路,接下来的系列博客就是笔者学习Cocos2d-x的思路。
如何开始呢?
自然先到Cocos2d-x官网下载相应版本的引擎,笔者这里是Cocos2d-x 3.1.1
下载完成后,希望童鞋们自己试着去搭建环境,网络和笔者前面的博客均有介绍,笔者在这里就不多说了。
最好要在win32平台、Android平台都运行成功过HelloWorld,有了这个基础之后,就可以找例子学习了。
Cocos2d-x 3.1.1例子的代码在cocos2d-x-3.1.1\tests下:
这里就有我们的C++代码和Lua代码,我们要学习的是Lua项目,怎么运行这些项目呢,看下图:
双击使用Visual Studio打开,笔者这里是2012的。
右键设置lua-tests为启动项目,然后进行编译运行,成功之后的效果如下:
从这些例子,我们可以了解到Cocos2d-x所有相关API所能实现的基础效果,笔者认为没有任何学习资料能比得上这些例子了。
怎么查看实现以上效果的Lua代码呢,下面笔者会给大家介绍。
笔者用到的一个开发工具是LDT,童鞋们可以到这里下载:http://www.eclipse.org/koneki/ldt/
打开LDT,切换工作空间到我们的lua-tests项目中,如下:
然后新建Lua项目,取名为src,这样我们就可以把当前目录下src所有的Lua代码都包含进来了:
这样我们就可以很方便查看每一个例子的Lua代码,查看它的具体实现。
我们的Lua项目的入口在哪里呢?
打开win32项目,找到AppDelegate.cpp,打开查看:
- #include "cocos2d.h"
- #include "AppDelegate.h"
- #include "CCLuaEngine.h"
- #include "audio/include/SimpleAudioEngine.h"
- #include "lua_assetsmanager_test_sample.h"
- using namespace CocosDenshion;
- USING_NS_CC;
- AppDelegate::AppDelegate()
- {
- }
- AppDelegate::~AppDelegate()
- {
- SimpleAudioEngine::end();
- }
- bool AppDelegate::applicationDidFinishLaunching()
- {
- // 获得导演类实例
- auto director = Director::getInstance();
- // 获取渲染所有东西的 EGLView NA NA
- auto glview = director->getOpenGLView();
- if(!glview) {
- glview = GLView::createWithRect("Lua Tests", Rect(0,0,900,640));
- director->setOpenGLView(glview);
- }
- // turn on display FPS
- // 打开显示帧屏
- director->setDisplayStats(true);
- // set FPS. the default value is 1.0/60 if you don't call this
- // 设置游戏画面每秒显示的帧数,默认是60帧。
- director->setAnimationInterval(1.0 / 60);
- // 获得屏幕大小
- auto screenSize = glview->getFrameSize();
- // 获得设计大小
- auto designSize = Size(480, 320);
- if (screenSize.height > 320)
- {
- auto resourceSize = Size(960, 640);
- director->setContentScaleFactor(resourceSize.height/designSize.height);
- }
- // 设置屏幕设计分辨率
- glview->setDesignResolutionSize(designSize.width, designSize.height, ResolutionPolicy::FIXED_HEIGHT);
- // register lua engine
- LuaEngine* pEngine = LuaEngine::getInstance();
- ScriptEngineManager::getInstance()->setScriptEngine(pEngine);
- #if (CC_TARGET_PLATFORM == CC_PLATFORM_WIN32 || CC_TARGET_PLATFORM == CC_PLATFORM_ANDROID ||CC_TARGET_PLATFORM == CC_PLATFORM_IOS || CC_TARGET_PLATFORM == CC_PLATFORM_MAC)
- LuaStack* stack = pEngine->getLuaStack();
- register_assetsmanager_test_sample(stack->getLuaState());
- #endif
- // 执行脚本语言
- pEngine->executeScriptFile("src/controller.lua");
- return true;
- }
- // This function will be called when the app is inactive. When comes a phone call,it's be invoked too
- void AppDelegate::applicationDidEnterBackground()
- {
- Director::getInstance()->stopAnimation();
- SimpleAudioEngine::getInstance()->pauseBackgroundMusic();
- }
- // this function will be called when the app is active again
- void AppDelegate::applicationWillEnterForeground()
- {
- Director::getInstance()->startAnimation();
- SimpleAudioEngine::getInstance()->resumeBackgroundMusic();
- }
我们会发现代码中这么一段:
pEngine->executeScriptFile("src/controller.lua");
这个就是我们的入口文件,我们执行Lua的代码是从controller.lua这个文件开始的。
我们用LDT查看一下它的代码:
- -- avoid memory leak
- -- 避免内存泄漏
- collectgarbage("setpause", 100)
- collectgarbage("setstepmul", 5000)
- require "src/mainMenu"
- ----------------
- -- run
- local glView = cc.Director:getInstance():getOpenGLView()
- local screenSize = glView:getFrameSize()
- local designSize = {width = 480, height = 320}
- local fileUtils = cc.FileUtils:getInstance()
- if screenSize.height > 320 then
- local searchPaths = {}
- table.insert(searchPaths, "hd")
- fileUtils:setSearchPaths(searchPaths)
- end
- local targetPlatform = cc.Application:getInstance():getTargetPlatform()
- local resPrefix = ""
- if cc.PLATFORM_OS_IPAD == targetPlatform or cc.PLATFORM_OS_IPHONE == targetPlatform or cc.PLATFORM_OS_MAC == targetPlatform then
- resPrefix = ""
- else
- resPrefix = "res/"
- end
- local searchPaths = fileUtils:getSearchPaths()
- table.insert(searchPaths, 1, resPrefix)
- table.insert(searchPaths, 1, resPrefix .. "cocosbuilderRes")
- if screenSize.height > 320 then
- table.insert(searchPaths, 1, resPrefix .. "hd")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/hd")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/hd/Images")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/hd/scenetest/ArmatureComponentTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/hd/scenetest/AttributeComponentTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/hd/scenetest/BackgroundComponentTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/hd/scenetest/EffectComponentTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/hd/scenetest/LoadSceneEdtiorFileTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/hd/scenetest/ParticleComponentTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/hd/scenetest/SpriteComponentTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/hd/scenetest/TmxMapComponentTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/hd/scenetest/UIComponentTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/hd/scenetest/TriggerTest")
- else
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/Images")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/scenetest/ArmatureComponentTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/scenetest/AttributeComponentTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/scenetest/BackgroundComponentTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/scenetest/EffectComponentTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/scenetest/LoadSceneEdtiorFileTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/scenetest/ParticleComponentTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/scenetest/SpriteComponentTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/scenetest/TmxMapComponentTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/scenetest/UIComponentTest")
- table.insert(searchPaths, 1, resPrefix .. "ccs-res/scenetest/TriggerTest")
- end
- fileUtils:setSearchPaths(searchPaths)
- -- 创建场景
- local scene = cc.Scene:create()
- -- 添加菜单
- scene:addChild(CreateTestMenu())
- if cc.Director:getInstance():getRunningScene() then
- cc.Director:getInstance():replaceScene(scene)
- else
- -- 根据给定的场景进入 Director的主循环 只能调用他运行你的第一个场景.
- cc.Director:getInstance():runWithScene(scene)
- end
然后我们就可以根据这个,来理清整个测试项目的脉路,我们也许想知道,例子中的那些菜单是怎么显示出来的,例子中又是如何进行切换场景的。只要我们知道如何开始了,以后我们就可以慢慢分析每一个例子所给我提供的代码。
在controller.lua文件中引入了maniMenu.lua
通过这个语句:require "src/mainMenu"
我们来看看mainMenu的代码:
- -- 引入资源文件
- require "Cocos2d"
- require "Cocos2dConstants"
- require "Opengl"
- require "OpenglConstants"
- require "StudioConstants"
- require "GuiConstants"
- require "src/helper"
- require "src/testResource"
- require "src/VisibleRect"
- require "src/AccelerometerTest/AccelerometerTest"
- require "src/ActionManagerTest/ActionManagerTest"
- require "src/ActionsEaseTest/ActionsEaseTest"
- require "src/ActionsProgressTest/ActionsProgressTest"
- require "src/ActionsTest/ActionsTest"
- require "src/AssetsManagerTest/AssetsManagerTest"
- require "src/BugsTest/BugsTest"
- require "src/ClickAndMoveTest/ClickAndMoveTest"
- require "src/CocosDenshionTest/CocosDenshionTest"
- require "src/CocoStudioTest/CocoStudioTest"
- require "src/CurrentLanguageTest/CurrentLanguageTest"
- require "src/DrawPrimitivesTest/DrawPrimitivesTest"
- require "src/EffectsTest/EffectsTest"
- require "src/EffectsAdvancedTest/EffectsAdvancedTest"
- require "src/ExtensionTest/ExtensionTest"
- require "src/FontTest/FontTest"
- require "src/IntervalTest/IntervalTest"
- require "src/KeypadTest/KeypadTest"
- require "src/LabelTest/LabelTest"
- require "src/LabelTestNew/LabelTestNew"
- require "src/LayerTest/LayerTest"
- require "src/MenuTest/MenuTest"
- require "src/MotionStreakTest/MotionStreakTest"
- require "src/NewEventDispatcherTest/NewEventDispatcherTest"
- require "src/NodeTest/NodeTest"
- require "src/OpenGLTest/OpenGLTest"
- require "src/ParallaxTest/ParallaxTest"
- require "src/ParticleTest/ParticleTest"
- require "src/PerformanceTest/PerformanceTest"
- require "src/RenderTextureTest/RenderTextureTest"
- require "src/RotateWorldTest/RotateWorldTest"
- require "src/Sprite3DTest/Sprite3DTest"
- require "src/SpriteTest/SpriteTest"
- require "src/SceneTest/SceneTest"
- require "src/SpineTest/SpineTest"
- require "src/Texture2dTest/Texture2dTest"
- require "src/TileMapTest/TileMapTest"
- require "src/TouchesTest/TouchesTest"
- require "src/TransitionsTest/TransitionsTest"
- require "src/UserDefaultTest/UserDefaultTest"
- require "src/ZwoptexTest/ZwoptexTest"
- require "src/LuaBridgeTest/LuaBridgeTest"
- require "src/XMLHttpRequestTest/XMLHttpRequestTest"
- require "src/PhysicsTest/PhysicsTest"
- -- 行间距
- local LINE_SPACE = 40
- -- 当前位置
- local CurPos = {x = 0, y = 0}
- -- 开始位置
- local BeginPos = {x = 0, y = 0}
- -- 定义一张表
- local _allTests = {
- { isSupported = true, name = "Accelerometer" , create_func= AccelerometerMain },
- { isSupported = true, name = "ActionManagerTest" , create_func = ActionManagerTestMain },
- { isSupported = true, name = "ActionsEaseTest" , create_func = EaseActionsTest },
- { isSupported = true, name = "ActionsProgressTest" , create_func = ProgressActionsTest },
- { isSupported = true, name = "ActionsTest" , create_func = ActionsTest },
- { isSupported = true, name = "AssetsManagerTest" , create_func = AssetsManagerTestMain },
- { isSupported = false, name = "Box2dTest" , create_func= Box2dTestMain },
- { isSupported = false, name = "Box2dTestBed" , create_func= Box2dTestBedMain },
- { isSupported = true, name = "BugsTest" , create_func= BugsTestMain },
- { isSupported = false, name = "ChipmunkAccelTouchTest" , create_func= ChipmunkAccelTouchTestMain },
- { isSupported = true, name = "ClickAndMoveTest" , create_func = ClickAndMoveTest },
- { isSupported = true, name = "CocosDenshionTest" , create_func = CocosDenshionTestMain },
- { isSupported = true, name = "CocoStudioTest" , create_func = CocoStudioTestMain },
- { isSupported = false, name = "CurlTest" , create_func= CurlTestMain },
- { isSupported = true, name = "CurrentLanguageTest" , create_func= CurrentLanguageTestMain },
- { isSupported = true, name = "DrawPrimitivesTest" , create_func= DrawPrimitivesTest },
- { isSupported = true, name = "EffectsTest" , create_func = EffectsTest },
- { isSupported = true, name = "EffectAdvancedTest" , create_func = EffectAdvancedTestMain },
- { isSupported = true, name = "ExtensionsTest" , create_func= ExtensionsTestMain },
- { isSupported = true, name = "FontTest" , create_func = FontTestMain },
- { isSupported = true, name = "IntervalTest" , create_func = IntervalTestMain },
- { isSupported = true, name = "KeypadTest" , create_func= KeypadTestMain },
- { isSupported = true, name = "LabelTest" , create_func = LabelTest },
- { isSupported = true, name = "LabelTestNew" , create_func = LabelTestNew },
- { isSupported = true, name = "LayerTest" , create_func = LayerTestMain },
- { isSupported = true, name = "LuaBridgeTest" , create_func = LuaBridgeMainTest },
- { isSupported = true, name = "MenuTest" , create_func = MenuTestMain },
- { isSupported = true, name = "MotionStreakTest" , create_func = MotionStreakTest },
- { isSupported = false, name = "MutiTouchTest" , create_func= MutiTouchTestMain },
- { isSupported = true, name = "NewEventDispatcherTest" , create_func = NewEventDispatcherTest },
- { isSupported = true, name = "NodeTest" , create_func = CocosNodeTest },
- { isSupported = true, name = "OpenGLTest" , create_func= OpenGLTestMain },
- { isSupported = true, name = "ParallaxTest" , create_func = ParallaxTestMain },
- { isSupported = true, name = "ParticleTest" , create_func = ParticleTest },
- { isSupported = true, name = "PerformanceTest" , create_func= PerformanceTestMain },
- { isSupported = true, name = "PhysicsTest" , create_func = PhysicsTest },
- { isSupported = true, name = "RenderTextureTest" , create_func = RenderTextureTestMain },
- { isSupported = true, name = "RotateWorldTest" , create_func = RotateWorldTest },
- { isSupported = true, name = "SceneTest" , create_func = SceneTestMain },
- { isSupported = true, name = "SpineTest" , create_func = SpineTestMain },
- { isSupported = false, name = "SchdulerTest" , create_func= SchdulerTestMain },
- { isSupported = false, name = "ShaderTest" , create_func= ShaderTestMain },
- { isSupported = true, name = "Sprite3DTest" , create_func = Sprite3DTest },
- { isSupported = true, name = "SpriteTest" , create_func = SpriteTest },
- { isSupported = false, name = "TextInputTest" , create_func= TextInputTestMain },
- { isSupported = true, name = "Texture2DTest" , create_func = Texture2dTestMain },
- { isSupported = false, name = "TextureCacheTest" , create_func= TextureCacheTestMain },
- { isSupported = true, name = "TileMapTest" , create_func = TileMapTestMain },
- { isSupported = true, name = "TouchesTest" , create_func = TouchesTest },
- { isSupported = true, name = "TransitionsTest" , create_func = TransitionsTest },
- { isSupported = true, name = "UserDefaultTest" , create_func= UserDefaultTestMain },
- { isSupported = true, name = "XMLHttpRequestTest" , create_func = XMLHttpRequestTestMain },
- { isSupported = true, name = "ZwoptexTest" , create_func = ZwoptexTestMain }
- }
- local TESTS_COUNT = table.getn(_allTests)
- -- create scene 创建场景
- local function CreateTestScene(nIdx)
- cc.Director:getInstance():purgeCachedData()
- local scene = _allTests[nIdx].create_func()
- return scene
- end
- -- create menu 创建菜单
- function CreateTestMenu()
- -- 菜单层
- local menuLayer = cc.Layer:create()
- local function closeCallback()
- -- 结束执行,释放正在运行的场景。
- cc.Director:getInstance():endToLua()
- end
- -- 菜单回调
- local function menuCallback(tag)
- print(tag)
- local Idx = tag - 10000
- local testScene = CreateTestScene(Idx)
- if testScene then
- -- 切换场景
- cc.Director:getInstance():replaceScene(testScene)
- end
- end
- -- add close menu 添加关闭菜单
- local s = cc.Director:getInstance():getWinSize()
- local CloseItem = cc.MenuItemImage:create(s_pPathClose, s_pPathClose)
- CloseItem:registerScriptTapHandler(closeCallback)
- CloseItem:setPosition(cc.p(s.width - 30, s.height - 30))
- local CloseMenu = cc.Menu:create()
- CloseMenu:setPosition(0, 0)
- CloseMenu:addChild(CloseItem)
- menuLayer:addChild(CloseMenu)
- -- 获取目标平台
- local targetPlatform = cc.Application:getInstance():getTargetPlatform()
- if (cc.PLATFORM_OS_IPHONE == targetPlatform) or (cc.PLATFORM_OS_IPAD == targetPlatform) then
- CloseMenu:setVisible(false)
- end
- -- add menu items for tests
- -- 添加菜单项
- local MainMenu = cc.Menu:create()
- local index = 0
- local obj = nil
- for index, obj in pairs(_allTests) do
- -- 创建文本(obj.name 为文本名称, s_arialPath为字体,24为字体大小)
- local testLabel = cc.Label:createWithTTF(obj.name, s_arialPath, 24)
- -- 设置锚点
- testLabel:setAnchorPoint(cc.p(0.5, 0.5))
- -- 创建菜单项标签
- local testMenuItem = cc.MenuItemLabel:create(testLabel)
- -- 如果此项不支持,则设置菜单项不可用
- if not obj.isSupported then
- testMenuItem:setEnabled(false)
- end
- -- 注册脚本处理句柄
- testMenuItem:registerScriptTapHandler(menuCallback)
- -- 设置菜单标签显示的位置,设置到居中的位置
- testMenuItem:setPosition(cc.p(s.width / 2, (s.height - (index) * LINE_SPACE)))
- -- 添加菜单项到菜单中去
- MainMenu:addChild(testMenuItem, index + 10000, index + 10000)
- end
- -- 设置菜单内容大小
- MainMenu:setContentSize(cc.size(s.width, (TESTS_COUNT + 1) * (LINE_SPACE)))
- MainMenu:setPosition(CurPos.x, CurPos.y)
- -- 将菜单添加到层中去
- menuLayer:addChild(MainMenu)
- -- handling touch events
- -- 处理触摸事件
- local function onTouchBegan(touch, event)
- -- 获取触摸点的位置
- BeginPos = touch:getLocation()
- -- CCTOUCHBEGAN event must return true
- return true
- end
- -- 手指移动时触发
- local function onTouchMoved(touch, event)
- local location = touch:getLocation()
- local nMoveY = location.y - BeginPos.y
- local curPosx, curPosy = MainMenu:getPosition()
- local nextPosy = curPosy + nMoveY
- local winSize = cc.Director:getInstance():getWinSize()
- if nextPosy < 0 then
- MainMenu:setPosition(0, 0)
- return
- end
- if nextPosy > ((TESTS_COUNT + 1) * LINE_SPACE - winSize.height) then
- MainMenu:setPosition(0, ((TESTS_COUNT + 1) * LINE_SPACE - winSize.height))
- return
- end
- --
- MainMenu:setPosition(curPosx, nextPosy)
- BeginPos = {x = location.x, y = location.y}
- CurPos = {x = curPosx, y = nextPosy}
- end
- -- 创建事件监听器
- local listener = cc.EventListenerTouchOneByOne:create()
- -- 注册事件监听
- listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN )
- listener:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED )
- -- 获取事件派发器
- local eventDispatcher = menuLayer:getEventDispatcher()
- eventDispatcher:addEventListenerWithSceneGraphPriority(listener, menuLayer)
- return menuLayer
- end
我们就可以发现,这里就是界面中菜单的实现,mainMenu中还引入了其他文件,比如testResource.lua
- s_pPathGrossini = "Images/grossini.png"
- s_pPathSister1 = "Images/grossinis_sister1.png"
- s_pPathSister2 = "Images/grossinis_sister2.png"
- s_pPathB1 = "Images/b1.png"
- s_pPathB2 = "Images/b2.png"
- s_pPathR1 = "Images/r1.png"
- s_pPathR2 = "Images/r2.png"
- s_pPathF1 = "Images/f1.png"
- s_pPathF2 = "Images/f2.png"
- s_pPathBlock = "Images/blocks.png"
- s_back = "Images/background.png"
- s_back1 = "Images/background1.png"
- s_back2 = "Images/background2.png"
- s_back3 = "Images/background3.png"
- s_stars1 = "Images/stars.png"
- s_stars2 = "Images/stars2.png"
- s_fire = "Images/fire.png"
- s_snow = "Images/snow.png"
- s_streak = "Images/streak.png"
- s_PlayNormal = "Images/btn-play-normal.png"
- s_PlaySelect = "Images/btn-play-selected.png"
- s_AboutNormal = "Images/btn-about-normal.png"
- s_AboutSelect = "Images/btn-about-selected.png"
- s_HighNormal = "Images/btn-highscores-normal.png"
- s_HighSelect = "Images/btn-highscores-selected.png"
- s_Ball = "Images/ball.png"
- s_Paddle = "Images/paddle.png"
- s_pPathClose = "Images/close.png"
- s_MenuItem = "Images/menuitemsprite.png"
- s_SendScore = "Images/SendScoreButton.png"
- s_PressSendScore = "Images/SendScoreButtonPressed.png"
- s_Power = "Images/powered.png"
- s_AtlasTest = "Images/atlastest.png"
- -- tilemaps resource
- s_TilesPng = "TileMaps/tiles.png"
- s_LevelMapTga = "TileMaps/levelmap.tga"
- -- spine test resource
- s_pPathSpineBoyJson = "spine/spineboy.json"
- s_pPathSpineBoyAtlas = "spine/spineboy.atlas"
- -- fonts resource
- s_markerFeltFontPath = "fonts/Marker Felt.ttf"
- s_arialPath = "fonts/arial.ttf"
- s_thonburiPath = "fonts/Thonburi.ttf"
- s_tahomaPath = "fonts/tahoma.ttf"
这个文件定义了所有的资源路径,一些图片、json资源、字体资源等。
其他相关的文件,笔者在这里就不贴代码,这个大家私下去查看,我在这里只是提供相关的思路,让大家理清如何使用Cocos2d-x给我们提供的例子进行学习。
下一篇博客,笔者将会介绍第一个例子-重力加速器,非常感谢你的关注。