通常YDWE的学习目录:
1、物体编辑:单位、物品、地形装饰、可破坏物、技能、魔法特效、输入管理;
2、触发编辑:变量、数组、触发(时间、条件、动作)、循环、单位组、计时器、地形区域;
3、功能实战:单位路线、定时刷兵、练功房、物品合成、物品叠加、选择英雄、失败条件、漂浮文字、排行榜、多面板、对话框。
这次我们来学习下太阳编辑器的全局变量。一定要看到最后哟!
一、YDWE的全局变量
我在《太阳编辑器学思笔记1:物体编辑》说过:太阳编辑器不适合0基础的使用者,它需要使用者熟悉WE或YDWE。我们先来回忆下YDWE的全局变量。
(一)触发编辑器中的全局变量
YDWE的全局变量是在触发编辑器中的变量(Ctrl+B)中新建的,变量类型包括:点、单位、单位组、玩家、玩家组、区域、计时器等等。
当你新建全局变量————保存地图————查看war3map.j文件,会发现新建的全局变量位于globals与endglobals之间:例如:
globals
location udg_p= null //点
player udg_player= null //玩家
unit udg_unit= null //单位
force udg_playergroup= null //玩家组
group udg_unitgroup= null //单位组
endglobals
[danger]注意上面变量名称前的变量类型的写法,它们在你用太阳编辑器定义全局变量时很重要。为了大家方便,我特别整理如下:[/danger]
序号 | T触发中的变量类型 | JASS触发中的变量类型 | 太阳编辑器中的变量类型 |
1 | Frame | integer | number |
2 | 锚点 | integer | number |
3 | 界面事件 | integer | number |
4 | 按键 | integer | number |
5 | 鼠标 | integer | number |
6 | 布尔值 | boolean | boolean |
7 | 整数 | integer | number |
8 | 实数 | real | number |
9 | 字符串 | string | string |
10 | 可破坏物 | destructable | destructable |
11 | 可破坏物类型 | integer | number |
12 | 物品 | item | item |
13 | 物品类型 | integer | number |
14 | 物品池 | itempool | itempool |
15 | 单位 | unit | unit |
16 | 单位组 | group | group |
17 | 单位类型 | integer | number |
18 | 单位池 | unitpool | unitpool |
19 | 玩家 | player | player |
20 | 玩家组 | force | force |
21 | 点 | location | location |
22 | 区域类型 | rect | rect |
23 | 不规则区域类型 | region | region |
24 | 触发器 | trigger | trigger |
25 | 对话框 | dialog | dialog |
26 | 对话框按钮 | button | button |
27 | 计时器 | timer | timer |
28 | 计时器窗口 | timerdialog | timerdialog |
29 | 漂浮文字 | texttag | texttag |
30 | 排行榜 | leaderboard | leaderboard |
31 | 多面板 | multiboard | multiboard |
32 | 多面板项目 | multiboarditem | multiboarditem |
33 | 镜头 | camerasetup | camerasetup |
34 | 可追踪物 | trackable | trackable |
35 | 图像 | image | image |
36 | 声音 | sound | sound |
37 | 特效 | effect | effect |
38 | 闪电效果 | lightning | lightning |
39 | 游戏缓存 | gamecache | gamecache |
40 | 技能 | integer | number |
41 | 魔法效果 | integer | number |
42 | 命令ID | integer | number |
43 | 种族 | race | race |
44 | 任务 | quest | quest |
45 | 任务要求 | questitem | questitem |
46 | 科技类型 | integer | number |
47 | 地形变化 | terraindeformation | terraindeformation |
48 | 地形纹理变化 | ubersplat | ubersplat |
49 | 可见度修整器 | fogmodifier | fogmodifier |
50 | 天气效果 | weathereffect | weathereffect |
51 | 布尔表达式 | boolexpr | boolexpr |
52 | 弧度 | real | number |
53 | 角度 | real | number |
54 | 哈希表 | hashtable | hashtable |
55 | 函数 | code | code |
(二)已放置在地形上的单位
我们作图时一定会在地图上放置一些固定单位,这些单位在触发编辑器里设置变量时可以直接被选择。如下实例:
我们在地图上放置了三个单位:神秘宝藏室、山丘之王、狮鹫骑士。
这样我们在触发编辑器里设置变量时,可以直接“选择一个单位”。所以放置在地图上的物体可以理解为已经被赋值的单位变量,这个值可以是一个建筑单位,可以是一个战斗单位等等。
【扩展阅读】已放置单位在JASS中的表现"]
1、在globals与endglobals之间定义了一个全局变量 unit gg_unit_hvlt_0001= null
2、地图初始化时运行一个创建单位的函数 call CreateAllUnits()
3、这个函数里又执行了2个函数,1个是给玩家1创建建筑单位,1个是给玩家1创建战斗单位
function CreateAllUnits takes nothing returns nothing
call CreateBuildingsForPlayer0() // INLINED!!
call CreateUnitsForPlayer0() // INLINED!!
endfunction
4、创建建筑单位给玩家1。因为我在一个触发里调用了神秘宝藏室,所以下面设置时是用的全局变量;如果没有被触发调用,则使用局部变量u。
function CreateBuildingsForPlayer0 takes nothing returns nothing
local player p= Player(0)
local unit u
local integer unitID
local trigger t
local real life
set gg_unit_hvlt_0001=CreateUnit(p, 'hvlt', - 320.0, - 192.0, 270.000)
endfunction
5、创建战斗单位给玩家1
function CreateUnitsForPlayer0 takes nothing returns nothing
local player p= Player(0)
local unit u
local integer unitID
local trigger t
local real life
set u=CreateUnit(p, 'Hmkg', 53.2, - 190.6, 157.362)
set u=CreateUnit(p, 'hgry', 313.2, - 281.0, 12.964)
endfunction
(三)在地形放置的矩形区域
我们在使用YDWE时可以通过区域面板在地形上设置矩形区域。如下实例:
其实和上述第二点同理,这个在YDWE地形上设置矩形区域,也可以被理解为是一个被赋值的矩形区域变量。
【扩展阅读】已放置矩形区域在JASS中的表现
1、在globals与endglobals之间定义了一个全局变量 rect gg_rct_jihe= null
2、地图初始化时运行一个创建区域的函数 call CreateRegions()
3、这个函数里默认定义天气效果,但是没有赋值;同时设定了区域的范围
function CreateRegions takes nothing returns nothing
local weathereffect we
set gg_rct_jihe=Rect(- 256.0, - 1312.0, 352.0, - 800.0)
endfunction
二、太阳编辑器转换JASS的全局变量
前面铺垫了这么多内容,终于进入了和太阳编辑器有关的内容了。虽然我们可以用太阳编辑器,按照JASS的写法在地图上放置单位,设置区域,但是缺点就是不如YDWE操作直观。
那么我们在地图上放置单位,设置区域,太阳编辑器在写触发时有办法能调用吗?答案是肯定的。
1、打开地图
2、打开YDWE放置:在左侧树形栏上方点击“保存并用YDWE里打开”——在地形上放置了三个单位,设置了一个区域。
3、在YDWE的触发编辑器中设置变量,并选择单位。这步的目的是在“war3mapJ转Ts全局变量定义”时能够获取单位,否则无法获取。“war3mapJ转Ts全局变量定义”。实例如下:
[info]小技巧:你可以新建一个永远不会用到的变量,再新建一个永远不会被执行的触发,在触发的动作里重复设置变量。[/info]
4、YDWE保存地图——回到太阳编辑器界面,它会检测到地图改动——弹出对话框提醒刷新当前地图——点击“确定”
5、转换war3map.j到TS全局变量:待地图刷新完毕——在左侧树形栏找到war3map.j文件——右键单击“格式转换”——选择“war3mapJ转Ts全局变量定义”
6、在左侧树形栏src目录下,你可以找到一个名为“war3map.d.ts”的文件。文件中变量可以在太阳编辑器中写触发时直接引用。
实例中放置的单位和设置的区域被定义如下:
declare var udg_Tdanwei: unit;
declare var gg_rct_jihe: rect;
declare var gg_rct_jihe2: rect;
declare var gg_trg_Ttest: trigger;
declare var gg_unit_hvlt_0001: unit;
declare var gg_unit_Hmkg_0000: unit;
declare var gg_unit_hmtt_0002: unit;
declare var gg_unit_Hamg_0004: unit;
三、太阳编辑器调用war3map.d.ts中的全局变量
我们趁热打铁通过实例来学习:太阳编辑器如何调用war3map.d.ts中的全局变量?
实例的目标是:命令演示地图中的山丘之王移动到矩形区域的中心点
1、新建*.ts文件:在左侧树形栏右键单击src文件夹(这步的目的是将ts文件新建在src目录下)——新建——新建ts文件——命名文件名,例如:Move
2、用Vscode编辑器它:点击新建的Move.ts——在左侧树形栏上方点击“用VS code打开[粘性窗口]”——编辑Move.ts的默认触发代码。这里先讲下默认触发代码的语法:
// 新建一个名为Move的类并导出
export default class Move {
// 构造函数
constructor() {
// 新建触发
let trigger = new Trigger()
// 触发事件.注册计时器事件(秒,是否循环)
trigger.registerTimerEvent(1, false)
// 添加触发器动作
trigger.addAction(this.action)
}
// 执行触发动作
action(this: void) {
}
}
【为什么使用构造函数的扩展阅读可以访问《太阳编辑器学思笔记1:TypeScript编程语言》】
3、我们写入以下代码后,保存Move.ts
action(this: void) {
IssuePointOrderLoc(gg_unit_Hmkg_0000, 'Move', GetRectCenter(gg_rct_jihe)) >
}
[info]小技巧:不知道/不熟练函数写法可以在太阳编辑器的菜单栏——工具——函数查找中进行关键词搜索。不知道函数()内的参数:参数类型,可以将鼠标放置在函数上会有相关提示。[/info]
4、我们在App.ts的构造函数constructor() { } 中增加以下代码后,保存App.ts。
new Move();
[danger]注意:
1、在敲完以上代码后,VScode会自动在App.ts文件内容的上面补齐“import Move from 'Move';”,请不要删除。
2、TS文件编辑完成后一定要保存,否则运行魔兽测试时一定无效。
[/danger]
5、回到太阳编辑器中点击“运行”查看效果。
四、太阳编辑器自定义全局变量
(一)新建.ts文件新建全局变量
虽然我们可以在war3map.d.ts中参照写法定义全局变量,但是我们不建议这样做!因为,这个文件是从war3map.j转换而来,你每次转换会将你自己增加的全局变量给覆盖! 所以,我们要新建一个.ts文件来存放自定义的全局变量。 这次我们实例的目标是:新建3个单位在地图中心点,将这3个单位放入1个单位组中,命令单位组中的所有单位移动到某坐标点。
1、新建*.ts文件:在左侧树形栏右键单击src文件夹(这步的目的是将ts文件新建在此)——新建——新建ts文件——命名文件名。实例名字:BianLiang
2、删除默认的触发代码:点击新建的BianLiang.ts——在左侧树形栏上方点击“用VS code打开[粘性窗口]”——删除默认代码(即触发的语法模板)
3、全局变量语法格式如下所示:
export default class 当前TS的文件名{
static 变量名称:类型= 默认值;
}
实例:
export default class BianLiang{
static dian:location ; static danweizu:group ; static danwei:unit;
}
4、我们在App.ts的构造函数constructor() { } 中增加以下代码后,并检查上面是否有补齐“import Move2 from 'Move2';”,最后保存App.ts。
new Move2();
5、回到太阳编辑器中点击“运行”查看效果。
[success]知识点:static 表明类变量是静态的,静态的变量可以通过类名直接访问。如BianLiang.danwei[/success]
(二)在其他.ts文件中调用自定义全局变量
1、新建另一个*.ts文件:在左侧树形栏右键单击src文件夹——新建——新建ts文件——命名文件名。实例名字:Move2
2、用Vscode编辑器它:点击新建的Move2.ts——在左侧树形栏上方点击“用VS code打开[粘性窗口]”——编辑默认的触发代码,实例如下:
export default class Move2 {
constructor()
{
let trigger = new Trigger()
trigger.registerTimerEvent(1, false)
trigger.addAction(this.action)
}
action(this: void)
{
BianLiang.danwei = gg_unit_Hamg_0004; IssuePointOrderLoc(BianLiang.danwei,'Move',GetRectCenter(gg_rct_jihe2))
}
}
}
五、演示地图下载
(已过期)
六、课外笔记
看了几张TS的开源地图,我发现:
1、war3mapJ转Ts全局变量定义,转换的都是矩形区域,没有放置单位。原因推测:一是上述《二、太阳编辑器转换JASS的全局变量》中的第3步比较鸡肋。二是在class类中完全可以用局部变量代替。
2、对新触发的调用都不放在app.ts里,而是放在了stateinit.ts文件中,或者是自定了一个新的ts文件存放。原因推测:添加或更新太阳TS框架时不至于被覆盖。
3、static danweizu:group ; 在太阳编辑器里这句代码只是声明了一个单位组的变量名称,并没有进行初始化,即没有新建空的单位组。所以单位组一般不会声明为全局变量,二是在class类中声明为局部变量后直接初始化,即写成:let g = CreateGroup();
4、如何解释上述第3点?是因为我们忽视了在YDWE中设置单位组、玩家组、排行榜、多面板、漂浮文字等全局变量时,JASS会默认对全局变量进行初始化:CreateGroup()、CreateForce()、CreateLeaderboard()、CreateMultiboard()、CreateTextTag()。而在太阳编辑器中我们要手动进行初始化。