一、单位组

实例1:

事件:玩家输入dwz 动作: 创建1个牧师添加进单位组danweizu 创建1个女巫添加进单位组danweizu 创建1个魔法破坏者添加进单位组danweizu 选取单位组的所有单位做动作:移动到地图区域的随机点

(一)被弃用的ForGroup/ForGroupBJ

老规矩,先上JASS转TS的写法:

import BianLiang from 'BianLiang';

export default class Dan_Weizu {

    constructor() {

        let t = CreateTrigger();

        TriggerRegisterPlayerChatEvent(t, Player(0), "dwz", true);

        TriggerAddAction(t, Dan_Weizu.action);

    }

    static action(this: void) {

        let g: group;

        let u: unit;

        GroupAddUnitSimple(CreateUnitAtLoc(Player(0), FourCC('hmpr'), GetRectCenter(GetPlayableMapRect()), 0), BianLiang.danweizu);

        GroupAddUnitSimple(CreateUnitAtLoc(Player(0), FourCC('hsor'), GetRectCenter(GetPlayableMapRect()), 0), BianLiang.danweizu);

        GroupAddUnitSimple(CreateUnitAtLoc(Player(0), FourCC('hspt'), GetRectCenter(GetPlayableMapRect()), 0), BianLiang.danweizu);

        ForGroupBJ(BianLiang.danweizu, Dan_Weizu.action1);

        GroupClear(BianLiang.danweizu);

        g = null;

        u = null;

    }

    static action1(this: void): void {

        IssuePointOrderLoc(GetEnumUnit(), "move", GetRandomLocInRect(GetPlayableMapRect()));

    }

}

[success]

知识点:

1、我们在BianLiang.ts里定义了danweizu,所以直接import BianLiang from 'BianLiang';后引用它。

2、在太阳编辑器中ForGroup和ForGroupBJ已经被弃用了!作者推荐我们使用GroupUnit.for

3、运行上面的代码并不会执行单位组内的单位移动到地图随机点的动作,原因:《太阳编辑器学思笔记2:全局变量》最后我们提到,单位组类型的变量声明后要初始化,即新建空的单位组。否则无法将单位添加进一个不存在的、具体的单位组中。

[/success]

(二)GroupUnit.for

太阳编辑器目前推荐的单位组语法表达,实例如下:

import GroupUtil from 'solar/util/unit/GroupUtil';

import { MapPlayer } from 'solar/w3ts/handles/player';

import { Trigger } from 'solar/w3ts/handles/trigger';

export default class Dan_Weizu {

    constructor() {

        let t = new Trigger();

        t.registerPlayerChatEvent(MapPlayer.fromIndex(0), 'dwz', true)

        t.addAction(this.action);

    }

    action(this: void) {

        let g = CreateGroup();

        GroupAddUnitSimple(CreateUnitAtLoc(Player(0), FourCC('hmpr'), GetRectCenter(GetPlayableMapRect()), 0), g);

        GroupAddUnitSimple(CreateUnitAtLoc(Player(0), FourCC('hsor'), GetRectCenter(GetPlayableMapRect()), 0), g);

        GroupAddUnitSimple(CreateUnitAtLoc(Player(0), FourCC('hspt'), GetRectCenter(GetPlayableMapRect()), 0), g);

        GroupUtil.for(g, (u) = {

            IssuePointOrderLoc(u, "move", GetRandomLocInRect(GetPlayableMapRect()));

    })

}

}

[success]

知识点:

1、用let局部声明单位组变量g后直接初始化,弃用全局变量的单位组BianLiang.danweizu;

2、单位变量u在 GroupUtil.for中作为参数直接声明,不需要赋值是因为已在import的GroupUtil模块中完成。

3、不需要自己清空单位组,同样也是因为遍历完清空单位组的动作在import的GroupUtil模块中完成。

综上大大简化了代码!

[/success]

二、计时器

(一)注册计时器事件:registerTimerEvent

实例2: 事件:游戏计时(单次)——当时间逝去1秒 动作:给红色玩家创建1个血魔法师在地图中心点

import { Trigger } from "solar/w3ts/handles/trigger";

export default class Ji_Shiqi {

    constructor() {

        let trigger = new Trigger()

        trigger.registerTimerEvent(1, false)

        trigger.addAction(this.action)

    }

    action(this: void) {

        CreateUnitAtLoc(Player(0), FourCC('Hblm'), GetRectCenter(GetPlayableMapRect()), 0)

    }

}

实例3: 事件:游戏计时(循环)——每当时间逝去1秒 动作:给红色玩家创建1个血魔法师在地图中心点

import { Trigger } from "solar/w3ts/handles/trigger";

export default class Ji_Shiqi {

    constructor() {

        let trigger = new Trigger()

        trigger.registerTimerEvent(1, true)

        trigger.addAction(this.action)

    }

    action(this: void) {

        CreateUnitAtLoc(Player(0), FourCC('Hblm'), GetRectCenter(GetPlayableMapRect()), 0)

    }

}

[warning]学习笔记: 1、单次计时器还是循环计时器,对于注册计时器事件registerTimerEvent来说,就是:false和true的差别。 2、如果我们需要控制实例中单位创建的次数,还需要设置一个整数变量作为条件。[/warning]

(二)太阳中心计时器:BaseUtil.onTimer

BaseUtil.onTimer(参数1,参数2)指计时器延迟x秒后执行动作。参数1是整数,表示x秒;参数2是布尔值,返回true 代表继续执行,返回false 代表不再执行。

实例4:间隔1秒创建1个单位就停止创建 事件:红色玩家输入jsq 动作: 运行(新建计时器),周期1秒,模式:1次 给红色玩家创建1个血魔法师在地图中心点

 

 export default class Ji_Shiqi {

    constructor() {

        let trigger = new Trigger()

        trigger.registerPlayerChatEvent(MapPlayer.fromIndex(0), 'jsq', true)

        trigger.addAction(this.action)

    }

    action(this: void) {

        BaseUtil.onTimer(1, () = {

            CreateUnitAtLoc(Player(0), FourCC('Hblm'), GetRectCenter(GetPlayableMapRect()), 0)

        return false;

    })

    }
   
}

[info]笔记:参数2处不带参数,执行完创建动作后,直接返回false就可以不再执行。[/info]

实例5:每间隔1秒创建1个单位,创建10个后停止创建。 事件:红色玩家输入jsq1 动作: 运行(新建计时器),周期1秒,模式:10次 给红色玩家创建1个血魔法师在地图中心点

 

export default class Ji_Shiqi {

    constructor() {

        let trigger = new Trigger()

        trigger.registerPlayerChatEvent(MapPlayer.fromIndex(0), 'jsq1', true)

        trigger.addAction(this.action)

    }

    action(this: void) {

        BaseUtil.onTimer(1, (n) = {

            CreateUnitAtLoc(Player(0), FourCC('Hblm'), GetRectCenter(GetPlayableMapRect()), 0)

        if (n <= 9) {

            return true;

        } return false;

    })

    }
   
}

[info]笔记:参数2处设置参数n,执行完创建动作后,判断条件真假,返回true 代表继续执行,返回false 代表不再执行。这里需要特别注意n默认是整数0。[/info]

(三)太阳中心计时器:BaseUtil.runLater

BaseUtil.runLater(参数1,参数2,参数3)指计时器间隔x秒后执行动作y,执行z次。参数1是整数,表示x秒;参数2是空值;参数3是循环次数。

实例6:每间隔1秒创建1个单位,执行5次。 事件:红色玩家输入jsq2 动作: 运行(新建计时器),周期1秒 给红色玩家创建1个血魔法师在地图中心点 执行5次

export default class Ji_Shiqi {

    constructor() {

        let trigger = new Trigger()

        trigger.registerPlayerChatEvent(MapPlayer.fromIndex(0), 'jsq2', true)

        trigger.addAction(this.action)

    }

    action(this: void) {

        BaseUtil.runLater(1, () = {

            CreateUnitAtLoc(Player(0), FourCC('Hblm'), GetRectCenter(GetPlayableMapRect()), 0)

        }, 5)

    }
   
}

总结

1、对比我们不难发现,BaseUtil.runLater使用起来更简洁。

2、无论是BaseUtil.onTimer还是BaseUtil.runLater,两者都是基于太阳计时器STimer模块。

三、演示地图下载

(已过期)