Как пользоваться одним глобальным таймером? Как отслеживать его время в других триггерах и удобней ли это, чем создавать много таймеров?

Принятый ответ

Кастомная система оглушения без использования способностей на глобальном таймере, с комментариями, говорящими названиями переменных и с адекватным форматированием. Без структур, так как они здесь излишни.
По такому же принципу можно реализовать всё, что угодно, лепится на единый таймер. Примерно по такому принципу работают все существующие игры (серверные/клиентские тики), только хранение данных по-другому реализовано (здесь параллельные массивы).
Код
library StunUnit // initializer Init
{
    private timer   periodicTimer = CreateTimer()    // Can be replaced with main map timer

    private unit    unitsStack[]
    private effect  effectsStack[]  // Stun effect storage
    private float   timeRemaining[] // Time of stun left
    private int     stackCounter = 0

    #define private TICK_PERIOD  = 0.05
    #define private STACK_LIMIT  = 8190
    #define private STUN_EFFECT  = "Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl"
    #define private ORDERID_STOP = 0xD0004


    // Looking for id of specified unit in stack
    private int StackSearch(unit givenUnit) {
        int i = -1;
        while(i++ < stackCounter) {
            if (givenUnit == unitsStack[i]) {
                return i;
            }
        }
        return -1;
    }

    // Add unit to stack with overflow check
    private void StackPush(unit givenUnit, float duration) {
        if(stackCounter < STACK_LIMIT) {
            unitsStack   [stackCounter] = givenUnit;
            effectsStack [stackCounter] = AddSpecialEffectTarget(STUN_EFFECT, givenUnit, "overhead");
            timeRemaining[stackCounter] = duration;
            stackCounter++;
        } else {
            BJDebugMsg("Stunned units stack overflow!");
        }
    }

    // Remove unit from stack
    private void StackPop(int id) {

        DestroyEffect(effectsStack[id]);

        stackCounter--;
        unitsStack   [id] = unitsStack   [stackCounter];
        effectsStack [id] = effectsStack [stackCounter];
        timeRemaining[id] = timeRemaining[stackCounter];

        unitsStack   [stackCounter] = null;
        effectsStack [stackCounter] = null;
        timeRemaining[stackCounter] = 0.0;
    }

    void StunUnit(unit givenUnit, float duration) {

        int stackedUnitId = StackSearch(givenUnit);

        if (stackedUnitId == -1) {
            StackPush(givenUnit, duration);
        } elseif (timeRemaining[stackedUnitId] < duration) {
            timeRemaining[stackedUnitId] = duration;
        }
    }

    private void TimerCallback() {

        int i = -1;

        while(i++ < stackCounter) {

            timeRemaining[i] -= TICK_PERIOD;
            IssueImmediateOrderById(unitsStack[i], ORDERID_STOP);

            if (timeRemaining[i] <= 0.0) {
                StackPop(i);
            }
        }
    }

    private void Init() {
        TimerStart(periodicTimer, TICK_PERIOD, true, function TimerCallback);
    }
}

ledoed, за такое форматирование просто руки отрывать надо и пожизненно лишать доступа к любым IDE.

Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
0
17
7 лет назад
Отредактирован ledoed
0
на структурах в лс могу дать пример
0
10
7 лет назад
0
ledoed:
на структурах в лс могу дать пример
ну напиши тут в лс, либо в вк
0
17
7 лет назад
Отредактирован ledoed
0
ну ок смори пример делаю на скорую руку

//=============================================
scope Myscope initializer init{

timer GLOBALTIMER==null//наш глобальный таймер




private MyMethod(){



Mylibrary_Update()//эта функция будет обновляться по таймеру сюда засовывай и норм будет


}


private void init(){

GLOBALTIMER=CreateTimer()
TimerStart(GLOBALTIMER, 0.025, true, function MyMethod)



}

}
//====================================================
library Mylibrary{

public void Update(){//эту функцию обновляет наш таймер сюда всё что угодно можно прикрепить на эту библиотеку


UnitMovePolar.Update()

}

//=====================
private void Mymethod(unit u){
UnitMovePolar.AddToUnitMove(u,30,30*0.0174,5,true)

}
//============
//передвижение по градусу UnitMovePolar.AddToUnitMove(u,speed,rad,Time,Trenie)
struct UnitMovePolar{ 
static UnitMovePolar Name[]
static int count = 0
//===================
unit u
int tt = 0

float speed,rad,timmer,tr
bool b



void Move(){

SetUnitX(.u,GetUnitX(.u)+.speed*Cos(.rad))
SetUnitY(.u,GetUnitY(.u)+.speed*Sin(.rad))
if(.b){
.speed-=.tr
if(.speed<=0){
Remove()
 }
}
}


void Remove(){
.tt = 0
.b=false
RemoveUnitStruct(.u)

}

void Action(){
Move()

.tt++

	if(.tt>=.timmer){

		Remove()
	 }

}

//=================================
static void AddToUnitMove(unit u,float speed,float rad,float timmer,bool trenie){
int i = Proverka(u)
if(i!=-1){return}
Name[count++] = UnitMovePolar.create() 
Name[count-1].u=u
Name[count-1].speed=speed
Name[count-1].rad=rad
Name[count-1].b=trenie
Name[count-1].timmer=timmer*sek
Name[count-1].tr=(speed/timmer)/sek
//================================

}
static int Proverka(unit u){
int i = 0
while(i<count){if(Name[i].u==u){return i};i++}
return -1
}
//Удаление
static void RemoveUnitStruct(unit u){
int i = Proverka(u);if(i==-1){return};count--;Name[i].u=null
Name[i].destroy()
while(i<count){
Name[i]=Name[i+1]
i++}
}

static void Update(){int i =0;while(i<count){Name[i].Action();i++}}

}//==========end struct






}
ещё самое важное о чём тебя предупредить хочу если у тя много функций требующих секундного таймера вешай отдельно на него все там системки а вот на такие в 0.025 вешай системы спелов
а если у тя очень много функций в них ещё много циклов и тд то лутше несколько таймеров по идеи на карту с 800 тригерными спелами уйдут 4 таймера
2
30
7 лет назад
Отредактирован Clamp
2
Кастомная система оглушения без использования способностей на глобальном таймере, с комментариями, говорящими названиями переменных и с адекватным форматированием. Без структур, так как они здесь излишни.
По такому же принципу можно реализовать всё, что угодно, лепится на единый таймер. Примерно по такому принципу работают все существующие игры (серверные/клиентские тики), только хранение данных по-другому реализовано (здесь параллельные массивы).
Код
library StunUnit // initializer Init
{
    private timer   periodicTimer = CreateTimer()    // Can be replaced with main map timer

    private unit    unitsStack[]
    private effect  effectsStack[]  // Stun effect storage
    private float   timeRemaining[] // Time of stun left
    private int     stackCounter = 0

    #define private TICK_PERIOD  = 0.05
    #define private STACK_LIMIT  = 8190
    #define private STUN_EFFECT  = "Abilities\\Spells\\Human\\Thunderclap\\ThunderclapTarget.mdl"
    #define private ORDERID_STOP = 0xD0004


    // Looking for id of specified unit in stack
    private int StackSearch(unit givenUnit) {
        int i = -1;
        while(i++ < stackCounter) {
            if (givenUnit == unitsStack[i]) {
                return i;
            }
        }
        return -1;
    }

    // Add unit to stack with overflow check
    private void StackPush(unit givenUnit, float duration) {
        if(stackCounter < STACK_LIMIT) {
            unitsStack   [stackCounter] = givenUnit;
            effectsStack [stackCounter] = AddSpecialEffectTarget(STUN_EFFECT, givenUnit, "overhead");
            timeRemaining[stackCounter] = duration;
            stackCounter++;
        } else {
            BJDebugMsg("Stunned units stack overflow!");
        }
    }

    // Remove unit from stack
    private void StackPop(int id) {

        DestroyEffect(effectsStack[id]);

        stackCounter--;
        unitsStack   [id] = unitsStack   [stackCounter];
        effectsStack [id] = effectsStack [stackCounter];
        timeRemaining[id] = timeRemaining[stackCounter];

        unitsStack   [stackCounter] = null;
        effectsStack [stackCounter] = null;
        timeRemaining[stackCounter] = 0.0;
    }

    void StunUnit(unit givenUnit, float duration) {

        int stackedUnitId = StackSearch(givenUnit);

        if (stackedUnitId == -1) {
            StackPush(givenUnit, duration);
        } elseif (timeRemaining[stackedUnitId] < duration) {
            timeRemaining[stackedUnitId] = duration;
        }
    }

    private void TimerCallback() {

        int i = -1;

        while(i++ < stackCounter) {

            timeRemaining[i] -= TICK_PERIOD;
            IssueImmediateOrderById(unitsStack[i], ORDERID_STOP);

            if (timeRemaining[i] <= 0.0) {
                StackPop(i);
            }
        }
    }

    private void Init() {
        TimerStart(periodicTimer, TICK_PERIOD, true, function TimerCallback);
    }
}

ledoed, за такое форматирование просто руки отрывать надо и пожизненно лишать доступа к любым IDE.
Принятый ответ
0
32
7 лет назад
0
Эмм зачем? Таймер самый легкий объект в игре, создавайте новый и удаляйте старый.
0
30
7 лет назад
Отредактирован Clamp
0
создавайте новый и удаляйте старый
Зачем, если в этом нет необходимости?
0
17
7 лет назад
Отредактирован ledoed
0
Clamp:
Без структур, так как они здесь излишни.
странно чем-то напоминает структуры(точней во что компилируются на жасс) и вообще я их использую чтобы не писать такие вещи как
Masiv[Peremenayz]=peremenaya и для ооп
0
30
7 лет назад
0
ledoed, моё мнение таково, что если использование структур vJass не необходимо, то стоит писать не структурами. ООП в Jass нет, существует только кривая эмуляция.
Кроме того, такое написание явным образом демонстрирует логику работы алгоритма, что в качестве ответа несколько актуальнее. Всё-таки почитай про отступы и стандарты оформления кода и комментариев в нём
Показан только небольшой набор комментариев вокруг указанного. Перейти к актуальным.
Чтобы оставить комментарий, пожалуйста, войдите на сайт.