开始学习quick-cocos2d-x这个工具了,边学边记录吧。
欢迎各界交流
http://quick.cocoachina.com/?p=39
http://quick.cocoachina.com/?p=1
这篇文档讲的甚是明白
http://quick.cocoachina.com/?p=1527
断点调试编码必备
需要什么信息,可以直接在官网上进行搜索,必定会得到你想要的结果。
引用自官方文档:quick 和 cocos2d-x 的主要区别有如下几点:
1. 更完善的 Lua 支持,包括一个 Lua 框架对 C++ 接口进行了二次封装
2. 补充了大量cocos2d-x 没有提供,但游戏需要的功能
3. 为提高开发效率,提供了Objective-C 和 Java 的桥接模块,以及强化的 Windows/Mac 模拟器
引用官方:quick-cocos2d-x 里附带了一个功能强大的模拟器,称为 quick-x-player(后文简称 player)。
player 可以在 Mac 和 Windows 环境中模拟游戏引擎的绝大部分功能。在开发过程中,利用 player 可以高效的测试游戏功能。
Player支持从命令行启动,感觉貌似作用不大了,因为现在直接可在图形化操作了。具体参数参看官网。
这里先通过Player创建一个项目后,
在src目录中便可找到config.lua。
Config.lua文件中,定义了程序的一些特性是否开启,如是否调试、是否显示FPS信息等。
在code-ide中编辑MainScene.lua文件,修改如下文件
function MainScene:ctor()
cc.ui.UILabel.new({
UILabelType = 2, text = "Hello, World", size = 64})
:align(display.CENTER, display.cx,display.cy)
:addTo(self)
end
将text = "Hello,World",修改为text = "YES,World" 保存后即可见修改。
每个程序都有自己的入门,这个基于LUA的项目入门函数在main.lua函数中,
然后进入MyApp.lua文件,该文件中的
function MyApp:run()
该函数会实现跳转,到达MainScene.lua文件中的函数。
新建一个LUA文件,输入代码如
local Player = class("Player", function()
local sprite = display.newSprite("image/diji.png")
return sprite
end)
function Player:ctor()
end
return Player
即可实现新类创建。
然后在MainScene.lua中输入
一下代码即可
local Player =import("..role.Player")
local Player = class("Player", function()
return display.newSprite("image/diji.png") end)
function MainScene:ctor()
cc.ui.UILabel.new({
--其他代码省略
self.player = Player.new() --display.newSprite("#player1-1-1.png")
self.player:setPosition(display.left + self.player:getContentSize().width/2, display.cy)
self:addChild(self.player)
end
类的构造函数是ctor。
ctrl+shift+C 会加上或者去掉--注释
在工具上选中Window –> Preferences – >General –> Workspace , Text fileencoding ,选成UTF-8即可。退出code-ide重进,问题解决。
和刷新网页一样,F5即可。主要保护F5键盘。
添加资源搜索路径
CCFileUtils:sharedFileUtils():addSearchPath("res/")
device.writablePath获得存档文件保存目录
可以用 display.width,display.height 获得屏幕分辨率。
cc.ui.UIPushButton.new("CloseNormal.png" )
:setButtonLabel(cc.ui.UILabel.new({text= "Use CCSLoader"}))
:onButtonPressed(function(event)
event.target:setScale(1.2)
print("pressed")
end)
这里假设大家已熟悉quick开发的基础知识。
Quick版本是3.3的。
在ctor()函数中加入如下函数即可是实现一个抖动菜单
local button1 = cc.ui.UIPushButton.new("CloseNormal.png")
:align(display.CENTER, display.cx,display.cy + 40)
:onButtonPressed(function(event)
local function zoom1(offset, time,scale, onComplete)
local x, y = event.target:getPosition()
local size = self:getContentSize()
local scaleX = event.target:getScaleX() * (size.width + scale) / size.width
local scaleY = event.target:getScaleY() * (size.height - scale) / size.height
transition.moveTo(event.target, {y = y - offset, time = time})
transition.scaleTo(event.target, {
scaleX = scaleX,
scaleY = scaleY,
time = time,
onComplete = onComplete,
})
end
local function zoom2(offset, time, scale,onComplete)
local x, y = event.target:getPosition()
local size = self:getContentSize()
transition.moveTo(event.target, {y = y + offset, time = time / 2})
transition.scaleTo(event.target, {
scaleX = 1.0,
scaleY = 1.0,
time = time,
onComplete = onComplete,
})
end
zoom1(20, 0.08,500, function()
zoom2(20, 0.09,500, function()
zoom1(10, 0.10,400, function()
zoom2(10, 0.11,400, function()
end)
end)
end)
end)
print("pressed")
end)
:addTo(self)
文件头处输入:
local scheduler = require("framework.scheduler")
函数中输入
local time = 0
local function update(dt)
time = time + 1
print(time)
end
scheduler.scheduleUpdateGlobal(update)
local time = 0
local function onInterval(dt)
time = time + 1
print(time)
end
scheduler.scheduleGlobal(onInterval, 1)
local time = 0
local function onInterval(dt)
time = time + 1
print(time)
print("over")
end
scheduler.performWithDelayGlobal(onInterval, 1)
scheduler.unscheduleGlobal() |
参数是前面那些定时器返回的句柄,所以如果需要在后面停止掉,在创建的留一个返回值
local layer = display.newLayer()
self:addChild(layer)
layer:setTouchEnabled(true)
layer:setTouchMode(cc.TOUCH_MODE_ONE_BY_ONE)
layer:addNodeEventListener(cc.NODE_TOUCH_EVENT, function (event)
local x, y, prevX, prevY = event.x, event.y, event.prevX, event.prevY
if event.name == "began" then
print("layer began")
elseif event.name == "moved" then
print("layer moved")
elseif event.name == "ended" then
print("layer ended")
end
end)
· cc.TOUCH_MODE_ONE_BY_ONE 是单点触摸
· cc.TOUCH_MODE_ALL_AT_ONCE 是多点触摸
在添加节点事件监听addNodeEventListener中,我们设置监听事件的类型是cc.NODE_TOUCH_EVENT
这个监听事件类型,其定义了几个引擎级事件,分别是,
-- Cocos2d-x 引擎级事件
|
c.NODE_EVENT = 0 c.NODE_ENTER_FRAME_EVENT = 1 c.NODE_TOUCH_EVENT = 2 c.NODE_TOUCH_CAPTURE_EVENT = 3 c.MENU_ITEM_CLICKED_EVENT = 4 c.ACCELERATE_EVENT = 5 c.KEYPAD_EVENT = 6 |
在event参数里,里面有name,x,y,prevX,prevY 这五个变量,分别代表着
· event.name 是触摸事件的状态:began, moved, ended, cancelled, added(仅限多点触摸), removed(仅限多点触摸);
· event.x, event.y 是触摸点当前位置;
· event.prevX, event.prevY 是触摸点之前的位置;
触摸捕获事件的优先级要比触摸事件要高,换句话说,触摸捕获事件会比触摸事件先响应,并且有权不分发给触摸事件响应。举例如下
local layer = display.newLayer()
self:addChild(layer)
layer:setTouchEnabled(true)
layer:setTouchSwallowEnabled(false)
layer:setTouchMode(cc.TOUCH_MODE_ONE_BY_ONE)
layer:addNodeEventListener(cc.NODE_TOUCH_EVENT, function (event)
if event.name == "began" then
print("layer began")
elseif event.name == "moved" then
print("layer moved")
elseif event.name == "ended" then
print("layer ended")
end
return true
end)
layer:addNodeEventListener(cc.NODE_TOUCH_CAPTURE_EVENT,function (event)
if event.name == "began" then
print("layer capture began")
elseif event.name == "moved" then
print("layer capture moved")
elseif event.name == "ended" then
print("layer capture ended")
end
return true
end)
local sp = display.newSprite("HelloWorld.png", display.cx,display.cy)
layer:addChild(sp)
--self:addChild(sp)
sp:setTouchEnabled(true)
sp:setTouchSwallowEnabled(false)
sp:setTouchMode(cc.TOUCH_MODE_ONE_BY_ONE)
sp:addNodeEventListener(cc.NODE_TOUCH_EVENT, function (event)
if event.name == "began" then
print("sp began")
elseif event.name == "moved" then
print("sp moved")
elseif event.name == "ended" then
print("sp ended")
end
return true
end)
sp:addNodeEventListener(cc.NODE_TOUCH_CAPTURE_EVENT,function (event)
if event.name == "began" then
print("sp capture began")
elseif event.name == "moved" then
print("sp capture moved")
elseif event.name == "ended" then
print("sp capture ended")
end
return true
end)
多点触摸如下:
local layer = display.newLayer()
self:addChild(layer)
layer:setTouchEnabled(true)
layer:setTouchMode(cc.TOUCH_MODE_ALL_AT_ONCE)
layer:addNodeEventListener(cc.NODE_TOUCH_EVENT, function (event)
if event.name == "began" or event.name == "added" then
for id, point in pairs(event.points) do
printf("%d, %f, %f", id, event.points[id].x, event.points[id].y)
end
elseif event.name == "removed" then
print("touch removed")
elseif event.name == "moved" then
print("touch moved")
elseif event.name == "ended" then
print("touch ended")
end
return true
end)
硬件按键是设备上的触摸屏之外的按键。
预定义的层事件主要有两个:
· cc.ACCELERATE_EVENT:重力感应事件
· cc.KEYPAD_EVENT:硬件按键事件
要实现一个按键响应事件主要就两步:
· 1. 打开键盘功能setKeypadEnabled(true)
· 2. 添加事件监听addNodeEventListener
local layer = display.newLayer()
self:addChild(layer)
layer:setKeypadEnabled(true)
layer:addNodeEventListener(cc.KEYPAD_EVENT, function (event)
if event.key == "back" then
print("back")
device.showAlert("Confirm Exit", "Are you sure exit game ?", {"YES", "NO"}, function (event)
if event.buttonIndex == 1 then
CCDirector:sharedDirector():endToLua()
else
device.cancelAlert()
end
end)
elseif event.key == "menu" then
print("menu")
end
end)
预定义的节点事件:
· cc.NODE_EVENT - enter, exit等事件
· cc.NODE_ENTER_FRAME_EVENT -帧事件
· cc.NODE_TOUCH_EVENT - 触摸事件
· cc.NODE_TOUCH_CAPTURE_EVENT- 捕获触摸事件
预定义的层事件:
· cc.ACCELERATE_EVENT - 重力感应事件
· cc.KEYPAD_EVENT - 硬件按键事件
预定义的菜单事件:
· cc.MENU_ITEM_CLICKED_EVENT- CCMenu 菜单项点击事件
如果开发没有断点调试实在是让人异常头疼,好吧,蛤蟆就记录下如何是是实现QUICK项目的断点调试。
需要quick 的develop版本。只有DEVEOP版本才有断点调试。
仓库地址:https://github.com/chukong/quick-cocos2d-x
下载后运行加压包中的 setup_win.bat进行环境变量配置
然后按下网址代码进行配置
http://quick.cocos.org/?p=1527
Player3后的调试,查看官网
《在 Code IDE 中调试 Quick 工程》
CODE IDE 调试
http://cn.cocos2d-x.org/article/index?type=quick_doc&url=/doc/cocos-docs-master/manual/framework/quick/V3/how-to/use-codeide/zh.md
命令行启动带CONSOLE
D:\cocos\quick-3.3\quick\player\win32>player3.exe-workdir F:\cocoside_zhizuo\com
创建状态机
self.fsm_ = {}
cc.GameObject.extend(self.fsm_)
:addComponent("components.behavior.StateMachine")
:exportMethods()
self.fsm_:setupState({
-- 初始状态
initial = "idle",
-- 事件和状态转换
events = {
-- t1:clickScreen; t2:clickEnemy; t3:beKilled; t4:stop
{name = "clickScreen", from = {"idle", "attack"}, to = "walk" },
{name = "clickEnemy", from = {"idle", "walk"}, to = "attack"},
{name = "beKilled", from = {"idle", "walk", "attack"}, to = "dead"},
{name = "stop", from = {"walk", "attack"}, to = "idle"},
},
-- 状态转变后的回调
callbacks = {
onidle = function () print("idle") end,
onwalk = function () print("move") end,
onattack = function () print("attack") end,
ondead = function () print("dead") end
},
})
end
增加doEvent函数
命名规则
· onbeforexxx: 执行xxx事件前的响应函数;
· onxxx或者onafterxxx: 执行xxx事件完成的响应函数;
· onenterxxx或者onxxx: 进入xxx状态时的响应函数;
· onleavexxx: 离开xxx状态时的响应函数;
· onbeforeevent: 执行所有事件之前会执行该响应函数,事件信息以参数形式下发;
· onafterevent或者onevent: 执行所有事件完成之后执行该响应函数,事件信息以参数形式下发;
· onchangestate: 改变状态时的响应函数,事件信息会以参数的形式下发;
· onenterstate: 进入状态时的响应函数,事件信息会以参数形式下发:
· onleavestate: 离开状态时的响应函数,事件信息会以参数形式下发。
设置状态逻辑是重写setupState方法,这其中有这么几个字段参数,
· initial:状态机的初始状态
· terminal (final):结束状态
· events:状态发生转变时对应的事件
· callbacks:发生转变时的回调函数
接下来一个重点是callbacks参数,即所谓回调了,就是事件触发,会执行一系列的函数。
· onbeforeEVNET:在事件EVENT开始前被激活
· onleaveSTATE:在离开旧状态STATE时被激活
· onenterSTATE 或 onSTATE:在进入新状态STATE时被激活
· onafterEVENT 或 onEVENT:在事件EVENT结束后被激活
此外还有5种通用型的回调来捕获所有事件和状态的变化:
· onbeforeevent:在任何事件开始前被激活
· onleavestate:在离开任何状态时被激活
· onenterstate:在进入任何状态时被激活
· onafterevent :在任何事件结束后被激活
· onchangestate :当状态发生改变的时候被激活
这里面的名称是不可以修改的,它是针对于任何事件和任何状态的。
最后,就是调用这些事件了,通过self.fsm:doEvent(event)就可以了,参数event对应events参数名称。此外还有这些,
· fsm:isReady():返回状态机是否就绪
· fsm:getState():返回当前状态
· fsm:isState(state):判断当前状态是否是参数state状态
· fsm:canDoEvent(eventName):当前状态如果能完成eventName对应的event的状态转换,则返回true
· fsm:cannotDoEvent(eventName):当前状态如果不能完成eventName对应的event的状态转换,则返回true
· fsm:isFinishedState():当前状态如果是最终状态,则返回true
· fsm:doEventForce(name, ...):强制对当前状态进行转换
官网链接如下:
http://cn.cocos2d-x.org/tutorial/show?id=1471
文章二
http://cn.cocos2d-x.org/article/index?type=quick_doc&url=/doc/cocos-docs-master/manual/framework/quick/V3/how-to/compile-android/zh.md
文章三
http://cn.cocos2d-x.org/article/index?type=quick_doc&url=/doc/cocos-docs-master/tutorial/framework/quick/chap1/zh.md
蛤蟆实践过程如下:
android环境编译手动记录,下面这些是必须的:
· Quick-Cocos2d-x引擎
· JDK
· android-sdk
· android-ndk(r9以上)
环境变量中需要设置ANDROID_NDK_ROOT
1、进入项目\upgrade_bak\frameworks\runtime-src\proj.android
2、在proj.android目录下执行./build_native(Mac)或者build_native.bat(windows)拷贝资源和编译C++文件。
编译完成后我们可以在proj.android目录下面的assets中有res和src文件夹,这两个文件夹就是我们的资源文件夹。(此处处理后第4、5步就不用操作了)
3、通过Eclipse来打包。
使用Eclipse打包相对来说要简单的多,打开Eclipse,点击File->Import
,在弹出的界面中选择Existing Android Code Into Workspace
:
选择刚才创建的工程,导入完成后点击Finish
结束导入。
4、将LUA 项目中\upgrade_bak \cocos2d-x\cocos\platform\android\java\src中java代码
复制到ECLIPSE项目中的\src 中,覆盖之。
5、最后将LUA代码复制到Eclipse 项目中assets/src/ 下
如果有图片等资源存放至:\assets\res\
6、编译运行。
成功!
运行Build_native.bat出错
'./obj/local/armeabi/objs-debug/extra_static/F_\cocoside_zhizuo\test\upgra
de_bak\frameworks\runtime-src\proj.android\/__/Classes/quick-src/extra/luabindin
g/lua_cocos2dx_extension_filter_auto.o.d':
Error opening output file
答:项目路径超长
复制\upgrade_bak文件夹出来到分区根目录下重命名后编辑即可。
升级到最新3.2rc0
http://cn.cocos2d-x.org/article/index?type=quick_doc&url=/doc/cocos-docs-master/manual/framework/quick/V3/how-to/upgrade/zh.md
http://www.verypig.com/
http://www.niaogebiji.com/article-4056-1.html
http://www.niaogebiji.com/article-1948-1.html
http://www.oschina.net/question/tag/hadoop