• <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>

            李錦俊(mybios)的blog

            游戲開(kāi)發(fā) C++ Cocos2d-x OpenGL DirectX 數(shù)學(xué) 計(jì)算機(jī)圖形學(xué) SQL Server

              C++博客 :: 首頁(yè) :: 聯(lián)系 :: 聚合  :: 管理
              86 Posts :: 0 Stories :: 370 Comments :: 0 Trackbacks

            公告

            QQ:30743734
            EMain:mybios@qq.com

            常用鏈接

            留言簿(16)

            我參與的團(tuán)隊(duì)

            最新隨筆

            搜索

            •  

            積分與排名

            • 積分 - 370171
            • 排名 - 67

            最新評(píng)論

            閱讀排行榜

            評(píng)論排行榜

            注意:本文純屬是本人從研究魔獸爭(zhēng)霸III地圖編輯器的過(guò)程中的一種猜想,所以,不當(dāng)之處,還請(qǐng)高手指出。謝謝!

              魔獸爭(zhēng)霸III我以前玩得比較多,也聽(tīng)說(shuō)他的地圖編輯器非常牛X,以前也曾經(jīng)想編輯個(gè)地圖出來(lái)。但是,限于當(dāng)時(shí)得水平問(wèn)題,沒(méi)有成功。直到最近在研究如何制作游戲的時(shí)候,打開(kāi)魔獸爭(zhēng)霸III的地圖編輯器來(lái)看,突然有一種擴(kuò)然開(kāi)朗的感覺(jué)!哦!原來(lái)地圖編輯器是這樣出來(lái)的!閑話不多說(shuō)!馬上進(jìn)入正題!

              魔獸爭(zhēng)霸III的地圖編輯器使用了一個(gè)文件來(lái)代表一個(gè)地圖,地圖里包含了什么東西?我無(wú)從得知,但是,從他的編輯器上看,看到編輯器能對(duì)地圖修改的東西,就可以大概猜想到有哪些東西。仔細(xì)看地圖編輯器,看到有那么幾個(gè)模塊:地形編輯器、開(kāi)關(guān)編輯器、聲音編輯器、物體編輯器、戰(zhàn)役編輯器、AI編輯器、物體管理器、輸入管理器。我把我的理解逐一說(shuō)來(lái)。

              1.地形編輯器
                主要用來(lái)編輯地形,例如某個(gè)地方擺放什么地形,什么地方擺放什么物體、英雄、燈光等等東西。那么,這些東西在地圖文件中我想是以數(shù)據(jù)的形式來(lái)存放的,而不是腳本!因?yàn)椋覝y(cè)試過(guò),放了一個(gè)英雄到地圖中,然后導(dǎo)出腳本,但是腳本里沒(méi)有任何關(guān)于這個(gè)英雄的資料!那就證明了是用某種格式保存在地圖文件中。整個(gè)地形都是這么存放。

              2.開(kāi)關(guān)編輯器
                開(kāi)關(guān)編輯器,也就是觸發(fā)事件編輯器。這個(gè)東西在地圖編輯器中比較的高級(jí),人們都說(shuō)魔獸爭(zhēng)霸III的地圖編輯器是萬(wàn)能編輯器,很大的原因就是因?yàn)橛辛诉@個(gè)東西!這個(gè)東西是如何實(shí)現(xiàn)的呢?說(shuō)起來(lái)很簡(jiǎn)單!就是腳本實(shí)現(xiàn)!我分析了一下,一個(gè)觸發(fā)器,分成三個(gè)部分:發(fā)生事件、觸發(fā)條件、執(zhí)行動(dòng)作。那么三個(gè)東西在腳本中和程序中是如何實(shí)現(xiàn)?
                讓我在編輯器中新建一個(gè)觸發(fā)器解釋一下。新建一個(gè)觸發(fā)器,叫做TestTrigger,在這個(gè)觸發(fā)器下新建一個(gè)事件“玩家 - 玩家1 (紅色) leaves the game”,新建一個(gè)條件“TRUE 等于TRUE”,新建一個(gè)動(dòng)作“Do nothing”。然后導(dǎo)出腳本,看看腳本如何:
            //===========================================================================
            // 
            // 只是另外一張魔獸爭(zhēng)霸III的地圖
            // 
            //   Warcraft III map script
            //   Generated by the Warcraft III World Editor
            //   Date: Sat Nov 18 23:35:12 2006
            //   Map Author: 李錦俊
            // 
            //===========================================================================

            //***************************************************************************
            //*
            //*  Global Variables
            //*  全局變量
            //***************************************************************************

            globals
                
            // Generated
                
            //  我們的觸發(fā)器保存成一個(gè)全局變量了!!
                trigger                 gg_trg_TestTrigger         = null
            endglobals

            function InitGlobals takes nothing returns nothing
            endfunction

            //***************************************************************************
            //*
            //*  Triggers
            //*  觸發(fā)器!
            //***************************************************************************

            //===========================================================================
            // Trigger: TestTrigger 我們的觸發(fā)器的觸發(fā)條件
            //===========================================================================
            function Trig_TestTrigger_Conditions takes nothing returns boolean
                
            // 如果true == true ?? 不正是我們?cè)O(shè)置的“TRUE等于TRUE”嗎
                if ( not ( true == true ) ) then
                    
            return false
                endif
                
            return true
            endfunction

            // 我們的觸發(fā)器的執(zhí)行動(dòng)作!!
            function Trig_TestTrigger_Actions takes nothing returns nothing
                
            // DoNothing ?? 不正是我們?cè)O(shè)置的“Do nothing”嗎?
                call DoNothing(  )
            endfunction

            //===========================================================================
            // 初始化我們的觸發(fā)器
            function InitTrig_TestTrigger takes nothing returns nothing
                
            // 創(chuàng)建一個(gè)觸發(fā)器,保存在一個(gè)全局變量里
                set gg_trg_TestTrigger = CreateTrigger(  )
                
                
            // 看這個(gè)英文的函數(shù)名。。我翻譯一下應(yīng)該是“觸發(fā)器:注冊(cè)玩家單位簡(jiǎn)單事件”
                
            // 再看看參數(shù)
                
            // 第一個(gè)參數(shù)是我們的觸發(fā)器的全局變量
                
            // 第二個(gè)參數(shù)是Player(0)啊,不就是我們?cè)O(shè)置的“玩家1”嗎?(語(yǔ)言上從0開(kāi)始,顯示上從1開(kāi)始,習(xí)慣了)。
                
            // 第三個(gè)參數(shù)EVENT_PLAYER_UNIT_DEATH,翻譯一下應(yīng)該是“玩家單位死亡事件”,哈哈!很明顯又是我們?cè)O(shè)置的
                call TriggerRegisterPlayerUnitEventSimple( gg_trg_TestTrigger, Player(0), EVENT_PLAYER_UNIT_DEATH )

                
            // 翻譯:“觸發(fā)器:添加觸發(fā)條件”,然后參數(shù)就是上面那個(gè)觸發(fā)條件的函數(shù),函數(shù)里就是我們?cè)O(shè)置的條件
                call TriggerAddCondition( gg_trg_TestTrigger, Condition( function Trig_TestTrigger_Conditions ) )

                
            // 翻譯:“觸發(fā)器:添加執(zhí)行動(dòng)作”,然后參數(shù)就是上面那個(gè)執(zhí)行動(dòng)作的函數(shù),函數(shù)里就是我們?cè)O(shè)置的動(dòng)作!
                call TriggerAddAction( gg_trg_TestTrigger, function Trig_TestTrigger_Actions )
            endfunction

            //===========================================================================
            // 地圖初始化的時(shí)候都會(huì)調(diào)用這個(gè)函數(shù)初始化所有自定義的觸發(fā)器,當(dāng)然也有我們的觸發(fā)器了。InitTrig_TestTrigger不就是剛才那個(gè)函數(shù)了嗎
            function InitCustomTriggers takes nothing returns nothing
                call InitTrig_TestTrigger(  )
            endfunction

            //***************************************************************************
            //*
            //*  Main Initialization
            //*  main啊!這么熟悉!一定是此腳本文件的入口函數(shù)了!在C++主程序中調(diào)用的!(我暫且認(rèn)為WarCraftIII是用C++寫的了)
            //***************************************************************************

            //===========================================================================
            function main takes nothing returns nothing
                call SetCameraBounds( 
            -3328.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), -3584.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM), 3328.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), 3072.0 - GetCameraMargin(CAMERA_MARGIN_TOP), -3328.0 + GetCameraMargin(CAMERA_MARGIN_LEFT), 3072.0 - GetCameraMargin(CAMERA_MARGIN_TOP), 3328.0 - GetCameraMargin(CAMERA_MARGIN_RIGHT), -3584.0 + GetCameraMargin(CAMERA_MARGIN_BOTTOM) )
                call SetDayNightModels( 
            "Environment\\DNC\\DNCLordaeron\\DNCLordaeronTerrain\\DNCLordaeronTerrain.mdl""Environment\\DNC\\DNCLordaeron\\DNCLordaeronUnit\\DNCLordaeronUnit.mdl" )
                call NewSoundEnvironment( 
            "Default" )
                call SetAmbientDaySound( 
            "LordaeronSummerDay" )
                call SetAmbientNightSound( 
            "LordaeronSummerNight" )
                call SetMapMusic( 
            "Music"true0 )
                call InitBlizzard(  )
                call InitGlobals(  )
                
            // 上面執(zhí)行的這幾個(gè)函數(shù)主要是設(shè)置一些環(huán)境變量,什么攝像頭、日晝幾何模型、背景音樂(lè)等等
                
            // 這個(gè)函數(shù)就是初始化我們的觸發(fā)器啊!
                call InitCustomTriggers(  )
            endfunction

            //***************************************************************************
            //*
            //*  Map Configuration
            //*  地圖配置,估計(jì)也是在C++主程序中調(diào)用的!
            //***************************************************************************

            function config takes nothing returns nothing
                call SetMapName( 
            "只是另外一張魔獸爭(zhēng)霸III的地圖" )
                call SetMapDescription( 
            "沒(méi)有描述" )
                call SetPlayers( 
            1 )
                call SetTeams( 
            1 )
                call SetGamePlacement( MAP_PLACEMENT_USE_MAP_SETTINGS )

                call DefineStartLocation( 
            0-1409.3219.2 )

                
            // Player setup
                call InitCustomPlayerSlots(  )
                call SetPlayerSlotAvailable( Player(
            0), MAP_CONTROL_USER )
                call InitGenericPlayerSlots(  )
            endfunction

              我加的注釋里已經(jīng)寫得很清楚了,很明顯我們?cè)诘貓D編輯器里面設(shè)置的所有觸發(fā)器的東西,都會(huì)以一種腳本的形式生成,然后程序在根據(jù)地圖數(shù)據(jù)初始化地圖之后調(diào)用這個(gè)腳本的main函數(shù)和config函數(shù)。在游戲進(jìn)行過(guò)程中,TriggerRegister開(kāi)頭的函數(shù)注冊(cè)了一些事件開(kāi)端,簡(jiǎn)單的實(shí)現(xiàn)就是維護(hù)一個(gè)列表而已。然后游戲進(jìn)行到這個(gè)事件的時(shí)候(例如剛才的例子里是TriggerRegisterPlayerUnitEventSimple,則玩家單位發(fā)生一些簡(jiǎn)單事件的時(shí)候就會(huì)執(zhí)行),就遍歷這個(gè)列表的每一個(gè)元素調(diào)用他們用TriggerAddCondition注冊(cè)的條件,如果為true,則執(zhí)行TriggerAddAction函數(shù)的內(nèi)容!觸發(fā)器的實(shí)現(xiàn)原理基本上就是這樣了!當(dāng)然,真正實(shí)現(xiàn)起來(lái)還是有很多東西要做的,例如要有很多很多的函數(shù)要綁定到腳本引擎中!

              3.聲音編輯器
                這個(gè)我沒(méi)研究過(guò)啊,待續(xù)....

              4.物體編輯器
                里面就是所有單位、建筑物、物品(簡(jiǎn)稱Items吧,中文翻譯過(guò)來(lái)就變味了,呵呵!)的一些屬性設(shè)置,這些屬性都是以數(shù)據(jù)的形式保存在地圖中的,程序運(yùn)行的時(shí)候就以這些數(shù)據(jù)來(lái)基礎(chǔ)運(yùn)行起來(lái),例如某某英雄聲明值是多少云云....

              5.戰(zhàn)役編輯器
                沒(méi)搞過(guò),不多作評(píng)論

              6.AI編輯器
                我只知道AI不是腳本引擎實(shí)現(xiàn)的!他只是一些數(shù)據(jù),至于為何不用腳本來(lái)實(shí)現(xiàn)?我想應(yīng)該還是執(zhí)行效率問(wèn)題吧!(猜想而已...)

              7.物體管理器
                用來(lái)管理場(chǎng)景上出現(xiàn)的物體,也是數(shù)據(jù)保存。

              8.輸入管理器
                實(shí)現(xiàn)一個(gè)簡(jiǎn)單的單文件系統(tǒng),就是說(shuō)在一個(gè)地圖文件里包含多個(gè)附件進(jìn)去,例如:模型、貼圖等等。那么就可以實(shí)現(xiàn)一個(gè)自定義的東西了(例如自定義一個(gè)以我的形象做出來(lái)的英雄!哈哈!)。然后程序可以直接調(diào)用這個(gè)模型。

              另外,說(shuō)說(shuō)C++程序中應(yīng)該如何導(dǎo)入綁定函數(shù)到腳本中,綁定的方法很多文章都有說(shuō),我的BLOG上LUA那部分也有幾篇這樣的文章。我現(xiàn)在要說(shuō)的是應(yīng)該綁定什么函數(shù)進(jìn)去腳本引擎中。我覺(jué)得,腳本引擎主要是實(shí)現(xiàn)一些速度要求不高,但是邏輯性又極強(qiáng)的代碼。那么,相反,對(duì)速度要求高,邏輯性比較固定的,就不應(yīng)該寫到腳本引擎中。
              舉幾個(gè)應(yīng)該在腳本中實(shí)現(xiàn)的例子:注冊(cè)觸發(fā)器、觸發(fā)器的執(zhí)行條件、觸發(fā)器執(zhí)行的事件、地圖初始化之后應(yīng)該設(shè)置的信息(例如攝像機(jī)的位置,Load一些東西),這些東西都是邏輯性比較強(qiáng),也就是說(shuō)變化是比較大的,如果用數(shù)據(jù)來(lái)驅(qū)動(dòng),估計(jì)很難驅(qū)動(dòng)得了(就好像,N個(gè)條件組合,還有邏輯判斷的東西,如何能用數(shù)據(jù)來(lái)表示?例如:3D中的可編程流水線(Shader腳本驅(qū)動(dòng))就有很多固定流水線(渲染狀態(tài)數(shù)據(jù)驅(qū)動(dòng))無(wú)法實(shí)現(xiàn)的)。
              舉幾個(gè)不應(yīng)該在腳本中實(shí)現(xiàn)的例子:尋路算法、讀取文件等等需要比較多系統(tǒng)資源的操作。AI,是一個(gè)特例,他執(zhí)行速度要求比較高,但是他的邏輯性又比較強(qiáng)。暴雪公司的選擇是速度,那么他們就需要作一個(gè)比較龐大的數(shù)據(jù)來(lái)驅(qū)動(dòng)這些AI(這里編程估計(jì)比較復(fù)雜了)。我還沒(méi)學(xué)過(guò)AI的算法呢,只知道復(fù)雜。不多作評(píng)論了,還請(qǐng)高手們給指點(diǎn)指點(diǎn)。
              舉了幾個(gè)比較有代表意義的例子。簡(jiǎn)單的說(shuō),就是應(yīng)該把一些固定功能的函數(shù)盡量用C++來(lái)實(shí)現(xiàn),然后綁定到腳本引擎中,然后由腳本引擎來(lái)實(shí)現(xiàn)相應(yīng)的邏輯。

              好了,大的東西基本上都說(shuō)完了。好像也沒(méi)說(shuō)什么,主要就是分析了腳本的實(shí)現(xiàn)了。可能說(shuō)得不明白啊,大家回帖討論一下。

              PS:第一次寫這種文章,寫得不好請(qǐng)見(jiàn)諒!

            如果本文對(duì)你的開(kāi)發(fā)有所幫助,并且你手頭恰好有零錢。

            不如打賞我一杯咖啡,鼓勵(lì)我繼續(xù)分享優(yōu)秀的文章。




            posted on 2006-11-19 00:20 李錦俊(mybios) 閱讀(8923) 評(píng)論(9)  編輯 收藏 引用 所屬分類: C++LUA

            Feedback

            # re: 【原創(chuàng)】魔獸爭(zhēng)霸III 地圖編輯器原理(關(guān)鍵是腳本) 2006-11-28 16:16 沒(méi)仔細(xì)看
            摟主繼續(xù)努力  回復(fù)  更多評(píng)論
              

            # re: 【原創(chuàng)】魔獸爭(zhēng)霸III 地圖編輯器原理(關(guān)鍵是腳本) 2006-11-28 22:28 李錦俊
            謝謝支持  回復(fù)  更多評(píng)論
              

            # 我最近也在研究魔獸地圖編輯器的腳本實(shí)現(xiàn) 2007-07-23 11:10 goodboy
            受益匪淺,希望樓主多發(fā)布一些相關(guān)的文章。  回復(fù)  更多評(píng)論
              

            # re: 【原創(chuàng)】魔獸爭(zhēng)霸III 地圖編輯器原理(關(guān)鍵是腳本)[未登錄](méi) 2007-08-08 09:21 初學(xué)者
            殺死敵人單位(非中立敵對(duì))后怎樣能獲得金錢?(請(qǐng)各位幫忙)  回復(fù)  更多評(píng)論
              

            # re: 【原創(chuàng)】魔獸爭(zhēng)霸III 地圖編輯器原理(關(guān)鍵是腳本) 2007-08-20 08:24 jj
            不錯(cuò)不錯(cuò)!!o稀飯^_^  回復(fù)  更多評(píng)論
              

            # re: 【原創(chuàng)】魔獸爭(zhēng)霸III 地圖編輯器原理(關(guān)鍵是腳本)[未登錄](méi) 2008-02-10 17:10 QQ
            怎樣用魔獸地圖編輯器把一個(gè)不是英雄的單位變成英雄 說(shuō)說(shuō)吧  回復(fù)  更多評(píng)論
              

            # re: 【原創(chuàng)】魔獸爭(zhēng)霸III 地圖編輯器原理(關(guān)鍵是腳本) 2008-02-14 11:27 #
            這個(gè)把單位變英雄我會(huì),只要調(diào)模形,聲音,圖標(biāo)和武器聲音。單位就能變英雄了。  回復(fù)  更多評(píng)論
              

            # re: 【原創(chuàng)】魔獸爭(zhēng)霸III 地圖編輯器原理(關(guān)鍵是腳本) 2008-02-14 11:29 接上
            補(bǔ)充下:改的單位要是英雄才行!  回復(fù)  更多評(píng)論
              

            # re: 【原創(chuàng)】魔獸爭(zhēng)霸III 地圖編輯器原理(關(guān)鍵是腳本) 2009-03-03 10:21 peerincle
            加油啊~~
            期待著你的最新研究成果~  回復(fù)  更多評(píng)論
              

            国产精品青草久久久久福利99 | 麻豆成人久久精品二区三区免费| 狠狠狠色丁香婷婷综合久久五月 | 久久久黄色大片| 久久精品亚洲福利| 99久久精品国产一区二区| 欧美精品一本久久男人的天堂| 久久久久久九九99精品| 久久综合亚洲欧美成人| 亚洲国产精品无码久久一区二区 | 色天使久久综合网天天| 久久午夜综合久久| 亚洲国产精品综合久久网络| 欧美伊人久久大香线蕉综合69| 久久久久黑人强伦姧人妻| 久久久无码精品午夜| 伊人精品久久久久7777| 2021久久精品免费观看| 少妇久久久久久久久久| 久久99精品久久久久久动态图| 精品久久久久久久| 国产成人久久精品二区三区| 久久久久亚洲AV无码专区桃色 | 国产欧美久久久精品影院| 久久精品免费全国观看国产| 18岁日韩内射颜射午夜久久成人| 国产亚洲欧美精品久久久| 亚洲国产天堂久久综合网站| 无码精品久久一区二区三区| 久久久久久久精品妇女99| 久久精品国产亚洲av水果派| 91亚洲国产成人久久精品网址| 一级女性全黄久久生活片免费 | 久久久久久亚洲精品无码| 国产精品久久久久久久久久影院| 久久国产热精品波多野结衣AV| av国内精品久久久久影院| 日本精品一区二区久久久| 亚洲精品白浆高清久久久久久| 久久国产免费观看精品| 久久久无码精品亚洲日韩京东传媒|