[cocos2dx-lua]"Hello Lua"分析
一年之前学的cocos2dx,那时候还是用C++编写的。但学完之后就找的一个新的方向——Unity3D开发的岗位,对我而言是一个新方向,那时候经过了几个月的每天熬夜奋战,从”0“基础到最后项目开发,那时候是在的是个小公司,整体而言还算比較轻松,可能效率利用的比較低。如今刚出来了。来到一家大公司。感觉到非常多不一样的变化。方向又改变了,还是回到之前的cocos2dx开发,但用的不是C++,而是lua脚本语言来开发,对我而言又是差点儿是从新開始。既来之则安之,在接触了那么多方向之后,是该选择一个确定的研究方向深入下去。
来这该公司一周了,感受到一种之前所没有的紧迫感,每天要给自己下定任务,而且按时按量的去完毕,同事都非常厉害。都是在这行业工作了多少年的。非常有工作经验。希望以后像他们多多请教,公司好多女程序,都非常厉害,我的直属上司杨总就是当时面试我的,我以为当时面试的时候他旁边的那位是秘书的,挺美丽的一个女”上司“,我一直以为是秘书。看起来非常年轻,后来从同事那儿了解到她是我们全部人的上司,是公司的技术总监。好吧,我吃惊了,原来她是公司元老级别的程序了。第一天入职,办理好入职手续,下午的时候老大递给了我一本Lua编程的教程。不是太厚,但也不薄,三百多页吧。后来花了两天左右的时间将它看完。因为之前学的语言都是编译型语言,用上强大的Visutial studio+VA提示功能非常强大。导致如今要用文本编辑器来写lua语言有点痛苦。非常easy手误,但还是要慢慢习惯。不论什么事物都有两面性,没有所谓绝对的完美。
花两天时间看完lua语法,然后花了一天看了下cocos2dx lua的Demo,接下来就能够进行项目开发了,不然每天开例会总是处于学习阶段总感觉不好,公司不会养两种人,懒人和闲人,所以还是多花点业余时间来弥补自己的缺陷,跟上大部队的开发。
- 创建Cocos2dx-Lua项目
我这里使用的是Visual Studio 2012+cocos2dx 2.2.4,前提安装上Python
打开控制台。通过命令来创建新的项目
然后打开cocos2dx的projects文件夹发现生成了刚刚创建的lua项目
假设是Windows平台就打开proj.win32->luastudy1.sln,编译一下就可以执行势力demo。
- 效果图
cocos2dx lua项目。lua脚本放在Resources文件夹下。也就是说lua脚本也像图片。声音资源这些一样被当成是资源利用了,所以假设程序要逻辑跟新或者说有什么bug,能够直接改动lua文件然后又一次上传就可以,不需要再次编译公布。这也是lua开发cocos2dx的一大长处。
- lua脚本
require "AudioEngine" -- for CCLuaEngine traceback function __G__TRACKBACK__(msg) print("----------------------------------------") print("LUA ERROR: " .. tostring(msg) .. "\n") print(debug.traceback()) print("----------------------------------------") end --打印函数 local cclog = function(...) print(string.format(...)) end function main() --调用其它脚本的方法 require "hello2" --调用其它lua的脚本中的方法 cclog("调用hello2脚本的方法:Result = "..myadd(3,5)) --获取屏幕分辨率 local visibleSize = CCDirector:sharedDirector():getVisibleSize() --获取屏幕分辨率的起始坐标 local origin = CCDirector:sharedDirector():getVisibleOrigin() print("可视区域的起点坐标:",origin.x,origin.y) print("屏幕分辨率:",visibleSize.width,visibleSize.height) --创建一个场景 local scene = CCScene:create() --创建一个层 local layer = CCLayer:create() --创建一个文本 local label = CCLabelTTF:create("你好 Lua","simkai",50) --假设中文不显示的话,必需要将lua文件保存为中文 label:setPosition(ccp(visibleSize.width/2+30,visibleSize.height/2+100)) layer:addChild(label) --创建一个Sprite图标 local iconSprite = CCSprite:create("Icon.png") iconSprite:setPosition(ccp(80,260)) layer:addChild(iconSprite) ----------------------------创建一个动画精灵--------------------------------------------------- local function createDog() --创建一个动画(这里是两张图片合成的一张,所以要依据矩形切割) local frameWidth = 105 local frameHeight = 95 --纹理块管理器创建一个图片文理 local textureDog = CCTextureCache:sharedTextureCache():addImage("dog.png") local rect = CCRectMake(0,0,frameWidth,frameHeight) --创建精灵帧 local frame0 = CCSpriteFrame:createWithTexture(textureDog,rect) rect = CCRectMake(frameWidth,0,frameWidth,frameHeight) local frame1 = CCSpriteFrame:createWithTexture(textureDog,rect) --创建一个精灵 local spriteDog = CCSprite:createWithSpriteFrame(frame0) spriteDog.isPaused = false spriteDog:setPosition(origin.x+visibleSize.width-60,origin.y + visibleSize.height/2) local animFrames = CCArray:create() animFrames:addObject(frame0) animFrames:addObject(frame1) --由容器类实例对象创建一个动画帧对象,设定每0.4秒更新一帧 local animation = CCAnimation:createWithSpriteFrames(animFrames,0.4) --第二个參数是播放的速率,值越小播放越快 --创建一个动画 local animate = CCAnimate:create(animation) --设置精灵循环播放这个动作 spriteDog:runAction(CCRepeatForever:create(animate)) --设置精灵颜色 --spriteDog:setColor(ccc3(0,255,0)) --自己定义一个定时器 local function tick() if spriteDog.isPaused then return end local x,y = spriteDog:getPosition() --获取坐标 if x<origin.x+60 then x = origin.x+visibleSize.width-60 else x = x - 1 end spriteDog:setPositionX(x) end --启动定时器 CCDirector:sharedDirector():getScheduler():scheduleScriptFunc(tick,0,false) return spriteDog end ---------------------------------创建一个可移动的背景层----------------------------------------- local function createMoveLayer() local layerFarm = CCLayer:create() --加入背景 local bg = CCSprite:create("farm.jpg") bg:setPosition(origin.x+visibleSize.width/2+80,origin.y+visibleSize.height/2 -20) layerFarm:addChild(bg) --加入地面田地 for i = 0,3 do for j = 0,1 do local spriteLand = CCSprite:create("land.png") spriteLand:setPosition(200+j*180 - i%2 *90 ,10 + i*95/2) layerFarm:addChild(spriteLand) end end --加入植物(一个4*1的图片) local frameCrop = CCSpriteFrame:create("crop.png",CCRectMake(0,0,105,95)) for i = 0,3 do for j = 0,1 do local spriteCrop = CCSprite:createWithSpriteFrame(frameCrop) spriteCrop:setPosition(10+200+j*180 - i%2*90,30+10+i*95/2) layerFarm:addChild(spriteCrop) end end --------------------触摸事件------------------------------------------- local touchBeginPoint = nil --開始触摸 local function onTouchBegan(x,y) cclog("onTouchBegin:%0.2f,%0.2f",x,y) touchBeginPoint = {x = x,y = y} return true end --触摸移动 local function onTouchMoved(x,y) cclog("onTouchMoved:%0.2f,%0.2f",x,y) if touchBeginPoint then local cx,cy = layerFarm:getPosition() layerFarm:setPosition(cx+x-touchBeginPoint.x,cy+y-touchBeginPoint.y) touchBeginPoint = {x = x,y = y} end end --结束触摸 local function onTouchEnded(x,y) cclog("onTouchEnded:%0.2f,%0.2f",x,y) touchBeginPoint = nil end --推断触摸动作 local function onTouch(eventType,x,y) if eventType == "began" then return onTouchBegan(x,y) elseif eventType == "moved" then return onTouchMoved(x,y) else return onTouchEnded(x,y) end end --调用layerFarm的registerScriptTouchHnadler函数注冊按下的事件对应函数 layerFarm:registerScriptTouchHandler(onTouch) --使layerFarm能够对应屏幕按下的事件 layerFarm:setTouchEnabled(true) return layerFarm end --------------------------创建菜单----------------------------------------------------- local function createLayerMenu() local layerMenu = CCLayer:create() local menuPopup,menuTools,effectID --菜单条、左下角的工具栏button、音效ID --关闭菜单条 local function menuCallBackClosePopup() AudioEngine.stopEffect(effectID) --依据ID号来关闭这个声音 menuPopup:setVisible(false) end --开启菜单条 local function menuCallBackOpenPopup() local effectPath = CCFileUtils:sharedFileUtils():fullPathForFilename("effect1.wav") effectID = AudioEngine.playEffect(effectPath) --播放一个声音然后赋值给某个ID menuPopup:setVisible(true) end --加入一个选择菜单 local menuPopupItem = CCMenuItemImage:create("menu2.png","menu2.png") -- 菜单选项 menuPopupItem:setPosition(0,0)--选项卡的位置 menuPopupItem:registerScriptTapHandler(menuCallBackClosePopup) --点击事件 menuPopup = CCMenu:createWithItem(menuPopupItem) --依据菜单选项创建菜单 menuPopup:setPosition(origin.x+visibleSize.width/2,origin.y+visibleSize.height/2) --设置菜单的位置 menuPopup:setVisible(false) --设置面板的不显示 layerMenu:addChild(menuPopup) --将菜单加入到菜单层中 --加入左下角的工具图标 local menuToolsItem = CCMenuItemImage:create("menu1.png","menu1.png") menuToolsItem:setPosition(0,0) menuToolsItem:registerScriptTapHandler(menuCallBackOpenPopup) menuTools = CCMenu:createWithItem(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 ---------------------------加入背景音乐----------------------------------------------- --循环播放背景音乐 --SimpleAudioEngine:sharedEngine():playBackgroundMusic("background.mp3",true) --或者 local bgMusicPath = CCFileUtils:sharedFileUtils():fullPathForFilename("background.mp3") AudioEngine.playMusic(bgMusicPath,true) -- 取得声音引擎的实例对象并调用其preloadEffect函数将声音文件“effect1.wav”预载入进内存。这里并不播放,预载入是为了在播放时不造成卡顿感。 --SimpleAudioEngine:sharedEngine():preloadEffect("effect1.wav"); --或者 local effectPath = CCFileUtils:sharedFileUtils():fullPathForFilename("effect1.wav") AudioEngine.preloadEffect(effectPath) --加入动画狗 layer:addChild(createDog(),4) --第二个參数是Z(深度),值越大越在前面 --加入可移动的背景层到主场景中 scene:addChild(createMoveLayer()) --加入menu菜单 scene:addChild(createLayerMenu()) --加入自己绘制的图标和文字层 scene:addChild(layer) --执行场景 CCDirector:sharedDirector():runWithScene(scene) end --脚本的入口函数,前面一个參数是调用执行的函数。后面一个是错误处理的函数 xpcall(main, __G__TRACKBACK__)
注意:假设要显示中文。解决方式将lua文件保存为utf8格式