亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

cocos2dx游戲怎么使用腳本?

cocos2dx游戲怎么使用腳本?

ibeautiful 2018-09-03 14:10:15
cocos2dx游戲怎么使用腳本
查看完整描述

1 回答

?
桃花長相依

TA貢獻1860條經驗 獲得超8個贊

對于游戲公司而言,采用游戲腳本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 (?。。。。?!備注!?。。。。。?br/>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,基本就是這樣,對于腳本的熟悉,主要還是在公司進行使用然后慢慢熟悉和熟練掌握的,本章主要需要童鞋們記住的是腳本的概念和作用!

查看完整回答
反對 回復 2018-09-20
  • 1 回答
  • 0 關注
  • 1261 瀏覽

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號