Quick-3.3 开发笔记

由于Cocos2d-x中使用的是C++,而C++对开发人员要求较高,逐渐的开发者开始将Cocos2d-x的C++接口转换成了Lua接口,从而衍生出Cocos2d-lua的版本。而Quick是Cocos2d-lua的一个增强和扩展版本,它重写了支持代码、解决了内存泄漏和只能使用全局函数做回调等问题。Quick能让开发者使用Lua简单易懂的脚本来编写游戏,并大大提高了开发效率。

环境搭建

版本

  • Quick-3.3
  • SublimeText3

Quick框架

quick-cocos2d-x v3 是在 cocos2dx 3.x 的最新版本基础之上,移植了原来 quick-cocos2d-x 的核心框架、强大的 player 、丰富的示例等,并增加更多新的功能。

$ git clone https://github.com/dualface/v3quick.git

Quick-3.3 源码目录

4933701-55746847f3b4a480.png
系统目录
  • build cocos2dx项目存放目录
  • cocos cocos2dx主目录核心代码存放位置
  • docsquick文档目录
  • extension cocos扩展内容、GUI扩展库
  • external 扩展内容,物理引擎第三方库、Box2D和chipmunk、数据库第三方库、sqlite3、网络第三方库、webp、websockets等
  • licenses 认证,引擎使用的各种许可证文件
  • quick quick核心目录,quick引擎代码
  • tools quick用作luabinding的工具
  • README.html 使用指南
  • setup_win.bat 搭建Windows开发环境的脚本
  • VERSION 版本标识

Quick框架核心目录

4933701-0bde06124eb6850c.png
quick目录
  • bin quick工具脚本,包括binding脚本、加密脚本等
  • cocos C++定义的常量与封装的接口
  • framework quick框架核心目录
  • lib quick类库
  • player player的工程文件
  • samples quick示例代码
  • templates quick项目模板
  • welcome player启动界面代码

开发工具

QuickXDev是SublimeText开发quick-cocos2d-x的插件,SublimeText配置QuickXDev插件步骤:

  1. 下载之后解压,并重命名为QuickXDev。
  2. 把该文件夹放入到SublimeText的Packages目录下Preferences->Browse Packages
  3. SublimeText设置 Preferences->Package Settings->QuickXDev->Settings – User
{
    "quick_cocos2dx_root": "D:\\quick-cocos2d-x",
    "date_format": "%Y-%m-%d %H:%M:%S",
    "author": "JunChow",
    "compile_scripts_key": ""
}

重点是配置Quick的根目录"quick_cocos2dx_root": "D:\\quick-cocos2d-x",

模拟器

4933701-b84fb4efa6e33cf1.png
Player

quick-cocos2d-x 中带有一个名为 Player 的工具,这个工具不但是一个功能完善的模拟器,可以在 Mac/Windows 桌面运行开发者的游戏,还是一个功能齐备的开发工具入口。开发者启动 Player 后,将可以完成下列任务:创建项目、打开项目、编译项目、查看示例

  1. player 依赖一些特定的环境设置才能正常工作,Windows 平台下运行 setup_win.bat。
  2. 启动 player 后将看到以下画面
  3. 创建项目,有两种方式:命令行创建、通过 Player 创建

创建项目

# 创建一个test的项目
$ create_project.bat -p com.junchow.games.test
4933701-0afc98af376bcd65.png
创建项目

项目目录结构

4933701-7a2a65835ed32275.png
项目目录
  • debug.log 调试日志,即打印控制台窗口输出的日志。
  • config.json 项目配置文件
  • src 项目源码存放目录
  • runtime 预编译的运行时库存放目录
  • res 项目资源的存放目录
  • frameworks cocos2d-x引擎核心代码及各平台运行时资源

项目源码目录结构

4933701-ebe5ec292af84da1.png
src项目源码目录
  • app 项目工程界面等文件,存放游戏代码
  • cocos cocos引擎代码目录
  • framework quick引擎核心
  • config.lua 项目工程配置文件
  • main.lua 项目工程入口文件

项目配置文件 src/config.lua

-- 配置quick工程调试信息:0关闭,1打印少量调试信息,2打印标准调试信息
-- 0 - disable debug info, 1 - less debug info, 2 - verbose debug info
DEBUG = 1
-- 是否显示模拟器左下角的FPS信息
-- display FPS stats on screen
DEBUG_FPS = true
-- 是否每10秒打印一次内存信息
-- dump memory info every 10 seconds
DEBUG_MEM = false
-- 是否加载已废弃的API
-- load deprecated API
LOAD_DEPRECATED_API = false
-- 是否加载段代码的API
-- load shortcodes API
LOAD_SHORTCODES_API = true
-- 游戏屏幕方向:landscape横屏,portrait竖屏
-- screen orientation
CONFIG_SCREEN_ORIENTATION = "portrait"
-- 游戏屏幕宽度:横屏是时表示高度
-- design resolution
CONFIG_SCREEN_WIDTH  = 640
-- 游戏屏幕高度:横屏时表示宽度
CONFIG_SCREEN_HEIGHT = 960
-- 屏幕适配策略:
-- FIXED_WIDTH:保持传入的设计分辨率宽度不变,根据屏幕分辨率修正设计分辨率的高度。
-- FIXED_HEIGHT:保持传入的设计分辨率高度不变,根据屏幕分辨率修正设计分辨率的宽度。
-- FILL_ALL:保证设计区域某个方向铺满屏幕,另一方向可能超出屏幕或留有黑边。
-- auto scale mode
CONFIG_SCREEN_AUTOSCALE = "FIXED_WIDTH"

分辨率适配问题

市场上各种屏幕尺寸和分辨率的移动设备层出不穷,为了让开发的项目能够更好地适应不同的设备,分辨率适配尤为重要。

4933701-b891334ead13d673.png
常见手机分辨率

Cocos中图片显示到屏幕有两个逻辑过程,结合在一起影响最终的显示效果。首先是将资源布局到设计分辨率,然后是将设计分辨率布局到屏幕。

4933701-767298608bb14121.jpg
分辨率适配.jpg

设计分辨率指config.lua文件中设置的CONFIG_SCREEN_WIDTHCONFIG_SCREEN_HEIGHT,相当于参考分辨率。确定了参考分辨率才能得到图片资源的缩放比率。

-- 图片资源显示到屏幕的缩放因子,由“背景图片资源宽高/设计分辨率宽高”得到。
cc.Director:getInstance():setContentScaleFactor(value)
  • 缩放因子 = 图片资源高/设计分辨率高
    保证了背景资源垂直方向在设计分辨率范围内的全部显示,但水平方向上可能会溢出或留有黑边。
4933701-2e6a13cf28d4a1fd.png
缩放因子=图片资源高/设计分辨率高
  • 缩放因子 = 图片资源宽/设计分辨率宽
    保证了背景资源的水平方向在设计分辨率范围内的全部显示,但垂直方向上可能会超出屏蔽范围或留有黑边。
4933701-e911569925388ce4.png
缩放因子=图片资源宽/设计分辨率宽
-- 设置设计分辨率宽高
setDesignResolutionSize(width, height, cc.ResolutionPolicy)
-- width 设计分辨率宽度
-- height 设计分辨率高度
-- cc.ResolutionPolicy 分辨率适配策略,由config.lua中CONFIG_SCREEN_WIDTH、CONFIG_SCREEN_HEIGHT、CONFIG_SCREEN_AUTOSCALE来设置。

分辨率适配的实现

横屏的飞行游戏,需要让背景图在高度上全部显示,那么宽度上必须会做出一些牺牲,即要么被裁剪要么留黑边,当然黑边可以通过将图片宽度做的更宽来解决。

  1. 选择1136x640的图片资源,宽高比够大,能确保在某些极端的分辨率也能完整不留黑边显示。
  2. 设置src/config.lua屏幕相关参数
-- 游戏屏幕方向:landscape横屏,portrait竖屏
-- screen orientation
CONFIG_SCREEN_ORIENTATION = "landscape"
-- 游戏屏幕宽度:横屏是时表示高度
-- design resolution
CONFIG_SCREEN_WIDTH  = 480
-- 游戏屏幕高度:横屏时表示宽度
CONFIG_SCREEN_HEIGHT = 320
-- 屏幕适配策略
-- auto scale mode
CONFIG_SCREEN_AUTOSCALE = "FIXED_HEIGHT"
  1. src/app/MyApp.lua修改run()加入内容缩放因子
    4933701-921957f3eab0f047.png
    添加内容缩放因子
-- MyApp.lua
require("config")
require("cocos.init")
require("framework.init")

local MyApp = class("MyApp", cc.mvc.AppBase)

function MyApp:ctor()
    MyApp.super.ctor(self)
end

function MyApp:run()
    cc.FileUtils:getInstance():addSearchPath("res/")

    -- 添加内容缩放因子
    cc.Director:getInstance():setContentScaleFactor(640/CONFIG_SCREEN_HEIGHT)

    self:enterScene("MainScene")
end

return MyApp

项目主入口 src/main.lua

main.lua是Quick的默认入口,即项目启动时,首先执行这个文件。

function __G__TRACKBACK__(errorMessage)
    print("----------------------------------------")
    print("LUA ERROR: " .. tostring(errorMessage) .. "\n")
    print(debug.traceback("", 2))
    print("----------------------------------------")
end
-- 将自定义包路径添加到package的所搜路径中
package.path = package.path .. ";src/"
-- 设置图片加载失败时是否弹出消息框
cc.FileUtils:getInstance():setPopupNotify(false)
-- 载入app.MyApp模块新建MyApp实例并运行
require("app.MyApp").new():run()

默认我的应用 src/app/MyApp.lua

-- 载入配置
require("config")
-- cocos框架初始化
require("cocos.init")
-- quick框架初始化
require("framework.init")

-- 定义类 MyApp
-- class()方法本身是quick框架中用于创建自定义lua类的函数,该函数在quick引擎的`quick/framework/functions.lua`中。
-- function class(classname, super)
-- classname 表示类名, super表示父类或创建对象实例的函数。
-- MyApp类是从cc.mvc.AppBase继承而来
-- AppBase是Quick中自带的一个MVC应用程序基础类,此类为应用程序提供了逻辑控制上的功能,如进入场景、切换场景等。
local MyApp = class("MyApp", cc.mvc.AppBase)

-- MyApp:ctor()
-- 1. 相当于C++中的构造函数(constructor)以及初始化函数(init)
-- 2. 在ctor()中初始化游戏数据
-- 3. 每次调用XXClass.new()创建对象实例时会自动执行ctor()
-- 4. 子类的ctor()中必须手动调用父类的构造函数,才能保证子类能继承父类的属性和方法。
function MyApp:ctor()
    MyApp.super.ctor(self)
end

function MyApp:run()
    -- 通过 addSearchPath()设置“资源搜索路径”
    cc.FileUtils:getInstance():addSearchPath("res/")
    -- 通过setContentScaleFactor()设置“内容缩放因子”
    cc.Director:getInstance():setContentScaleFactor(640/CONFIG_SCREEN_HEIGHT)
    -- MyApp继承自AppBase,调用enterScene()进入名为MainScene的游戏场景中
    self:enterScene("MainScene")
end

return MyApp
  1. ressrc目录添加到文件所搜路径
cc.FileUtils:getInstance():addSearchPath("res/")
  1. 读取config.lua加载Lua配置,并设置内容缩放因子,解决分辨率适配问题。
cc.Director:getInstance():setContentScaleFactor(640/CONFIG_SCREEN_HEIGHT)
  1. 创建App对象,调用run(),运行并配置第一个进入的场景,默认为MainScence
self:enterScene("MainScene")

默认主场景 src/app/scenes/MainScene.lua

-- 使用 class() 函数创建了一个 MainScene 场景类
-- 与创建 MyApp 类不同的是,MainScene 类不是从基础类继承而来的,而是通过回调函数创建出来的。
-- 因为 Scene 场景对象必须是 C++ 对象,而 C++对象是无法直接派生出 Lua 类的,所以只有用函数将其创建出来后再为其添加方法。
local MainScene = class("MainScene", function()
    -- display.newScene() :创建新场景并返回 Scene 场景对象
    -- quick中display模块封装了绝大部分与显示相关的功能,并负责根据 config.lua 中定义的分辨率设定计算屏幕的设计分辨率。
    -- display 模块提供了众多方法和属性,如创建层 display.newLayer,创建精灵 display.newSprite,恢复暂停切换场景等。
    return display.newScene("MainScene")
end)

-- MainScene 构造并初始化
function MainScene:ctor()
    -- 添加 UI 标签,其作用是在屏幕正中间添加一个文本,并显示到屏幕上。
    cc.ui.UILabel.new({UILabelType = 2, text = "Hello, World", size = 64})
        :align(display.CENTER, display.cx, display.cy)
        :addTo(self)
end

-- 进入场景时调用,用来做初始化工作。
function MainScene:onEnter()
end

-- 退出场景时调用,用来释放资源重置变量等。
function MainScene:onExit()
end

return MainScene

display 对象

display常用属性

  • display.widthInPixels 屏幕分辨率的宽度
  • display.heightInPixels 屏幕分辨率的宽度
  • display.width 设计分辨率的宽度
  • display.height 设计分辨率的高度
  • display.cx 设计分辨率中央的x坐标
  • display.cy 设计分辨率中央的y坐标
  • display.left 设计分辨率左坐标
  • display.top 设计分辨率上坐标
  • display.right 设计分辨率右坐标
  • display.bottom 设计分辨率下坐标
  • display.right 设计分辨率右坐标
  • display.c_left 当父对象在屏幕中央时屏幕左坐标
  • display.c_top 当父对象在屏幕中央时屏幕上坐标
  • display.c_right 当父对象在屏幕中央时屏幕右坐标
  • display.c_bottom 当父对象在屏幕中央时屏幕下坐标
  • display.contentScaleFactor 设计分辨率到屏幕分辨率的缩放因子,不同于内容缩放因子。

cc.ui模块中封装了大量复合脚本风格的cocos2d-x空间,包含UILabel、UIImage、UISlider等。

-- 实例化一个新的UILabel控件
cc.ui.UILabel.new()

-- UILabelType 创建文本对象所使用的方式
-- 1 表示使用位图字体创建文本显示对象,返回对象是LabelBMFont。
-- 2 表示使用TTF字体创建文本显示对象,返回对象是Label。
-- text 要显示的文本
-- size 文字尺寸

-- 创建好 UILabel后通过调用align()方法设置文本的锚点和显示位置,最后用addTo()方法把文本添加到场景中。
cc.ui.UILabel.new({UILabelType = 2, text = "Hello, World", size = 64})
    :align(display.CENTER, display.cx, display.cy)
    :addTo(self)

菜单场景

quick是一款基于节点树渲染的游戏引擎,它把游戏的各个部分抽象成导演(director)、节点(node)、场景(scene)、层(layer)、精灵(sprit)等一系列的概念,可以把cocos2d-x游戏中每个时刻都有一个场景在独立运行,通过切换不同的场景可完成整个游戏流程,场景切换的管理由导演来执行。

一个游戏可以有多个不同的游戏场景,每个场景又可包含多个不同的层或节点,每层可拥有任意的游戏节点。

4933701-7b9fe0bf792fa1ac.png
quick是基于节点树渲染的游戏引擎

添加背景图片

图片资源

4933701-a0a70b4b6750abb1.png
背景图片
4933701-ca93c60639b8f1c7.png
添加背景图片

操作步骤

  1. 创建 1136x640 的背景图片精灵 bg.png
  2. 将 bg.png 放到 /res/images/bg.png
  3. 编辑主场景 src/app/scenes/MainScene.luactor() 方法
-- 添加 UI 图片精灵
display.newSprite("images/bg.png")
:pos(display.cx, display.cy)
:addTo(self)

代码分析

-- 创建精灵对象
display.newSprite()

-- 将精灵对象添加到主场景 MainScene 中相应的位置中
display.newSprite("images/bg.png")
:pos(display.cx, display.cy)
:addTo(self)

验证结果

4933701-77d8e44f57f07cf9.png
验证分辨率适配结果

添加标题图片并上下运动

图片资源

4933701-7ead34ca507d9a9b.png
标题图片

效果预览

4933701-ff6b2582c7b07537.png
添加标题图片并上下运动

操作步骤

  1. 创建标题图片 title.png 并存入 res/images/title.png
  2. 在主场景构造器中添加代码
4933701-fbaa3712f8d6bf3f.png
代码
-- 添加图片精灵并设置位置,然后执行一系列动作。
local title = display.newSprite("images/title.png")
:pos(display.cx / 2 * 3, display.cy)
:addTo(self)
local move1 = cc.MoveBy:create(0.5, cc.p(0, 10))
local move2 = cc.MoveBy:create(0.5, cc.p(0, -10))
local SequenceAction = cc.Sequence:create(move1, move2)
-- 执行动作效果
transition.execute(title, cc.RepeatForever:create(SequenceAction))

代码解析

-- 添加精灵图片到场景上位置
pos(display.cs/2*3, display.cy)

-- 执行动作效果
transition.execute(target, action, args)
-- target 显示 cc.Node 对象
-- action 动作对象
-- args table参数表格对象

transition.execute(title, cc.RepeatForever:create(SequenceAction))
-- action 参数是自定义构建的复合动作
-- cc.MoveBy() 
local move1 = cc.MoveBy:create(0.5, cc.p(0, 10))
local move2 = cc.MoveBy:create(0.5, cc.p(0, -10))
该动作将使节点从当地前坐标点匀速直线运动到相对偏移一定向量的位置上
create()函数的两个参数分别表示运动到指定位置所需的时间和移动的距离(偏移量)
move1表示在0.5秒内向Y轴的正轴上移动10个像素
move2表示在0.5秒内向Y轴的负方向上移动10个像素

local SequenceAction = cc.Sequence:create(move1, move2)
cc.Sequence动作允许将一系列动作组合起来,并按顺序执行它们。
解析:
1. 创建一个顺序执行move1、move2的动作
2. SequenceAction动作会首先执行move1
3. 等move1完成后,再马上执行move2
4. 循环执行该动作的节点最终会回到原来的位置上

cc.RepeatForever:create(SequenceAction)
cc.RepeatForever动作是一个无限重复执行的动作
cc.RepeatForever:create(SequenceAction)表示创建一个无限地执行SequenceAction的动作。

添加按钮

图片资源

4933701-fc5539e98d406937.png
按钮图片

预览效果

4933701-2cfb2dd7acb71414.png
添加按钮

源码分析

4933701-255b522080b483e6.png
添加按钮

代码解析

-- 添加按钮
cc.ui.UIPushButton.new({normal = "images/btn1.png", pressed = "images/btn2.png"})
:onButtonClicked(function() print("start") end)
:pos(display.cx / 2, display.cy * 1.5)
:addTo(self)

在quick中有3中不同的Button按钮空间,分别是:

  • UIPushButton 按钮控件
    继承自 UIButton,可通过 cc.ui.UIPushButton.new(image, options)方法来创建 UIPushButton
    参数 images 是 table 类型,代表各个按钮状态:正常、按下、禁用下的图片。
    参数 options 为可选参数化,也是 table 类型,包含了是否 scale9 缩放,偏移flipX、flipY值等设置。

  • UICheckBoxButton CheckButton控件

  • UICheckBoxButtonGroup CheckButton组控件

onButtonClicked()用于监听按钮的点击事件,当点击按钮时,将调用该方法中的代码。

-- 点击按钮时,会在控制台窗口打印 "start" 的字段
onButtonClicked(function() print("start") end)

onButtonClicked() 方法类似的还有

  • onButtonPressed(callback) 用于监听按钮的按下事件
  • onButtonRelease(callback) 用于监听按钮的释放事件
  • onButtonStateChanged(callback) 用于监听按钮的状态改变事件
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值