分类: 【Cocos2dx Lua 脚本开发 】 2012-04-16 10:08 30803人阅读 评论(18) 收藏 举报

本站文章均为李华明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))
 
-- 创建一个Scene
sceneForWorld = cocos2d.CCScene:node()
 
-- 创建一个Layer
layerForWorld = 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)
-- 添加一个CCLabelTTF
myLableTTF2 =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 handers
pointBegin = nil
 
function 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))
end
 
function 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))
end
 
function btnTouchEnd(e)
    cocos2d.CCLuaLog("btnTouchEnd")
end
 
--   @@@@@@@@@@触摸结束
 
--动态小狗
winSize = cocos2d.CCDirector:sharedDirector():getWinSize()
FrameWidth = 105
FrameHeight = 95
 
textureDog = 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)
    end
end
 
-- 避免内存泄漏
collectgarbage( "setpause", 100)
collectgarbage( "setstepmul", 5000)
 
-- 播放背景音乐
--CocosDenshion.SimpleAudioEngine:sharedEngine():playBackgroundMusic("background.mp3", true)
-- 播放音效
--CocosDenshion.SimpleAudioEngine:sharedEngine():preloadEffect("effect1.wav")
 
-- run整个scene
cocos2d.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_labelWithString01
static 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脚本进行游戏开发(基础篇)并介绍脚本在游戏中详细用途!的更多相关文章

  1. cocos2dx基础篇(3) 常用重要类

    ---------------------------------------- 入口类main.cpp 主要控制类AppDelegate.cpp -------------------------- ...

  2. 前端开发工程师 - 02.JavaScript程序设计 - 第1章.基础篇

    第1章--基础篇 JS介绍 html 网页的内容:css 网页的样式:javascript 网页的行为 i.e. hello world <!DOCTYPE html> <html& ...

  3. 怎样在Cocos2d-x中使用Lua脚本

    版权声明:本文为博主原创文章.未经博主同意不得转载. https://blog.csdn.net/u013321328/article/details/25699545 笔者使用的是Cocos2d-x ...

  4. cocos2d-x 3.0 在C++中调用lua函数

    代码用的是<cocos2d-x 3.0 在lua中调用自定义类>中的代码. 在上篇的基础上进行扩充. 写lua函数 local function process_packet(user_d ...

  5. 在cocos2d-x中使用LUA

    在cocos2d-x中使用LUA 1.注冊LUA脚本引擎 CCLuaEngine* pEngine = CCLuaEngine::defaultEngine(); CCScriptEngineMana ...

  6. 【游戏开发】Excel表格批量转换成lua的转表工具

    一.简介 在上篇博客<[游戏开发]Excel表格批量转换成CSV的小工具> 中,我们介绍了如何将策划提供的Excel表格转换为轻便的CSV文件供开发人员使用.实际在Unity开发中,很多游 ...

  7. [整理]Unity3D游戏开发之Lua

    原文1:[Unity3D]Unity3D游戏开发之Lua与游戏的不解之缘(上) 各位朋友,大家好,我是秦元培,欢迎大家关注我的博客,我地博客地址是blog.csdn.net/qinyuanpei.如果 ...

  8. cocos2dx基础篇(1) Cocos2D-X项目创建

    已经入行工作半年多时间了,以前都是把这些东西记录在有道云上面的,现在抽出些时间把以前的笔记腾过来. 具体的环境配置就不用说了,因为现在已经是2018年,只需要下载对应版本解压后就能使用,不用再像多年前 ...

  9. lua学习:游戏中的Lua

    lua作为一种脚本语言,可以快速地开发游戏的原型.提高游戏的开发效率. 在游戏中,lua可以用来完成下面这些工作: ●编辑游戏的用户界面 ●定义.存储和管理基础游戏数据 ●管理实时游戏事件 ●创建和维 ...

随机推荐

  1. #424 Div2 C

    #424 Div2 C 题意 给出 k 个分数,初始分数未知,按顺序把这 k 个分数加到初始分数上,已知 n 个加入分数后的结果(无序),问初始分数有多少种可能. 分析 也就是说这 n 个结果,它们之 ...

  2. NIO入门之BIO

    传统BIO编程 网络编程的基本模型是Client-Server模型,也就是两个进程之间相互通信,其中服务端提供位置信息(绑定的IP地址和监听端口),客户端通过连接操作向服务端监听的端口发起连接请求,通 ...

  3. InputSplit—>RecordReder—>map(key,value,context)的过程解析

    上图首先描述了在TaskTracker端Task(MapTask.ReduceTask)的执行过程,MapTask(org.apache.hadoop.mapred)首先被TaskRunner调用,然 ...

  4. Tiny 6410的Linux学习总结!

    1.Tiny6410的Linux系统修改IP地址:         vi /etc/eth0-setting 2.Ubuntu14.04自动以root身份登录系统:  /etc/lightdm/lig ...

  5. 工作组模式下专用队列(Private Queue)如何引用远程队列路径

    查了N久资料,包括MSDN的官方文档,对于同一工作组下,不同机器之间如何利用Private Queue(专用队列)来发送/接收消息,关于Path的引用一说,无非都是MachineName\privat ...

  6. DNX 概览

    来源https://docs.asp.net/en/latest/dnx/overview.html .NET Execution Environment是什么 .NET Execution Envi ...

  7. 设计模式之建造者模式(php实现)

    github地址:https://github.com/ZQCard/design_pattern/** * 建造者模式 * 将一个复杂对象的建造与调用者分离.调用者只需要给出指定对象的类型和内容,建 ...

  8. Eclipse下的java工程目录

    对新手来讲,一个Java工程内部的多个文件夹经常会让大家困惑.更可恶的是莫名其妙的路径问题,在Eclipse编写Java程序中,出现频率最高的错误很可能就是路径问题. 这些问题原因其实都是一个,就是关 ...

  9. 利用Python,四步掌握机器学习

    为了理解和应用机器学习技术,你需要学习 Python 或者 R.这两者都是与 C.Java.PHP 相类似的编程语言.但是,因为 Python 与 R 都比较年轻,而且更加“远离”CPU,所以它们显得 ...

  10. iframe.contentWindow 属性:关于contentWindow和contentDocument区分

    定义和用法 contentDocument 属性能够以 HTML 对象来返回 iframe 中的文档,可以通过所有标准的 DOM 方法来处理被返回的对象. 语法:frameObject.content ...