【COCOS2DX-LUA 脚本开发之一】在Cocos2dX游戏中使用Lua脚本进行游戏开发(基础篇)并介绍脚本在游戏中详细用途!
本站文章均为李华明Himi原创,转载务必在明显处注明:
转载自【黑米GameDev街区】 原文链接: http://www.himigame.com/iphone-cocos2dx/681.html
☞ 点击订阅 ☜ 本博客最新动态!及时将最新博文通知您!
对于游戏公司而言,采用游戏脚本lua、python等进行开发也很常见,但是很多童鞋对脚本并没有很熟悉的概念,本篇则向大家简单介绍脚本的用途以及在Cocos2dx基础用法;
Lua
和python这些详细介绍的话,请不太熟悉的童鞋自行百度百科哈,那么对于lua和python则是两个常用的脚本语言,lua相对于python而
言,lua比较轻量级罢了,而其他区别就不多说了,但是为什么本章要讲解lua的原因则有两点,首先第一:cocos2dx
游戏引擎内嵌lua,第二点:自从“令人愤怒的小鸟”火起来之后,国内很多都偏向于使用lua了=。 =
那么对于脚本的用途这里也大概说两点:
1. 脚本在手游中是类于“大脑”的功能,所有游戏相关的逻辑代码一般都放在脚本中,而客户端(前台)的代码都则属于“肢体”,也可以说是“播放器”,作用只是用户展示出UI界面的功能;那么脚本的作用那么不仅仅如此,比如地图数据等都可以利用脚本使用;
2.
脚本在手机网游中的作用尤为重要,比如一款网游“Himi”没有使用脚本,如果“Himi”1.0版本在发布后突然发现客户端出现一些棘手的bug需要修
复,那么你想修改那么也要等待再次更新客户端重新提交发布才可以解决,这样会流失一大批用户,而且游戏每次更新也会流失掉部分用户,这是肯定的;但是如果
“Himi”这款网游使用脚本的话,那么解决此类问题很eazy,比如我在“Himi”游戏中的逻辑代码都放在脚本a.lua
中,那么如果a.lua逻辑中哪里出现了问题,我们直接可以将修复后的a.lua脚本更新至服务器中,因为一般脚本都会定义version号,比如
a.lua有bug的version:1.0,那么我们修复后的a.lua
version改成1.1,当用户每次启动游戏的时候,客户端都会将脚本的version与服务器脚本version做对比,当server端脚本
version号比当前脚本新,那么自动下载并覆盖当前脚本,OK,问题解决;不仅仅如此,比如游戏中做个活动呀,换个图片呀等等都可以即使更新,而不是
每次修改前端代码都要重新发布新的游戏版本,造成一些损失!
OK,
不再多说了,下面我们来介绍在Cocos2dx中对于lua脚本的一些简单使用,首先我们通过新建一个Cocos2dx-lua模版项目,默认此模版中有
个示例,童鞋们可以直接运行项目看效果,但是大家可能会郁闷在class中完全找不到任何相关的代码?!?那就对了,因为所有逻辑代码都放置在了lua脚
本中,项目启动后直接解析的一个名称为hello.lua的脚本!
打
开项目的Resources仔细找下,有没有发现有 hello.lua 合hello2.lua两个脚本文件?!OK,就是这里拉。
那么对于cocos2dx_lua
demo的例子脚本我这里不多说比较容易,但是肯定不太熟悉的童鞋比较疑惑,那么Himi这里重新整理了一份简单的示例脚本代码,大家可以直接将如下代码
直接复制到hello.lua中看效果;代码如下:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
|
require "hello2" -- 包含hello2这个脚本-- 注视语句 -- 基本上调用的cocos2dx函数和类的时候就是以cocos2d.*这样子来用-- 注意2:function 关键字定义函数,end结束函数-- 打印cocos2d.CCLuaLog("脚本hello开始运行... " .. myadd(3, 5))-- 创建一个ScenesceneForWorld = cocos2d.CCScene:node()-- 创建一个LayerlayerForWorld = cocos2d.CCLayer:node()sceneForWorld:addChild(layerForWorld)-- 创建一个精灵spriteForWorld = cocos2d.CCSprite:spriteWithFile("Icon.png")layerForWorld:addChild(spriteForWorld)-- 获取屏幕宽高screenSize=cocos2d.CCDirector:sharedDirector():getWinSize()-- 设置精灵坐标spriteForWorld:setPosition(cocos2d.CCPoint(screenSize.width*0.5,screenSize.height*0.5))-- 设置精灵缩放2倍spriteForWorld:setScale(2)-- 添加一个CCLabelTTF (!!!!!!备注!!!!!!)myLableTTF =cocos2d.CCLabelTTF:labelWithString("Himi- Lua 基础","Helvetica-Bold",24)myLableTTF:setPosition(cocos2d.CCPoint(screenSize.width*0.5,screenSize.height*0.5+100))sceneForWorld:addChild(myLableTTF)-- 添加一个CCLabelTTFmyLableTTF2 =cocos2d.CCLabelTTF:labelWithString("上面icon跟随用户触屏位置","Helvetica-Bold",24)myLableTTF2:setPosition(cocos2d.CCPoint(screenSize.width*0.5,screenSize.height*0.5-100))sceneForWorld:addChild(myLableTTF2)-- @@@@@@@@@@触摸事件--开启触摸layerForWorld:setIsTouchEnabled(true)-- 注册触摸事件layerForWorld.__CCTouchDelegate__:registerScriptTouchHandler(cocos2d.CCTOUCHBEGAN, "btnTouchBegin")layerForWorld.__CCTouchDelegate__:registerScriptTouchHandler(cocos2d.CCTOUCHMOVED, "btnTouchMove")layerForWorld.__CCTouchDelegate__:registerScriptTouchHandler(cocos2d.CCTOUCHENDED, "btnTouchEnd")-- touch handerspointBegin = nilfunction btnTouchBegin(e) cocos2d.CCLuaLog("btnTouchBegin") local v = e[1] local pointMove = v:locationInView(v:view()) pointMove = cocos2d.CCDirector:sharedDirector():convertToGL(pointMove) spriteForWorld:setPosition(cocos2d.CCPoint(pointMove.x,pointMove.y))endfunction btnTouchMove(e) cocos2d.CCLuaLog("btnTouchMove") local v = e[1] local pointMove = v:locationInView(v:view()) pointMove = cocos2d.CCDirector:sharedDirector():convertToGL(pointMove) spriteForWorld:setPosition(cocos2d.CCPoint(pointMove.x,pointMove.y))endfunction btnTouchEnd(e) cocos2d.CCLuaLog("btnTouchEnd")end-- @@@@@@@@@@触摸结束--动态小狗winSize = cocos2d.CCDirector:sharedDirector():getWinSize()FrameWidth = 105FrameHeight = 95textureDog = cocos2d.CCTextureCache:sharedTextureCache():addImage("dog.png")frame0 = cocos2d.CCSpriteFrame:frameWithTexture(textureDog, cocos2d.CCRectMake(0, 0, FrameWidth, FrameHeight))frame1 = cocos2d.CCSpriteFrame:frameWithTexture(textureDog, cocos2d.CCRectMake(FrameWidth*1, 0, FrameWidth, FrameHeight))spriteDog = cocos2d.CCSprite:spriteWithSpriteFrame(frame0)spriteDog:setPosition(cocos2d.CCPoint(100, winSize.height/4*3))layerForWorld:addChild(spriteDog)animFrames = cocos2d.CCMutableArray_CCSpriteFrame__:new(2)animFrames:addObject(frame0)animFrames:addObject(frame1)animation = cocos2d.CCAnimation:animationWithFrames(animFrames, 0.5)animate = cocos2d.CCAnimate:actionWithAnimation(animation, false);spriteDog:runAction(cocos2d.CCRepeatForever:actionWithAction(animate))--自定义函数function prForHimi() cocos2d.CCLuaLog("reFresh function") --取消选择器 --cocos2d.CCScheduler:sharedScheduler():unscheduleScriptFunc("prForHimi")end--使用选择器进行函数更新--cocos2d.CCScheduler:sharedScheduler():scheduleScriptFunc("prForHimi", 1, false)--循环语句for i=0,4,1 do for j=0,4,2 do cocos2d.CCLuaLog("for loop",i) endend-- 避免内存泄漏collectgarbage( "setpause", 100)collectgarbage( "setstepmul", 5000)-- 播放背景音乐--CocosDenshion.SimpleAudioEngine:sharedEngine():playBackgroundMusic("background.mp3", true)-- 播放音效--CocosDenshion.SimpleAudioEngine:sharedEngine():preloadEffect("effect1.wav")-- run整个scenecocos2d.CCDirector:sharedDirector():runWithScene(sceneForWorld)cocos2d.CCLuaLog("脚本hello正常执行结束... " .. myadd(3, 5)) |
运行效果图如下:
对于Himi上面给出的自己修改后的代码注视写的狠清楚了 =。 = 所以不多加赘述,但是Himi这里需要还要详细说一点;
脚本lua等一般都示通过中间层(解析)进行与前端代码(Cocos2dX封装的引擎类库)交互,所以很多方法名称可能发生了改变,那么对于不太熟悉的童鞋我们如何下手?
OK,
如刚才的代码中有个“备注”,不知道细心童鞋们看到没有,这里是添加了一个CCLabelTTF
,假如我们不知道它的构造函数是否有修改,或者说参数忘记都是什么了,那么请打开你项目的libs文件夹,然后打开lua文件夹,继续打开
cocos2dx_support文件夹找到
LuaCocos2d.cpp文件打开,(注意这个文件代码很多,打开较慢)然后你会看到很多方法的定义与实现!
那么假如我们来找 CCLabelTTF的构造方法,那么搜一下如下语句:
|
1
|
tolua_beginmodule(tolua_S,"CCLabelTTF"); |
你将发现此类下方一大批类似的代码:

没错这里就是此类的所有是lua-cocos2dx之间的转换函数定义,比如常用的CCLabelTTF构造函数:
|
1
|
tolua_function(tolua_S,"labelWithString",tolua_Cocos2d_cocos2d_CCLabelTTF_labelWithString01); |
此函数第一参数大家不用理会,第二个参数表示我们使用cocos2d/x时调用的函数名称,后面则是lua-cocos2dx之间的转换函数实现代码,大家可以继续搜索第三个参数或者按住command然后点击第三个参数找到其函数实现代码:
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
|
/* method: labelWithString of class cocos2d::CCLabelTTF */#ifndef TOLUA_DISABLE_tolua_Cocos2d_cocos2d_CCLabelTTF_labelWithString01static int tolua_Cocos2d_cocos2d_CCLabelTTF_labelWithString01(lua_State* tolua_S){ tolua_Error tolua_err; if ( !tolua_isusertable(tolua_S,1,"cocos2d::CCLabelTTF",0,&tolua_err) || !tolua_isstring(tolua_S,2,0,&tolua_err) || !tolua_isstring(tolua_S,3,0,&tolua_err) || !tolua_isnumber(tolua_S,4,0,&tolua_err) || !tolua_isnoobj(tolua_S,5,&tolua_err) ) goto tolua_lerror; else { const char* label = ((const char*) tolua_tostring(tolua_S,2,0)); const char* fontName = ((const char*) tolua_tostring(tolua_S,3,0)); float fontSize = ((float) tolua_tonumber(tolua_S,4,0)); { cocos2d::CCLabelTTF* tolua_ret = (cocos2d::CCLabelTTF*) cocos2d::CCLabelTTF::labelWithString(label,fontName,fontSize); tolua_pushusertype(tolua_S,(void*)tolua_ret,"cocos2d::CCLabelTTF"); } } return 1;tolua_lerror: return tolua_Cocos2d_cocos2d_CCLabelTTF_labelWithString00(tolua_S);}#endif //#ifndef TOLUA_DISABLE |
在这里看到此函数转换过程,并可以很清楚看到:
|
1
|
cocos2d::CCLabelTTF* tolua_ret = (cocos2d::CCLabelTTF*) cocos2d::CCLabelTTF::labelWithString(label,fontName,fontSize); |
到这里大家会很清楚需要的参数都是哪些,如果还不清楚,继续按住Command然后点击labelWithString进入cocos2dx引擎代码 CCLabelTTF.cpp中的此函数实现啦!
可能这部分有童鞋看得比较迷茫 =。 = 那么Himi来简化这些复杂来说:
解析lua脚本中的一句代码->通过解析层代码->将其转换并转到前端代码进行使用
那么当然此过程也可逆:
前端代码->通过解析层代码->使用lua脚本中东东
这里由于Himi对cocos2dx 中的lua还没有深入了解,所以不知是否过程可逆;
OK,基本就是这样,对于脚本的熟悉,主要还是在公司进行使用然后慢慢熟悉和熟练掌握的,本章主要需要童鞋们记住的是脚本的概念和作用!
【COCOS2DX-LUA 脚本开发之一】在Cocos2dX游戏中使用Lua脚本进行游戏开发(基础篇)并介绍脚本在游戏中详细用途!的更多相关文章
- cocos2dx基础篇(3) 常用重要类
---------------------------------------- 入口类main.cpp 主要控制类AppDelegate.cpp -------------------------- ...
- 前端开发工程师 - 02.JavaScript程序设计 - 第1章.基础篇
第1章--基础篇 JS介绍 html 网页的内容:css 网页的样式:javascript 网页的行为 i.e. hello world <!DOCTYPE html> <html& ...
- 怎样在Cocos2d-x中使用Lua脚本
版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u013321328/article/details/25699545 笔者使用的是Cocos2d-x ...
- cocos2d-x 3.0 在C++中调用lua函数
代码用的是<cocos2d-x 3.0 在lua中调用自定义类>中的代码. 在上篇的基础上进行扩充. 写lua函数 local function process_packet(user_d ...
- 在cocos2d-x中使用LUA
在cocos2d-x中使用LUA 1.注冊LUA脚本引擎 CCLuaEngine* pEngine = CCLuaEngine::defaultEngine(); CCScriptEngineMana ...
- 【游戏开发】Excel表格批量转换成lua的转表工具
一.简介 在上篇博客<[游戏开发]Excel表格批量转换成CSV的小工具> 中,我们介绍了如何将策划提供的Excel表格转换为轻便的CSV文件供开发人员使用.实际在Unity开发中,很多游 ...
- [整理]Unity3D游戏开发之Lua
原文1:[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(上) 各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我地博客地址是blog.csdn.net/qinyuanpei.如果 ...
- cocos2dx基础篇(1) Cocos2D-X项目创建
已经入行工作半年多时间了,以前都是把这些东西记录在有道云上面的,现在抽出些时间把以前的笔记腾过来. 具体的环境配置就不用说了,因为现在已经是2018年,只需要下载对应版本解压后就能使用,不用再像多年前 ...
- lua学习:游戏中的Lua
lua作为一种脚本语言,可以快速地开发游戏的原型.提高游戏的开发效率. 在游戏中,lua可以用来完成下面这些工作: ●编辑游戏的用户界面 ●定义.存储和管理基础游戏数据 ●管理实时游戏事件 ●创建和维 ...
随机推荐
- Python的并发并行[0] -> 基本概念
基本概念 / Basic Concept 快速跳转 进程 / Process 线程 / Thread 协程 / Coroutine 全局解释器锁 / Global Interpreter Lock ...
- 干净卸载mysql
一.在控制面板中卸载mysql软件 二.卸载过后删除C:\Program Files (x86)\MySQL该目录下剩余了所有文件,把mysql文件夹也删了 三.windows+R运行“regedit ...
- hiho一下第130周 后缀自动机二·重复旋律7
后缀自动机四·重复旋律7 时间限制:15000ms 单点时限:3000ms 内存限制:512MB 描述 小Hi平时的一大兴趣爱好就是演奏钢琴.我们知道一段音乐旋律可以被表示为一段数构成的数列. 神奇的 ...
- SQL常用语句|创建表,设置主键......
新建表 create table [表名]([自动编号字段] int IDENTITY (1,1) PRIMARY KEY ,[字段1] nVarChar(50) default \'默认值\' nu ...
- [POJ 2373][BZOJ 1986] Dividing the Path
Link: POJ 2373 传送门 Solution: 一开始想错方向的一道简单$dp$,不应该啊…… 我一开始的想法是以$cows' ranges$的节点为状态来$dp$ 但明显一个灌溉的区间的两 ...
- Lazy Scheduler:我的轻量级任务调度框架
一.背景 工作中经常涉及任务调度,一直都是采用while(true) => if hitted DO => Thread.Sleep(interval)的模式.但是最近实在是感觉这种实现模 ...
- C#如何把日期转成YYYYMMDDHHMMSSFFF的精确到毫秒的格式?
C#如何把YYYY-MM-DD HH:MM:SS格式的日期转成YYYYMMDDHHMMSS的格式? 方法一:string src= (new DataTime()).ToString(); str ...
- 利用osql/ocmd批处理批量执行sql文件
原文:利用osql/ocmd批处理批量执行sql文件 上周在测试环境建了几十张表,保存了.sql文件,准备在正式环境重建的时候懒得一个个打开建了,做一在网上搜寻了一下,果然有简单点的方法. 利用osq ...
- UBIFS - UBI File-System
参考:http://www.linux-mtd.infradead.org/doc/ubifs.html#L_raw_vs_ftl UBIFS - UBI File-System Table of c ...
- java的几个特性
前言 本文主要介绍java语言的三个特性:类型协变和逆变,动态代理和静态代理,注解. 协变和逆变 借用Treant的博文,逆变与协变用来描述类型转换(type transformation)后的继承关 ...