quick-cocos2d-x 学习系列之 开篇杂记
开始学习quick-cocos2d-x这个工具了,边学边记录吧。 邮箱appdevzw@163.com 欢迎各界交流 1.官方链接1.1quick-x-player 使用说明http://quick.cocoachina.com/?p=39 1.2初窥 quick-cocos2d-xhttp://quick.cocoachina.com/?p=1 这篇文档讲的甚是明白 1.3用 Eclipse LDT 调试 quick-cocos2d-x 游戏http://quick.cocoachina.com/?p=1527 断点调试编码必备 需要什么信息,可以直接在官网上进行搜索,必定会得到你想要的结果。 2.Quick和cocos2d-x区别引用自官方文档:quick 和 cocos2d-x 的主要区别有如下几点: 1.更完善的 Lua 支持,包括一个 Lua 框架对 C++ 接口进行了二次封装 2.补充了大量cocos2d-x 没有提供,但游戏需要的功能 3.为提高开发效率,提供了Objective-C 和 Java 的桥接模块,以及强化的 Windows/Mac 模拟器 3.PLAYER引用官方:quick-cocos2d-x 里附带了一个功能强大的模拟器,称为 quick-x-player(后文简称 player)。 player 可以在 Mac 和 Windows 环境中模拟游戏引擎的绝大部分功能。在开发过程中,利用 player 可以高效的测试游戏功能。 2.1从命令行启动 playerPlayer支持从命令行启动,感觉貌似作用不大了,因为现在直接可在图形化操作了。具体参数参看官网。 4.动态实时调试举例这里先通过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" 保存后即可见修改。 5.程序入口每个程序都有自己的入门,这个基于LUA的项目入门函数在main.lua函数中, 然后进入MyApp.lua文件,该文件中的 function MyApp:run() 该函数会实现跳转,到达MainScene.lua文件中的函数。 6.创建新类新建一个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。
7.code ide工具使用7.1注释ctrl+shift+C 会加上或者去掉--注释
7.2Code IDE函数注释显示乱码在工具上选中Window –> Preferences – >General –> Workspace,Text fileencoding,选成UTF-8即可。退出code-ide重进,问题解决。 7.3代码修改刷新程序和刷新网页一样,F5即可。主要保护F5键盘。 8.代码细节8.1增加搜索路径添加资源搜索路径 CCFileUtils:sharedFileUtils():addSearchPath("res/") 8.2存档路径device.writablePath获得存档文件保存目录 8.3屏幕分辨率可以用 display.width,display.height 获得屏幕分辨率。 8.4创建菜单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) 8.5抖动菜单效果按钮,果冻按钮效果这里假设大家已熟悉quick开发的基础知识。 Quick版本是3.3的。 在ctor()函数中加入如下函数即可是实现一个抖动菜单 local button1 = cc.ui.UIPushButton.new("CloseNormal.png") :align(display.CENTER,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,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, }) end zoom1(20,0.08,500, function() zoom2(20,0.09, function() zoom1(10,0.10,400, function() zoom2(10,0.11, function() end) end)
end) end) print("pressed") end) :addTo(self) 8.6定时器使用8.6.1每帧调用文件头处输入: local scheduler = require("framework.scheduler") 函数中输入 local time = 0 local function update(dt) time = time + 1 print(time) end scheduler.scheduleUpdateGlobal(update) 8.6.2间隔一定时间调用local time = 0 local function onInterval(dt) time = time + 1 print(time) end scheduler.scheduleGlobal(onInterval,1)
8.6.3间隔时间调用一次local time = 0 local function onInterval(dt) time = time + 1 print(time) print("over") end scheduler.performWithDelayGlobal(onInterval,1) 8.6.4停止定时器
参数是前面那些定时器返回的句柄,所以如果需要在后面停止掉,在创建的留一个返回值 8.7触摸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 引擎级事件
在event参数里,里面有name,x,y,prevX,prevY 这五个变量,分别代表着 ·event.name 是触摸事件的状态:began,moved,ended,cancelled,added(仅限多点触摸),removed(仅限多点触摸); ·event.x,event.y 是触摸点当前位置; ·event.prevX,event.prevY 是触摸点之前的位置; 8.8触摸捕获世界触摸捕获事件的优先级要比触摸事件要高,换句话说,触摸捕获事件会比触摸事件先响应,并且有权不分发给触摸事件响应。举例如下 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.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) 8.9多点触摸多点触摸如下: 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) 8.10硬件按键硬件按键是设备上的触摸屏之外的按键。 预定义的层事件主要有两个: ·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) 8.11其他事件预定义的节点事件: ·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 菜单项点击事件 9.断点调试如果开发没有断点调试实在是让人异常头疼,好吧,蛤蟆就记录下如何是是实现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:cocosquick-3.3quickplayerwin32>player3.exe-workdir F:cocoside_zhizuocom 10.状态机实现记录创建状态机 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","walk"},to = "attack"}, {name = "beKilled","walk",to = "dead"}, {name = "stop",from = {"walk",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,...):强制对当前状态进行转换 11.quick-coco2dx-x烧写到android/ios真机官网链接如下: 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_bakframeworksruntime-srcproj.android 编译完成后我们可以在proj.android目录下面的assets中有res和src文件夹,这两个文件夹就是我们的资源文件夹。(此处处理后第4、5步就不用操作了) 3、通过Eclipse来打包。 使用Eclipse打包相对来说要简单的多,打开Eclipse,点击 选择刚才创建的工程,导入完成后点击 4、将LUA 项目中upgrade_bak cocos2d-xcocosplatformandroidjavasrc中java代码 复制到ECLIPSE项目中的src 中,覆盖之。 5、最后将LUA代码复制到Eclipse 项目中assets/src/ 下 如果有图片等资源存放至:assetsres
6、编译运行。 成功! 1.4出错问题运行Build_native.bat出错 './obj/local/armeabi/objs-debug/extra_static/F_cocoside_zhizuotestupgra de_bakframeworksruntime-srcproj.android/__/Classes/quick-src/extra/luabindin g/lua_cocos2dx_extension_filter_auto.o.d': Error opening output file 答:项目路径超长 复制upgrade_bak文件夹出来到分区根目录下重命名后编辑即可。
12.相关链接升级到最新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 13.其他友情链接13.1王信文(刀塔传奇)创业笔记http://www.verypig.com/ 13.2创业不简单:一个失败手游创业者的自白
http://www.niaogebiji.com/article-4056-1.html 13.3鸟哥笔记http://www.niaogebiji.com/article-1948-1.html 13.4Hadoop开源社区http://www.oschina.net/question/tag/hadoop (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |