搜索
热搜: 活动 交友 discuz
查看: 3389|回复: 21

[代码] DOTA2 API实例解析第一节:CDOTA_MapTree(树木)

[复制链接]

96

主题

1874

帖子

2493

积分

Lv:6 苍空龙法师

UID
9458
金币
2486
精华
0
节操
-35

隐修议员教程大师开拓者黑科技玩的6

发表于 2016-1-11 06:42:12 | 显示全部楼层 |阅读模式

前方高能预警!非战斗人员请尽快登录!

您需要 登录 才可以下载或查看,没有帐号?注册账号

x
在此先做下自我介绍:
我的百度贴吧 ID:patatochips,是一个魔兽爱好者,更是一个DOTA爱好者。同时也是魔兽地图编辑器爱好者和计算机程序爱好者。业余时间制作了很多魔兽争霸自定义地图,但是基本没有公开发表。
出于个人的怀旧清洁,我现在才迟迟地追上DOTA2。
这里DOTA2创意工坊的出现给了我很大的触动,这真是我在魔兽自定义地图中苦苦追寻的东西。DOTA2给我们提供了这么好的平台,许多工具,代码开源,收入分成,这一切都意味着DOTA2的自定义地图一定能取得比魔兽争霸自定义地图更大的成功!
因此,我踏上了研究DOTA2 创意工坊工具和源码的征程!

与我当初学习魔兽争霸世界编辑器WE和JASS脚本一样,我希望把自己的高效的学习方法和研究成果与众多相同的爱好者一同分享!

制作DOTA2自定义地图需要掌握的东西基本和魔兽争霸编辑器差不多。但是对于新手来说内容庞杂而且难以入手。我们就在适当的时候慢慢分解开来学习。


我目前主要研究DOTA2 API这块,因为地图编辑器其实比较简单。最困难和最体现地图水平的就是脚本。而想要游戏脚本优秀,对源码提供的API的必须熟烂于心。
然而最基础和最重要的还是先掌握Lua的语法。

我的教程会像日记一样记录我学习的过程和收获,同时希望能对相同的新手学者起到相互借鉴得作用。

由于我已经具备了一定的Lua脚本基础,我的教程侧重讲解DOTA2 API源码,而不会过多纠结于Lua语法,新手关于lua语法部分自行补脑。我也不能保证我的学习和研究成功完全正确。

评分

参与人数 3金币 +150 创造力 +10 求知欲 +20 互助 +20 智慧 +30 节操 -10 收起 理由
NAT + 100 + 10 + 10 + 10 + 10 -10
dewangsky + 10 加油!
无双 + 50 + 10 + 10 + 10 很给力!赞!

查看全部评分

回复

使用道具 举报

96

主题

1874

帖子

2493

积分

Lv:6 苍空龙法师

UID
9458
金币
2486
精华
0
节操
-35

隐修议员教程大师开拓者黑科技玩的6

 楼主| 发表于 2016-1-11 08:34:20 | 显示全部楼层
2、对于树木4条API对于新手不会寻找实体对象。我一开始也没搞懂。
在另一节中我讲详细介绍DOTA2各类实体的创建和寻找方式。
在这里直接提一下:
一开始我使用:
local tree = Entities:FindByClassname(nil,CDOTA_MapTree )
tree:CutDown(2)                        

这里控制台提示:tree是一个nil空值,我们没有取到任何树木实体。
local tree = Entities:FindByClassname(nil,ent_dota_tree)
tree:CutDown(2)
可以提取到树木实体。 虽然不明白原因,但是以后使用Find类API时尽量使用子类型。
回复 支持 1 反对 0

使用道具 举报

96

主题

1874

帖子

2493

积分

Lv:6 苍空龙法师

UID
9458
金币
2486
精华
0
节操
-35

隐修议员教程大师开拓者黑科技玩的6

 楼主| 发表于 2016-1-11 07:40:02 | 显示全部楼层
本帖最后由 blockbaster 于 2016-1-11 12:11 编辑

在详细讲解4条API前向介绍一下:面对对象语言类Class的概念。

1、继承
任何对象Object都可以分为某一类Class,对象即是类Class实例化后产物。
Class重要一个特性就是继承,一个新类就是可以从基类或其他类继承来。
举个例子:

果实(基类)->水果(继承1)->苹果(继承2)->苹果A:苹果类实例化


2、方法
类有许多方法,一般以成员函数形式提供。方法提供对该类对象的属性修改手段。比如:
苹果类拥有颜色属性,那么可以定义一个改变颜色的方法。通过调用该方法可以改变苹果的颜色。

对象方法如何调用?
形式:   
                              对象:方法名(函数名)
例如:
                               local index = p:GetPlayerId()


子类可以调用父类方法,但是父类不能调用子类方法。比如:
果实类方法:设置果实重量
苹果类方法:设置苹果口味

那么对于一个拿在手上的苹果实例,我们可以:
1、调用苹果类方法:设置苹果口味
2、果实类方法:设置苹果重量
但是对于一个果实类(目前不知道具体为那种果实)我们不可以:
1、调用苹果类方法:设置果实的口味
这很容易理解!

在这里官方文档给出的类为:CDOTA_MapTree。
在地图编辑器中我们可以了解到树木的类为:ent_dota_tree
他们的关系如下:

CBaseEntity -> CDOTA_MapTree -> ent_dota_tree


DOTA2中实体建立方式:
1、地图编辑器中 使用刷子工具或实体工具(灯泡)在地图中预置
    例如:使用Hamm编辑器中使用树木刷子创建一片森林。
              使用Entity实体工具在地图特定坐标放置由列表框提供的类。比如开始点:info_player_start_badguys
2、在地图脚本addon_game_mode.lua中调用相关对象的类的方法在游戏中实时创建
    例如: 在玩家1的英雄的创建一个信使兵升级到飞行信使
              local p = PlayerResource:GetPlayer(0)     --由全局变量PlayerResource通过GetPlayer方法获取玩家1
              local team = p:GetTeam()                      --由玩家类的GetTeam方法获取玩家所在队伍

              local id = p:GetPlayerID()                       --由玩家类的GetPlayerID方法获取玩家索引index
              local hero = p:GetAssignedHero()            --由玩家类的GetAssignedHero方法获得当前控制的英雄
              local pos = hero:GetOrigin()                    --由实体类的GetOrigin方法获得英雄坐标
              local courier = CreateUnitByName("npc_dota_courier",pos,true,nil,nil,team)  --在pos位置创建一个属于team的信使npc_dota_courier

              courier:SetOwner(p)                               --设置单位拥有者为p
              courier:SetControllableByPlayer(id,true)    --设置单位可以由玩家p控制,与魔兽争霸机制不同。DOTA2引擎需要加上该方法才能控制单位行动。
              courier:UpgradeToFlyingCourier()             --升级到飞行信使



评分

参与人数 1节操 -1 收起 理由
shps951023 -1 很给力!赞!

查看全部评分

回复 支持 1 反对 0

使用道具 举报

96

主题

1874

帖子

2493

积分

Lv:6 苍空龙法师

UID
9458
金币
2486
精华
0
节操
-35

隐修议员教程大师开拓者黑科技玩的6

 楼主| 发表于 2016-1-11 06:53:40 | 显示全部楼层
本帖最后由 blockbaster 于 2016-1-11 06:55 编辑

先看看wiki上提供的关于树木(实体类型ent_dota_tree)的4条API:

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册账号

x
回复 支持 反对

使用道具 举报

96

主题

1874

帖子

2493

积分

Lv:6 苍空龙法师

UID
9458
金币
2486
精华
0
节操
-35

隐修议员教程大师开拓者黑科技玩的6

 楼主| 发表于 2016-1-11 07:58:15 | 显示全部楼层
本帖最后由 blockbaster 于 2016-1-11 08:23 编辑

那么对于由树木刷子放置在地图中的树木ent_dota_tree,我们显然可以使用CDOTA_MapTree类的4条API和CBaseEntity类的所有API。本节只讲CDOTA_MapTree类的4条API。

这4条API比较简单:
1、void CutDown(int TeamNumberKnownTo )
功能:砍到树木并标记为特定队伍TeamNumberKnownTo 砍倒
举例:local tree = Entities:FindByClassname(nil,"ent_dota_tree")      --通过实体类的FindByClassname方法寻找到地图上的第一颗树木
          tree:CutDown(2)                                                                   --砍倒这棵树

2、void CutDownRegrowAfter(float RegrowAfter, int TeamNumberKnownTo )
功能:砍到树木并标记为特定队伍TeamNumberKnownTo 砍倒,并在RegrowAfter时间后重新长出
举例:local tree = Entities:FindByClassname(nil,"ent_dota_tree")
      tree:CutDownRegrowAfter(5.0,2)                      --砍倒这棵树,会在5秒后重生

3、void GrowBack()
功能:长出这颗被砍倒的树,前提是被砍倒
举例: tree:GrowBack()


4、bool IsStanding()
功能:判断这棵树是否砍倒
举例:if tree:IsStanding() then
            tree:CutDown(0)           //站里状态,将其砍倒
       else
            tree:GrowBack()           //砍倒状态,令其重生
       end
回复 支持 反对

使用道具 举报

96

主题

1874

帖子

2493

积分

Lv:6 苍空龙法师

UID
9458
金币
2486
精华
0
节操
-35

隐修议员教程大师开拓者黑科技玩的6

 楼主| 发表于 2016-1-11 08:05:34 | 显示全部楼层
本帖最后由 blockbaster 于 2016-1-11 08:17 编辑

更加生动和实际的应用:

1、砍倒地图上所有树木,在控制台可以观察到地图的树木总量total和新被砍倒的数量count

function DestroyAllMapTrees()
     local tree = Entities:FindByClassname(nil,"ent_dota_tree")
     local total = 0
     local count = 0
     if tree == nil then
          print("No Tree On Map!")
     else
          while tree ~= nil do
              total = total + 1
              if tree:IsStanding() then
                  count=count+1
                  tree:CutDown(1)
               end
              tree = Entities:FindByClassname(tree,"ent_dota_tree")
           end
           print("Total "..total.." Trees,"..count.." trees destroyed!")   //总计total树木,销毁count树木
   end
end



我在空演示地图上使用刷子创建了4个树木,addon_game_mode.lua脚本如下:

function DestroyAllMapTrees()
     local tree = Entities:FindByClassname(nil,"ent_dota_tree")
     local total = 0
     local count = 0
     if tree == nil then
          print("No Tree On Map!")
     else
          while tree ~= nil do
              total = total + 1
              if tree:IsStanding() then
                  count=count+1
                  tree:CutDown(1)
               end
              tree = Entities:FindByClassname(tree,"ent_dota_tree")
           end
           print("Total "..total.." Trees,"..count.." trees destroyed!")   //总计total树木,销毁count树木
   end
end

function Activate()
     DestroyAllMapTrees()
end

即可在控制台中查看信息。
关于控制台的使用方法本节不介绍。控制台可以显示脚本中由print等输出的调试信息。下图最低边黑灰条纹中显示上例的一条调试信息。
当然图片是未调用脚本前截屏的。


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册账号

x
回复 支持 反对

使用道具 举报

96

主题

1874

帖子

2493

积分

Lv:6 苍空龙法师

UID
9458
金币
2486
精华
0
节操
-35

隐修议员教程大师开拓者黑科技玩的6

 楼主| 发表于 2016-1-11 08:20:15 | 显示全部楼层
2、恢复地图上所有被砍倒的树木。原理同上例。

function RefreshAllMapTrees()
     local tree = Entities:FindByClassname(nil,"ent_dota_tree")
     local total = 0
     local count=0
     if tree == nil then
           print("No Tree On Map!")
     else
           while tree ~= nil do
               total = total + 1
               if not tree:IsStanding() then
                      count = count+1
                      tree:GrowBack()
               end
               tree = Entities:FindByClassname(tree,"ent_dota_tree")
           end
      print("Total "..total.." Trees,"..count.." trees refeshed!")
     end
end

回复 支持 反对

使用道具 举报

96

主题

1874

帖子

2493

积分

Lv:6 苍空龙法师

UID
9458
金币
2486
精华
0
节操
-35

隐修议员教程大师开拓者黑科技玩的6

 楼主| 发表于 2016-1-11 08:26:32 | 显示全部楼层
本节的补充知识:
1、游戏常量 -队伍类型

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?注册账号

x
回复 支持 反对

使用道具 举报

4

主题

14

帖子

391

积分

Lv:3 空明术士

UID
3658
金币
385
精华
0
节操
0
发表于 2016-1-11 11:24:28 | 显示全部楼层
看完了! 大腿啊!
回复 支持 反对

使用道具 举报

2

主题

6

帖子

143

积分

Lv:1 隐谧贤者

UID
9125
金币
53
精华
0
节操
0
发表于 2016-1-11 16:28:24 来自手机 | 显示全部楼层
请问什么是标记为特定队伍?
回复 支持 反对

使用道具 举报

96

主题

1874

帖子

2493

积分

Lv:6 苍空龙法师

UID
9458
金币
2486
精华
0
节操
-35

隐修议员教程大师开拓者黑科技玩的6

 楼主| 发表于 2016-1-11 16:53:42 | 显示全部楼层
蛋炒饭 发表于 2016-1-11 16:28
请问什么是标记为特定队伍?

就是给树木绑定破坏者,可能其他地方需要用到。具体也不是很清楚。
回复 支持 反对

使用道具 举报

2

主题

6

帖子

143

积分

Lv:1 隐谧贤者

UID
9125
金币
53
精华
0
节操
0
发表于 2016-1-12 01:15:45 来自手机 | 显示全部楼层
blockbaster 发表于 2016-1-11 16:53
就是给树木绑定破坏者,可能其他地方需要用到。具体也不是很清楚。

谢谢了。。。
回复 支持 反对

使用道具 举报

3

主题

23

帖子

324

积分

Lv:3 空明术士

UID
9486
金币
197
精华
0
节操
0
发表于 2016-1-13 00:19:56 | 显示全部楼层
太棒了,久旱逢甘霖,突然看见刷出那么多帖子心里那个激动啊
回复 支持 反对

使用道具 举报

3

主题

23

帖子

324

积分

Lv:3 空明术士

UID
9486
金币
197
精华
0
节操
0
发表于 2016-1-13 00:22:33 | 显示全部楼层
辛苦了      
回复 支持 反对

使用道具 举报

96

主题

1874

帖子

2493

积分

Lv:6 苍空龙法师

UID
9458
金币
2486
精华
0
节操
-35

隐修议员教程大师开拓者黑科技玩的6

 楼主| 发表于 2016-1-13 00:31:48 | 显示全部楼层
GGGoldeN 发表于 2016-1-13 00:19
太棒了,久旱逢甘霖,突然看见刷出那么多帖子心里那个激动啊

能听你这么说,我很高兴和欣慰,我的辛苦和付出在促进自己的同时能启发别人是我最大的愿望!
在魔兽prg领域由于多方面原因,国人可能走在后面,但是在今天,DOTA2对为全世界爱好者来说,都处在同一起跑线上,我们中国人绝对不会输的!

我正在疯狂学习研究,并能及时在同一时间整理出供大家参阅共勉的资料。在有一些启发的时候我会及时开启新帖,但是由于时间和研究深度关系,可能不会太令人满意。我会慢慢修葺,博采众长,不断完善,能够为国人在dota2 rpg开发领域留下一些宝贵的值得借鉴额资料。

DOTA2 rpg能够成为一项事业!
回复 支持 反对

使用道具 举报

17

主题

40

帖子

475

积分

大摸导师

UID
1
金币
1969
精华
0
节操
-1

隐修议员

发表于 2016-1-13 16:04:58 | 显示全部楼层
blockbaster 发表于 2016-1-13 00:31
能听你这么说,我很高兴和欣慰,我的辛苦和付出在促进自己的同时能启发别人是我最大的愿望!
在魔兽prg ...

楼主堪称劳模啊,能否加个QQ,已经申请了。
建议把比较散的API解析帖子整理成一个梳理贴。加油!钦佩你。
欢迎大家 加入研究~
回复 支持 反对

使用道具 举报

96

主题

1874

帖子

2493

积分

Lv:6 苍空龙法师

UID
9458
金币
2486
精华
0
节操
-35

隐修议员教程大师开拓者黑科技玩的6

 楼主| 发表于 2016-1-13 18:14:16 | 显示全部楼层
admin 发表于 2016-1-13 16:04
楼主堪称劳模啊,能否加个QQ,已经申请了。
建议把比较散的API解析帖子整理成一个梳理贴。加油!钦佩你 ...

我不是经常上QQ,有空再加上。
回复 支持 反对

使用道具 举报

3

主题

35

帖子

455

积分

Lv:3 空明术士

UID
1759
金币
670
精华
0
节操
0
发表于 2016-1-13 23:35:33 | 显示全部楼层
屠版狂魔
回复

使用道具 举报

13

主题

42

帖子

541

积分

Lv:3 空明术士

UID
5008
金币
210
精华
0
节操
0
发表于 2016-1-19 21:01:41 | 显示全部楼层
楼主才是真正的在玩编辑器。
现在有些人掌握了点技术,生怕别人学去。
写教程的永远就那么几个,
楼主愿意花这么多精力来传道解惑,
用自己的经验缩短新手的学习成本,
我深表敬佩。
回复 支持 反对

使用道具 举报

2

主题

5

帖子

20

积分

Lv:1 隐谧贤者

UID
6853
金币
49
精华
0
节操
0
发表于 2016-1-21 16:33:39 | 显示全部楼层
好详细 让人看了好幸福的赶脚

建议弄一个索引页面  不然不好找
回复 支持 反对

使用道具 举报

96

主题

1874

帖子

2493

积分

Lv:6 苍空龙法师

UID
9458
金币
2486
精华
0
节操
-35

隐修议员教程大师开拓者黑科技玩的6

 楼主| 发表于 2016-1-21 18:45:10 | 显示全部楼层
Tin 发表于 2016-1-21 16:33
好详细 让人看了好幸福的赶脚

建议弄一个索引页面  不然不好找

对,是这么想的。前言+目录,先整体概括所有知识点,在链接到详细章节。工程很庞大,我一个人精力有限。很多内容都处于待研究发掘状态,慢慢来吧!
回复 支持 反对

使用道具 举报

0

主题

8

帖子

225

积分

Lv:2 长袍法师

UID
14780
金币
93
精华
0
节操
0
发表于 2019-9-3 18:48:39 | 显示全部楼层
感谢!还在更新吗?
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 注册账号

本版积分规则

QQ|Archiver|手机版|小黑屋|AMHC!dota2rpg~ ( 闽ICP备14009209 )

GMT+8, 2020-1-25 10:34 , Processed in 0.083219 second(s), 29 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2013 Comsenz Inc. Theme.Yeei

快速回复 返回顶部 返回列表