Сейчас 10:25:12 Понедельник, 29 апреля, 2024 год
[ x ] Главная ⇒ Форум ⇐ RSS Файлы Cтатьи Картинки В о й т и   или   з а р е г и с т р и р о в а т ь с я


[ Новые сообщения · Участники · Правила форума · Поиск · RSS ]
  • Страница 1 из 2
  • 1
  • 2
  • »
Модератор форума: PUVer, SirNikolas, Ty3uK  
Форум о Warcraft 3 » Раздел для картостроителей » GUI / Jass » Создание и удаление таймера (Надо ли это? Или можно пользоваться одним глобальным?)
Создание и удаление таймера
FatalBladeДата: Суббота, 30 Июля 2011, 14:37:16 | Сообщение # 1
10 уровень
Группа: Проверенные
Сообщений: 1523
Награды: 0
Репутация: 439
Блокировки:
Если не создавать каждый раз таймер (call CreateTimer) а потом удалять, а сразу всегда писать call StartTimer(глобальная переменная). Т.е. триггер не создаёт каждый раз новый таймер, а использует 1 и тот же. Удалять в таком случае его не надо (call DestroyTimer)?

 

FkoFFДата: Суббота, 30 Июля 2011, 14:55:35 | Сообщение # 2
Группа: Заблокированные
Сообщений: 4356
Награды: 1
Репутация: 1413
Блокировки:
вообще использовать один и тот же таймер - а какой смысл?

По сабжу - вообще не надо, НО, это даже не MPI, что уж говорить о МУИшности. Проще локальные таймеры спамить, они не нагружают карту практически.


 

FatalBladeДата: Суббота, 30 Июля 2011, 15:23:46 | Сообщение # 3
10 уровень
Группа: Проверенные
Сообщений: 1523
Награды: 0
Репутация: 439
Блокировки:
Quote (FkoFF)
вообще использовать один и тот же таймер - а какой смысл?

Не 1 и тот же таймер на все случаи жизни, а для каждого триггерно скилла 1 таймер. Например TimerCharge, TimerLeap, TimerTD. Это всё глобальные переменные. А когда создаёшь глобальню переменную типа Таймер, то он уже сразу подразумевает CreateTimer. И теперь, каждый раз когда герой например юзает скилл Charge, то он запускает 1 и тот же таймер, TimerCharge, снова и снова. Утечек ведь не должно быть, потому что он не создаёт НОВЫЙ таймер, а использует существующий, созданный при инициализации карты (или даже неё).
Я прав?

Quote (FkoFF)
Проще локальные таймеры спамить, они не нагружают карту практически.

Так мнеж надо запустить таймер, а потом в другом триггере с событием (TimerCharge) Expired, и продолжать действия триггерного спелла. Локальный таймер будет работать только в пределах одного триггера.

Добавлено (30-07-2011, 15:23)
---------------------------------------------
А если сделать так:
Сначала создать локальный таймер T, время которого равно = (расстояние между юнитами) / (скорость движения обьекта)
В этот же триггер добавить событие Trigger - Add to (This trigger) the event (Time - T expires)?
И после него писать дальнейшие действия.

Это будет расцениваться как пауза? То есть например если время таймера равно 0.66 секунд, то действия которые написаны после триггерного добавления события, произойдут спустя 0.66 секунд.




Сообщение отредактировал FatalBlade - Суббота, 30 Июля 2011, 15:24:28
 

FkoFFДата: Суббота, 30 Июля 2011, 15:44:18 | Сообщение # 4
Группа: Заблокированные
Сообщений: 4356
Награды: 1
Репутация: 1413
Блокировки:
Quote (FatalBlade)
Утечек ведь не должно быть, потому что он не создаёт НОВЫЙ таймер, а использует существующий, созданный при инициализации карты (или даже неё). Я прав?

Прав. Тогда зачем вообще делать таймеры, если можно обойтись переодическими триггерами (считай минус объект)?

Таймеры актуальны только на джасс, по тому что дают возможность легко делать MUI, тогда как на гуях это колдунство с глобальными переменными и циклами.

Quote (FatalBlade)
И после него писать дальнейшие действия.

теоретически можно если вбить условие GetExpiredTimer()==udg_TimerName then

Quote (FatalBlade)
Это будет расцениваться как пауза? То есть например если время таймера равно 0.66 секунд, то действия которые написаны после триггерного добавления события, произойдут спустя 0.66 секунд.

Учи уже джасс, чего ты колдовством убогим занимаешься?


 

FatalBladeДата: Суббота, 30 Июля 2011, 16:05:06 | Сообщение # 5
10 уровень
Группа: Проверенные
Сообщений: 1523
Награды: 0
Репутация: 439
Блокировки:
Quote (FkoFF)
Учи уже джасс, чего ты колдовством убогим занимаешься?

Не хочу комманды зубрить %)

Добавлено (30-07-2011, 15:54)
---------------------------------------------
Quote (FkoFF)
GetExpiredTimer()==udg_TimerName then

А вот такое
if ( TimerGetRemaining(t) <= 0.00 ) then
И тогда без добавления события.

Добавлено (30-07-2011, 16:05)
---------------------------------------------
call TimerStart(t, 0.3, false, null)
set r = TimerGetRemaining (t)
loop
exitwhen r<=0
set r = TimerGetRemaining (t)
endloop

А такое?




Сообщение отредактировал FatalBlade - Суббота, 30 Июля 2011, 16:13:08
 

SirNikolasДата: Суббота, 30 Июля 2011, 16:21:41 | Сообщение # 6
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Quote (FatalBlade)
Code
loop
     exitwhen r<=0
endloop
Цикл будет выполняться очень быстро, и, когда лимит операций превысит допустимое значение, поток завершится (действия после цикла не будут выполняться).

Добавлено (30-07-2011, 16:21)
---------------------------------------------
FatalBlade, учи JASS, на нем хэш-таблицы можно использовать. Как раз они и нужны в таких случаях.


 

FatalBladeДата: Суббота, 30 Июля 2011, 16:40:25 | Сообщение # 7
10 уровень
Группа: Проверенные
Сообщений: 1523
Награды: 0
Репутация: 439
Блокировки:
Ок а что сохранять в Хэш? Таймер?

Добавлено (30-07-2011, 16:32)
---------------------------------------------
Да и чем тут хэш поможет? Что он из себя представляет? Это всего лишь двумерный массив, который ко всему прочему ещё и глючит.

Добавлено (30-07-2011, 16:40)
---------------------------------------------
Как использовать локальный таймер? Шаблон плз, я уже сам разберусь что к чему. Если он локальный, значит не нужно создавать ещё 1 триггер, а значит всё проиходит в одном триггере.
call TimerStart(t, 0.3, false, null)
Дальше что? Какие условия? Какие действия? Какой цикл если он нужен?


 

SirNikolasДата: Суббота, 30 Июля 2011, 16:51:46 | Сообщение # 8
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Нет. Сохранять нужно требуемые значения, записывая их по номеру handle'а таймера. Вот простой пример:
Code
function Trig_HashSpell_Conditions takes nothing returns boolean
     return GetSpellAbilityId() == 'A000'
endfunction

function Trig_HashSpell_Timer takes nothing returns nothing
     local timer t = GetExpiredTimer()
     local integer id = GetHandleId(t)
     local widget w = LoadWidgetHandle(udg_Hash, id, 2)
     call UnitDamageTarget(LoadUnitHandle(udg_Hash, id, 1), w, LoadReal(udg_Hash, id, 0), true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)
     call DestroyEffect(AddSpecialEffect("Abilities\\Spells\\Human\\Thunderclap\\ThunderclapCaster.mdl", GetWidgetX(w), GetWidgetY(w))
     call FlushChildHashtable(udg_Hash, id)
     call DestroyTimer(t)
     set t = null
     set w = null
endfunction

function Trig_HashSpell_Actions takes nothing returns nothing
     local timer t = CreateTimer()
     local integer id = GetHandleId(t)
     call SaveReal(udg_Hash, id, 0, GetUnitAbilityLevel(GetTriggerUnit(), 'A000') * 500.)
     call SaveAgentHandle(udg_Hash, id, 1, GetTriggerUnit())
     call SaveAgentHandle(udg_Hash, id, 2, GetSpellTargetUnit())
     call TimerStart(t, 10., false, function Trig_HashSpell_Timer)
     set t = null
endfunction

//===========================================
functon InitTrig_HashSpell takes nothing returns nothing
      local trigger trig = CreateTrigger()
      local integer i = 0
      loop
          call TriggerRegisterPlayerUnitEvent(trig, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
          exitwhen i == 15
          set i = i + 1
      endloop
      call TriggerAddCondition(trig, Filter(function Trig_HashSpell_Conditions))
      call TriggerAddActions(trig, function Trig_HashSpell_Actions)
      set trig = null
endfunction


Добавлено (30-07-2011, 16:51)
---------------------------------------------
Quote (FatalBlade)
Это всего лишь двумерный массив, который, ко всему прочему, ещё и глючит.
Сначала разберись с хэшем, а уж потом думай над альтернативой.




Сообщение отредактировал SirNikolas - Суббота, 30 Июля 2011, 16:54:03
 

FatalBladeДата: Суббота, 30 Июля 2011, 16:57:50 | Сообщение # 9
10 уровень
Группа: Проверенные
Сообщений: 1523
Награды: 0
Репутация: 439
Блокировки:
Quote (SirNikolas)
loop
call TriggerRegisterPlayerUnitEvent(trig, Player(i), EVENT_PLAYER_UNIT_SPELL_EFFECT, null)
exitwhen i == 15
set i = i + 1
endloop

Это чё получается можно проверять 1 и то же событие на всех игроков? :o


 

SirNikolasДата: Суббота, 30 Июля 2011, 17:04:32 | Сообщение # 10
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Это добавляет в триггер событие каста заклинания для боевой единицы любого игрока.

 

FatalBladeДата: Суббота, 30 Июля 2011, 17:27:33 | Сообщение # 11
10 уровень
Группа: Проверенные
Сообщений: 1523
Награды: 0
Репутация: 439
Блокировки:
Quote (SirNikolas)
local widget w = LoadWidgetHandle(udg_Hash, id, 2)

Ты занёс в Widget юнита цель, а кастера нет. Почему?
w = LoadWidgetHandle(udg_Hash, id, 2)
а как насчёт LoadWidgetHandle(udg_Hash, id, 1) - который насколько я понял, является Triggering Unit

Quote (SirNikolas)
call UnitDamageTarget(LoadUnitHandle(udg_Hash, id, 1), w, LoadReal(udg_Hash, id, 0), true, false, ATTACK_TYPE_MAGIC, DAMAGE_TYPE_MAGIC, WEAPON_TYPE_WHOKNOWS)

Эти значения к чему относятся? Что они проверяют на true/false?

Quote (SirNikolas)
WEAPON_TYPE_WHOKNOWS

oO это что?
Как я понял UnitDamageTarget это более продвинутая версия UnitDamageTargetBJ?

Quote (SirNikolas)
GetWidgetX(w), GetWidgetY(w)

Координаты юнита w = LoadWidgetHandle(udg_Hash, id, 2), он же TargetUnitofAbilityBeingCast ?

Quote (SirNikolas)
call FlushChildHashtable(udg_Hash, id)

Очищает все ячейки Хэша на строке под номером id?

Quote (SirNikolas)
set w = null

А как насчёт LoadWidgetHandle(udg_Hash, id, 1) ?

Добавлено (30-07-2011, 17:25)
---------------------------------------------

Quote (SirNikolas)
Это добавляет в триггер событие каста заклинания для боевой единицы любого игрока.

И для любого игрока оно локально?

Добавлено (30-07-2011, 17:27)
---------------------------------------------

Quote (SirNikolas)
local trigger trig = CreateTrigger()

В чём разница между этим и set gg_trg_trig = CreateTrigger() ?


 

lawsonДата: Суббота, 30 Июля 2011, 20:11:50 | Сообщение # 12
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
Quote (FatalBlade)
Ты занёс в Widget юнита цель, а кастера нет. Почему?

Quote (SirNikolas)
LoadUnitHandle(udg_Hash, id, 1)

Quote (SirNikolas)
  call SaveAgentHandle(udg_Hash, id, 1, GetTriggerUnit())


Добавлено (30-07-2011, 20:09)
---------------------------------------------
Quote (FatalBlade)
Эти значения к чему относятся? Что они проверяют на true/false?

Раскрой BJ этой функции тогда поймешь.

Добавлено (30-07-2011, 20:10)
---------------------------------------------
Quote (FatalBlade)
Очищает все ячейки Хэша на строке под номером id?

Да.
Пиндец учи хеш по статьям! ты что будешь всех вопросами забрасывать?

Добавлено (30-07-2011, 20:10)
---------------------------------------------
Quote (FatalBlade)
А как насчёт LoadWidgetHandle(udg_Hash, id, 1) ?

Незачем обнулять LoadWidgetHandle(udg_Hash, id, 1) потому что это всего лишь ссылка на юнита в хеш таблице для этого используется call FlushChildHashtable(udg_Hash, id)!
А обнуляет w потому что это локальная перменная.

Добавлено (30-07-2011, 20:11)
---------------------------------------------
Quote (FatalBlade)
В чём разница между этим и set gg_trg_trig = CreateTrigger() ?

Обсолютно ни какой!
только gg_trg_trig является глобалкой созданной уже движком без участия игрока.


Nic nie wiem bo mam chuj.
редактирую посты! ВСЕ!


Сообщение отредактировал lawson - Суббота, 30 Июля 2011, 20:17:02
 

SirNikolasДата: Среда, 03 Августа 2011, 07:55:16 | Сообщение # 13
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Quote (FatalBlade)
В чём разница между этим и set gg_trg_trig = CreateTrigger()?
Локальные переменные чуть-чуть быстрее глобальных. Да, движок создает глобалку при создании триггера, но любой хороший оптимизатор (программа) уберет неиспользуемые переменные.


 

FatalBladeДата: Среда, 03 Августа 2011, 10:43:42 | Сообщение # 14
10 уровень
Группа: Проверенные
Сообщений: 1523
Награды: 0
Репутация: 439
Блокировки:
Quote (SirNikolas)
Локальные переменные чуть-чуть быстрее глобальных. Да, движок создает глобалку при создании триггера, но любой хороший оптимизатор (программа) уберет неиспользуемые переменные.

То есть во всех триггерах лучше поменять присвоение триггера глобалку на локалку? Или только в некоторых?


 

lawsonДата: Среда, 03 Августа 2011, 11:21:28 | Сообщение # 15
Группа: Проверенные
Сообщений: 3482
Награды: 0
Репутация: 974
Блокировки:
Quote (FatalBlade)
Или только в некоторых

Которые слишком часто используешь.


Nic nie wiem bo mam chuj.
редактирую посты! ВСЕ!
 

HexingДата: Среда, 03 Августа 2011, 12:28:04 | Сообщение # 16
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
если разговор еще о таймерах, то основной смысл создания для каждого триггера своего таймера: GetExpiredTimer() помогает нам сделать кучу всяких удобных вещей(триггерные спеллы и тп) и это не вариант если все к примеру заклинания будут весеть на одном таймере, тобишь ниче не заработает. А вот для простых целей, типа вывод подсказки, где нам не важен сам таймер, то можно сколько угодно вешать на 1 таймер.

 

FatalBladeДата: Среда, 03 Августа 2011, 12:35:47 | Сообщение # 17
10 уровень
Группа: Проверенные
Сообщений: 1523
Награды: 0
Репутация: 439
Блокировки:
Quote (Hexing)
это не вариант если все к примеру заклинания будут весеть на одном таймере,

Для каждого спелла 1 таймер, а не для всех 1))


 

[DS]Дата: Среда, 03 Августа 2011, 12:50:19 | Сообщение # 18
9 уровень
Группа: Проверенные
Сообщений: 1116
Награды: 0
Репутация: 527
Блокировки:
можно вообще все триггерами(на джассе)

 

SirNikolasДата: Среда, 03 Августа 2011, 13:34:06 | Сообщение # 19
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Использование единого таймера может немного повысить производительность.

Добавлено (03-08-2011, 13:34)
---------------------------------------------
Разумеется, если нормально сделать.


 

[DS]Дата: Среда, 03 Августа 2011, 13:36:03 | Сообщение # 20
9 уровень
Группа: Проверенные
Сообщений: 1116
Награды: 0
Репутация: 527
Блокировки:
не спорю таймеры быстрее

 

DragoNДата: Четверг, 04 Августа 2011, 12:46:49 | Сообщение # 21
Инквизитор
Группа: Стримеры
Сообщений: 4348
Награды: 7
Репутация: 2776
Блокировки:
юзать можно, если ты на него особо не планируешь данные вешать
в таком случае можно его просто паузить в нужный момент


El Psy Congroo
 

HexingДата: Четверг, 04 Августа 2011, 13:42:00 | Сообщение # 22
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
ощущение как будто каждый отвечает сам себе, а автор давно забыл про этот вопрос :D

 

FatalBladeДата: Четверг, 04 Августа 2011, 14:46:57 | Сообщение # 23
10 уровень
Группа: Проверенные
Сообщений: 1523
Награды: 0
Репутация: 439
Блокировки:
Да нет, почему, я всё ещё тут)

Добавлено (04-08-2011, 14:46)
---------------------------------------------
DragoN, думаешь можно для всех скиллов и вообще отсроченных действий на карте можно использовать 1 таймер?... У меня много триггерных скиллов, почти каждый из которых использует таймер. Нельзя для всех сделать 1. Я сделал для каждого скилла свой таймер. Например TimerCharge, TimerLeap итд..


 

SirNikolasДата: Пятница, 05 Августа 2011, 06:41:18 | Сообщение # 24
Группа: Модераторы
Сообщений: 6729
Награды: 1
Репутация: 1867
Блокировки:
Quote (FatalBlade)
Нельзя для всех сделать 1.
Можно. Заводишь для каждого скилла действительную, отвечающую за время таймера. При каждом истечении таймера прибавляешь к каждой переменной период единого таймера. Если переменная превышает период ее воображаемого таймера, выполняешь действия этого скилла и обнуляешь ее.


 

HexingДата: Пятница, 05 Августа 2011, 09:20:14 | Сообщение # 25
10 уровень
Группа: Проверенные
Сообщений: 1645
Награды: 1
Репутация: 432
Блокировки:
Quote (SirNikolas)
Можно. Заводишь для каждого скилла действительную, отвечающую за время таймера. При каждом истечении таймера прибавляешь к каждой переменной период единого таймера. Если переменная превышает период ее воображаемого таймера, выполняешь действия этого скилла и обнуляешь ее.

каждый раз, создавая local timer t, движок добавляет таймер в массив, и сам увеличивает время таймера каждый период "шага" движка. А повешенные StartTimer() - лишь как таковое addActions() к таймеру. Так что думаю твой вариант будет менее удобен, и менее быстродействующий(хотя хз).


 

Форум о Warcraft 3 » Раздел для картостроителей » GUI / Jass » Создание и удаление таймера (Надо ли это? Или можно пользоваться одним глобальным?)
  • Страница 1 из 2
  • 1
  • 2
  • »
Поиск:

Copyright © 2006 - 2024 Warcraft3FT.info При копировании материалов c сайта ставьте, пожалуйста, активную обратную ссылку на нас • Design by gReeB04ki ©
Хостинг от uCoz