Cocos2d-x-Lua示例项目HelloLua(1)

文章介绍了在Cocos2d-x框架中如何使用Lua脚本,并详细展示了AppDelegate类中与应用进入后台、前台切换相关的函数,以及如何在main.lua文件中管理内存和加载资源,包括动画和音频的控制。
摘要由CSDN通过智能技术生成

if (engine->executeScriptFile(“src/main.lua”)) {

return false;

}

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

// 该方法与applicationDidEnterBackground() 成对出现,在应用程序回到前台时被调用

void AppDelegate::applicationWillEnterForeground()

{

Director::getInstance()->startAnimation();

SimpleAudioEngine::getInstance()->resumeBackgroundMusic();

}

我们在AppDelegate类当中可以找到执行我们Lua脚本的方法,下面来看一下main.lua这个文件,我们屏幕显示的逻辑实现全部在这个文件中可以看到:

>>>main.lua

require “Cocos2d”

require “Cocos2dConstants”

– cclog

cclog = function(…)

print(string.format(…))

end

– for CCLuaEngine traceback 输出绑定执行函数发生错误的信息

function G__TRACKBACK(msg)

cclog(“----------------------------------------”)

cclog("LUA ERROR: " … tostring(msg) … “\n”)

cclog(debug.traceback())

cclog(“----------------------------------------”)

return msg

end

local function main()

collectgarbage(“collect”)

– avoid memory leak 这是脚本回收参数,避免内存泄漏

collectgarbage(“setpause”, 100)

collectgarbage(“setstepmul”, 5000)

– 追加资源的搜索顺序

cc.FileUtils:getInstance():addSearchResolutionsOrder(“src”);

cc.FileUtils:getInstance():addSearchResolutionsOrder(“res”);

local schedulerID = 0

–support debug 获取目标平台

local targetPlatform = cc.Application:getInstance():getTargetPlatform()

if (cc.PLATFORM_OS_IPHONE == targetPlatform) or (cc.PLATFORM_OS_IPAD == targetPlatform) or

(cc.PLATFORM_OS_ANDROID == targetPlatform) or (cc.PLATFORM_OS_WINDOWS == targetPlatform) or

(cc.PLATFORM_OS_MAC == targetPlatform) then

cclog("result is ")

–require(‘debugger’)()

end

– 类似c++的include,引入文件,会检查是否重复引入

require “hello2”

– 调用外部函数,在hello2.lua中

cclog("result is " … myadd(1, 1))


– 获取可视区域

local visibleSize = cc.Director:getInstance():getVisibleSize()

– 可视原点坐标 OpenGL坐标系,左下角为原点

local origin = cc.Director:getInstance():getVisibleOrigin()

– add the moving dog 添加移动的小松鼠

local function creatDog()

– 每一帧尺寸设置,local表示局部变量

local frameWidth = 105

local frameHeight = 95

– create dog animate 加载动画资源并创建精灵帧

– 加载精灵动画所在纹理

local textureDog = cc.Director:getInstance():getTextureCache():addImage(“dog.png”)

– 设置第一帧帧区域

local rect = cc.rect(0, 0, frameWidth, frameHeight)

– 创建第一帧精灵Frame

local frame0 = cc.SpriteFrame:createWithTexture(textureDog, rect)

– 设置第二帧帧区域

rect = cc.rect(frameWidth, 0, frameWidth, frameHeight)

– c创建第二帧精灵Frame

local frame1 = cc.SpriteFrame:createWithTexture(textureDog, rect)

– 基于使用第一帧Frame创建Sprite对象

local spriteDog = cc.Sprite:createWithSpriteFrame(frame0)

spriteDog.isPaused = false

spriteDog:setPosition(origin.x, origin.y + visibleSize.height / 4 * 3)

–[[

local animFrames = CCArray:create()

animFrames:addObject(frame0)

animFrames:addObject(frame1)

]]–

– 根据帧序列数组创建一个动画animation。帧间隔时间delay等于0.5秒

local animation = cc.Animation:createWithSpriteFrames({frame0,frame1}, 0.5)

– 根据动画animation创建动作实例

local animate = cc.Animate:create(animation);

– 松鼠精灵执行该动作

spriteDog:runAction(cc.RepeatForever:create(animate))

– moving dog at every frame 用来更新松鼠的位置,后面会调用该函数

local function tick()

if spriteDog.isPaused then return end

local x, y = spriteDog:getPosition()

if x > origin.x + visibleSize.width then

x = origin.x

else

x = x + 1

end

spriteDog:setPositionX(x)

end

– 生成一个scheule,每帧执行tick函数

schedulerID = cc.Director:getInstance():getScheduler():scheduleScriptFunc(tick, 0, false)

return spriteDog

end

– create farm 创建地面的农场

local function createLayerFarm()

– 创建一个新的Lyaer用作农场管理

local layerFarm = cc.Layer:create()

– add in farm background 添加农场管理

local bg = cc.Sprite:create(“farm.jpg”)

bg:setPosition(origin.x + visibleSize.width / 2 + 80, origin.y + visibleSize.height / 2)

layerFarm:addChild(bg)

– add land sprite 添加地面砖块

for i = 0, 3 do

for j = 0, 1 do

local spriteLand = cc.Sprite:create(“land.png”)、

– 设定每一块砖块位置

spriteLand:setPosition(200 + j * 180 - i % 2 * 90, 10 + i * 95 / 2)

layerFarm:addChild(spriteLand)

end

end

– add crop 添加庄稼,注意crop.png是多张图的合成贴图,所以只取了里面的部分贴图

local frameCrop = cc.SpriteFrame:create(“crop.png”, cc.rect(0, 0, 105, 95))

for i = 0, 3 do

for j = 0, 1 do

local spriteCrop = cc.Sprite:createWithSpriteFrame(frameCrop);

spriteCrop:setPosition(10 + 200 + j * 180 - i % 2 * 90, 30 + 10 + i * 95 / 2)

layerFarm:addChild(spriteCrop)

end

end

– add moving dog 调用上面的createDog()方面,创建一个移动的松鼠

local spriteDog = creatDog()

layerFarm:addChild(spriteDog)

– handing touch events 手指触摸事件处理

local touchBeginPoint = nil

– 手指点击开始

local function onTouchBegan(touch, event)

local location = touch:getLocation()

cclog(“onTouchBegan: %0.2f, %0.2f”, location.x, location.y)

touchBeginPoint = {x = location.x, y = location.y} – 保存点击位置

spriteDog.isPaused = true – 将松鼠暂停移动

– CCTOUCHBEGAN event must return true

return true

end

– 手指按住移动

local function onTouchMoved(touch, event)

local location = touch:getLocation()

cclog(“onTouchMoved: %0.2f, %0.2f”, location.x, location.y)

if touchBeginPoint then

– 将整个农村层拖动,因为之前已经将农场里面所有对象加入layerFarm

local cx, cy = layerFarm:getPosition()

layerFarm:setPosition(cx + location.x - touchBeginPoint.x,

cy + location.y - touchBeginPoint.y)

touchBeginPoint = {x = location.x, y = location.y}

end

end

– 手指离开

local function onTouchEnded(touch, event)

local location = touch:getLocation()

cclog(“onTouchEnded: %0.2f, %0.2f”, location.x, location.y)

touchBeginPoint = nil – 点击位置数据清空

spriteDog.isPaused = false – 恢复松鼠移动

end

– 创建触摸事件监听器

local listener = cc.EventListenerTouchOneByOne:create()

– 注册touch事件

listener:registerScriptHandler(onTouchBegan,cc.Handler.EVENT_TOUCH_BEGAN )

listener:registerScriptHandler(onTouchMoved,cc.Handler.EVENT_TOUCH_MOVED )

listener:registerScriptHandler(onTouchEnded,cc.Handler.EVENT_TOUCH_ENDED )

local eventDispatcher = layerFarm:getEventDispatcher()

– 添加场景图优先级事件监听

eventDispatcher:addEventListenerWithSceneGraphPriority(listener, layerFarm)

local function onNodeEvent(event)

if “exit” == event then

cc.Director:getInstance():getScheduler():unscheduleScriptEntry(schedulerID)

end

end

layerFarm:registerScriptHandler(onNodeEvent)

return layerFarm

end

– create menu 创建界面菜单

local function createLayerMenu()

– 创建一个新的Layer管理所有菜单

local layerMenu = cc.Layer:create()

local menuPopup, menuTools, effectID

– 点击菜单回调函数

local function menuCallbackClosePopup()

– stop test sound effect 关闭音效

cc.SimpleAudioEngine:getInstance():stopEffect(effectID)

menuPopup:setVisible(false) – 隐藏菜单

end

– 点击菜单回调函数

local function menuCallbackOpenPopup()

– loop test sound effect 打开营销

local effectPath = cc.FileUtils:getInstance():fullPathForFilename(“effect1.wav”)

effectID = cc.SimpleAudioEngine:getInstance():playEffect(effectPath)

menuPopup:setVisible(true)

end

– add a popup menu 创建弹出的菜单面板

local menuPopupItem = cc.MenuItemImage:create(“menu2.png”, “menu2.png”)

menuPopupItem:setPosition(0, 0)

menuPopupItem:registerScriptTapHandler(menuCallbackClosePopup)

menuPopup = cc.Menu:create(menuPopupItem)

menuPopup:setPosition(origin.x + visibleSize.width / 2, origin.y + visibleSize.height / 2)

menuPopup:setVisible(false)

layerMenu:addChild(menuPopup)

– add the left-bottom “tools” menu to invoke menuPopup

– 添加左下角的工具按钮,用来弹出菜单面板

local menuToolsItem = cc.MenuItemImage:create(“menu1.png”, “menu1.png”)

menuToolsItem:setPosition(0, 0)

– 注册点击回调地址

menuToolsItem:registerScriptTapHandler(menuCallbackOpenPopup)

menuTools = cc.Menu:create(menuToolsItem)

local itemWidth = menuToolsItem:getContentSize().width

local itemHeight = menuToolsItem:getContentSize().height

menuTools:setPosition(origin.x + itemWidth/2, origin.y + itemHeight/2)

layerMenu:addChild(menuTools)

return layerMenu

end

– play background music, preload effect

– uncomment below for the BlackBerry version

local bgMusicPath = nil

if (cc.PLATFORM_OS_IPHONE == targetPlatform) or (cc.PLATFORM_OS_IPAD == targetPlatform) then

bgMusicPath = cc.FileUtils:getInstance():fullPathForFilename(“res/background.caf”)

else

bgMusicPath = cc.FileUtils:getInstance():fullPathForFilename(“res/background.mp3”)

end

cc.SimpleAudioEngine:getInstance():playMusic(bgMusicPath, true)

local effectPath = cc.FileUtils:getInstance():fullPathForFilename(“effect1.wav”)

– 预加载音效

cc.SimpleAudioEngine:getInstance():preloadEffect(effectPath)

– run

local sceneGame = cc.Scene:create() – 创建场景

sceneGame:addChild(createLayerFarm()) – 将农场层加入场景

sceneGame:addChild(createLayerMenu()) – 将菜单界面层加入场景

– 判断是否有运行的场景

if cc.Director:getInstance():getRunningScene() then

cc.Director:getInstance():replaceScene(sceneGame) – 替换场景

else

cc.Director:getInstance():runWithScene(sceneGame)

end

end

–[[

xpcall( 调用函数, 错误捕获函数 );

lua提供了xpcall来捕获异常

xpcall接受两个参数:调用函数、错误处理函数。

当错误发生时,Lua会在栈释放以前调用错误处理函数,因此可以使用debug库收集错误相关信息。

两个常用的debug处理函数:debug.debug和debug.traceback

前者给出Lua的提示符,你可以自己动手察看错误发生时的情况;

后者通过traceback创建更多的错误信息,也是控制台解释器用来构建错误信息的函数。

–]]

local status, msg = xpcall(main, G__TRACKBACK)

if not status then

error(msg)

end

这是Cocos2d-x 3.1.1所使用的代码,代码中的注释已经很详细了,笔者在这里就不多说,希望大家能认真阅读,跟笔者一起尽快入门Lua在Cocos2dx中的使用。

最后

我见过很多技术leader在面试的时候,遇到处于迷茫期的大龄程序员,比面试官年龄都大。这些人有一些共同特征:可能工作了7、8年,还是每天重复给业务部门写代码,工作内容的重复性比较高,没有什么技术含量的工作。问到这些人的职业规划时,他们也没有太多想法。

其实30岁到40岁是一个人职业发展的黄金阶段,一定要在业务范围内的扩张,技术广度和深度提升上有自己的计划,才有助于在职业发展上有持续的发展路径,而不至于停滞不前。

不断奔跑,你就知道学习的意义所在!

《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》点击传送门,即可获取!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值