Quick-cocos2d-x-3.2中示例Coinfilp解析(一)

前提:我使用是的quick-cocos2d-x-3.2rc0和Cocos Code IDE进行学习的
首先,用 play3 新建一个工程(名字大家就任意起吧)

工程建立完成后,大家进去自己quick-cocos2d-x-3.2rc0所在目录,然后进入…\quick\samples\coinflip 中,将当中的两个文件夹 res 和 src 复制下来。
(其中,res存放游戏资源,src存放lua代码)


然后进入刚才我们新建的工程中,将当中的 res 和src 替换为刚才复制的 res 和 src
接着使用 play3 运行我们新建的工程,是不是与示例中的coinflip一样了?

打开 Cocos Code IDE ,将该工程导入,就可以进行代码的查看和修改了!

一、基础的main.lua、config.lua 和MyApp.lua
先打开src下的 main.lua

function __G__TRACKBACK__(errorMessage)
    print("----------------------------------------")
    print("LUA ERROR: " .. tostring(errorMessage) .. "\n")
    print(debug.traceback("", 2))
    print("----------------------------------------")
end

-- 启动后执行MyApp脚本, 并执行当中的 run() 方法
require("app.MyApp").new():run()


```

每个新建的工程的main.lua都一样,不需要改动,我们只要知道它是程序lua脚本的启动文件就够了。接着我们沿着最后一句代码 require("app.MyApp").new():run() ,打开MyApp.lua, 观察当中的 run() 方法

function MyApp:run()
    -- 设置资源搜索路径
    cc.FileUtils:getInstance():addSearchPath("res/")
    
    --创建图片缓存
    --在config中
    --GAME_TEXTURE_DATA_FILENAME  = "AllSprites.plist"
    --GAME_TEXTURE_IMAGE_FILENAME = "AllSprites.png"
    display.addSpriteFrames(GAME_TEXTURE_DATA_FILENAME, GAME_TEXTURE_IMAGE_FILENAME)

    -- 预加载音频文件
    for k, v in pairs(GAME_SFX) do
        audio.preloadSound(v)
    end

    -- 进入场景
    self:enterMenuScene()
end


```

在 run() 方法当中主要做了三件事:1、 设置资源搜索路径
                                                               2、 加载游戏资源
                                                               3、 进入主场景
也许你会说在这个脚本文件里找不到  GAME_TEXTURE_DATA_FILENAME 和  GAME_TEXTURE_IMAGE_FILENAME 相关代码,你应该打开config.lua ,所有的 配置信息 和 宏定义 都在里面(个人觉得统一写在config.lua中更方便查找,比C++更容易读懂)

同时MyApp.lua中还封装了所有场景的切换方法,更加方便了管理和后续的编写

function MyApp:enterMenuScene()
    self:enterScene("MenuScene", nil, "fade", 0.6, display.COLOR_WHITE)
end

function MyApp:enterMoreGamesScene()
    self:enterScene("MoreGamesScene", nil, "fade", 0.6, display.COLOR_WHITE)
end

function MyApp:enterChooseLevelScene()
    self:enterScene("ChooseLevelScene", nil, "fade", 0.6, display.COLOR_WHITE)
end

function MyApp:playLevel(levelIndex)
    self:enterScene("PlayLevelScene", {levelIndex}, "fade", 0.6, display.COLOR_WHITE)
end


```



二、第一个场景MenuScene
了解了基础的几个脚本后,我们跟着 self:enterMenuScene() 这个句代码,进入第一个场景MenuScene,场景界面如下
  
打开src\app\scenes\MenuScene.lua   (这有点废话了,大家肯定都知道的了。。。)
local AdBar = import("..views.AdBar")
local BubbleButton = import("..views.BubbleButton")


```

开头两句其实作用是跟C++里的导入是一样的,因此,很明显该场景中将会用到这个两个自定义的类

往下看
local MenuScene = class("MenuScene", function()
    return display.newScene("MenuScene")
end)


```

class方法有两个参数,第一个参数是类名。第二参数可以通过两种形式传递参数,一种是传入一个函数,另一种方式是传入一个Quick的类或者是Lua对象。
当传入函数时,新创建的类会以传入的函数作为 构造函数。当传入的是一个对象时,会以传入的对象为父类派生下来。

function MenuScene:ctor()
    
    -- 1、背景的添加
    self.bg = display.newSprite("#MenuSceneBg.png", display.cx, display.cy)
    self:addChild(self.bg)

    -- 2、信息条的添加
    self.adBar = AdBar.new()
    self:addChild(self.adBar)

    -- 3、“更过游戏”按钮
    self.moreGamesButton = BubbleButton.new({
            image = "#MenuSceneMoreGamesButton.png",
            sound = GAME_SFX.tapButton,
            prepare = function()
                audio.playSound(GAME_SFX.tapButton)
                self.moreGamesButton:setButtonEnabled(false)
            end,
            listener = function()
                app:enterMoreGamesScene()
            end,
        })
        :align(display.CENTER, display.left + 150, display.bottom + 300)
        :addTo(self)
    
    -- 4、“开始”按钮
    self.startButton = BubbleButton.new({
            image = "#MenuSceneStartButton.png",
            sound = GAME_SFX.tapButton,
            prepare = function()
                audio.playSound(GAME_SFX.tapButton)  -- 播放特效声
            self.startButton:setButtonEnabled(false)  -- 关闭按钮功能
            end,
            listener = function()
                app:enterChooseLevelScene()  -- 该方法在MyApp.lua中
            end,
        })
        :align(display.CENTER, display.right - 150, display.bottom + 300) -- 设置锚点,X坐标,Y坐标
        :addTo(self) -- 添加到该场景中

end


```

ctor() 相当于构造函数 或者说 是Cococs2d-x里的init(),一旦new,就会调用ctor() ,
在该ctor()中初始化的该场景的界面布置:1、 背景的添加
                                                                         2、信息条的添加
                                                                         3、“更过游戏”按钮
                                                                         4、“开始”按钮

1、背景的添加:其实十分简单,创建一精灵,将其位置设置在场景的中心点(锚点已经默认为精灵的中心点了),然后将其添加进场景就OK了。
     需要注意一点的就是在Quick中使用图片,如果使用的图片是以#开头的话表示是从SpriteFrameCache中读取,如果没有使用#开头的话表示是直接从文件读取。(还记得在MyApp.lua中我们已经加载了图片缓存了吗?)

    附:display.width和display.height表示屏幕宽度
           display.cx和display.cy表示屏幕的x轴中间位置和y轴中间位置
           display.left和display.right表示屏幕的最左边和最右边(x轴坐标为0和display.width的点)
           display.top和display.bottom表示屏幕的顶部和底部(y轴坐标为0和display.height的点)
           display.CENTER、display.LEFT_TOP、display.CENTER_TOP等分别表示node的锚点位置。

2、信息条的添加:
打开src\app\views\AdBar.lua  观察下面代码
-- 信息条(界面最下方那条)
-- 一个进行了二次封装的精灵
-- align:锚点,X坐标,Y坐标
local AdBar = {}

function AdBar.new()
    local sprite = display.newSprite("#AdBar.png")
    sprite:align(display.BOTTOM_CENTER, display.cx, display.bottom)
    return sprite
end

return AdBar


```

在AdBar中,一旦调用了new() 方法,将自动创建并返回一个设置好 精灵帧、锚点、X坐标 和 Y坐标 的精灵
(二次封装的目的除了外部的方便调用外,最大的动能就是 代码的复用!所以可以预测到后面的编写中必定将会继续用到这个信息条)

3、4、两个按钮的添加,都是使用自定义的 汽包按钮类 BubbleButton (我直译,错了请见谅,六级还没过T.T) ,将这个自定义按钮这个篇是讲不完了,但大家先观察好代码,记住创建气泡按钮传入的参数是个表table ,表里的元素有四个:
{ imgae = XXX, sound = XXX, prepare = XXX, listener = XXX }

下一篇将会继续讲解 气泡按钮 BubbleButton

前排。
这是一个系列的对不,楼主打算整几期~?连载多了 ,可以帮推广哦

我希望在10篇左右吧,最近在学Quick,本人大菜鸟,想以超级菜鸟角度试试看看

支持技术学习帖:2:

:2:支持技术学习帖

谢谢,看多了帖子忍不住想试试自己写

谢谢 :2:

楼主写得很好啊,一目了然,很好理解,支持一个

理解的不错。

支持支持:2::2:

楼主讲的甚好,学习完了 想自己试试 发现 代码不能提示 我把quick的framework导入到工程了 好像还是不行啊

没有提示是硬伤,但我觉得以后会有的,你看看这个http://cn.cocos2d-x.org/tutorial/show?id=1257,虽说提示版本不同,但还有有点帮助

楼主你好,在源码中有一句MyApp.lua中有一句app:enterChooseLevelScene()。。请问这个app变量到底是什么??找遍所有文件也没看到定义了这个变量。。求解

奇怪的问题,我在试验其 BubbleButton的代码,我把 moreGamesButton 和 startButton 只要只初始化放一个,点击就会出错。。

必须两个都初始化,点按钮才会正常。

我是用Player.exe 尝试的。。

用Player.exe调试太痛苦了。。系统出错 毫无出错信息。。太累了

不知道楼主 是否遇到过,是否解释下

楼上的问题

MyApp.lua中有
appInstance = MyApp
个人以为 你说的 那个 app:xxxx 就是 靠这个定义了一个全局变量。。

但是为啥 appInstance 就会自动认为 app 不是特别理解。。得查下Lua的语法

我试了没事哦,代码复制来看看里,还有用player运行时,要把窗口大小调整到整个都显示了才行,不然点击点可能会漂移