Добавлен , опубликован
Алгоритмы, Наработки и Способности
Способ реализации:
Jass
Тип:
Алгоритм
Давно искал что-то подобное, но так и не нашёл. Возможно, банальщина, но для меня было открытие. (Статью можно доработать вставками кода на Lua).

Начнём с проблемы

Если запустить таймер в рамках конструкции GetLocalPlayer(), то в итоге получим десинхрон.
Код (vJass)
globals
	framehandle Image
endglobals

private function TimerTick takes nothing returns nothing
	call BlzFrameSetAlpha(Image, BlzFrameGetAlpha(Image)-10)
endfunction

//*******************************************************************************************
private function CreateUI takes nothing returns nothing
	local framehandle gameUI = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)

	set Image = BlzCreateFrameByType("BACKDROP", "", gameUI , "StandardFrameTemplate", 0)
	call BlzFrameSetSize(Image, 0.1, 0.1)
	call BlzFrameSetPoint(Image, FRAMEPOINT_CENTER, gameUI, FRAMEPOINT_CENTER, .0, .0)
	call BlzFrameSetTexture(Image, "ReplaceableTextures\\CommandButtons\\BTNSorceressV1.blp", 0, true)

	set gameUI = null
endfunction

function onInit takes nothing returns nothing
	local timer myTimer = CreateTimer()

	call CreateUI()

	if GetLocalPlayer() == Player(0) then
		call TimerStart(myTimer, 0.01, true, function TimerTick)
	endif
	set myTimer  = null
endfunction
Видео (попытка менять прозрачность фрейма через локально запущенный таймер)

Решение

Для локального игрока запустим периодический таймер, для всех остальных таймер будет запущен как одноразовый. В качестве аргумента функции TimerStart под названием periodic передаём значение GetLocalPlayer() == Player(индекс игрока).
Код (vJass)
globals
	framehandle Image
endglobals

private function TimerTick takes nothing returns nothing
	call BlzFrameSetAlpha(Image, BlzFrameGetAlpha(Image)-10)
endfunction

//*******************************************************************************************
private function CreateUI takes nothing returns nothing
	local framehandle gameUI = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)

	set Image = BlzCreateFrameByType("BACKDROP", "", gameUI , "StandardFrameTemplate", 0)
	call BlzFrameSetSize(Image, 0.1, 0.1)
	call BlzFrameSetPoint(Image, FRAMEPOINT_CENTER, gameUI, FRAMEPOINT_CENTER, .0, .0)
	call BlzFrameSetTexture(Image, "ReplaceableTextures\\CommandButtons\\BTNSorceressV1.blp", 0, true)

	set gameUI = null
endfunction

function onInit takes nothing returns nothing
	local timer localTimer = CreateTimer()
	call CreateUI()
	call TimerStart(localTimer, 0.1, GetLocalPlayer() == Player(0), function TimerTick)
endfunction
Видео (меняем прозрачность фрейма через локально периодический таймер)
Чтобы реализовать локальный таймер для нескольких игроков, создаём N таймеров, каждый из которых не является периодическим для всех игроков, но для конкретного локального игрока его экземпляр таймера будет являться периодическим.
Код (vJass)
private function CreateTimers takes nothing returns nothing 
	local integer np = 0
	local timer array localTimer
	loop
		exitwhen np > 23
			set localTimer[np] = CreateTimer()
			call TimerStart(localTimer[np], 0.1, GetLocalPlayer() == Player(np), function TimerTick)
			set localTimer[np] = null
		set np = np + 1
	endloop
endfunction

Применение

Всё периодическое, что не требует синхронизации, делаем локально и радуемся оптимизации, а также независимости от пинга хоста (камера, анимация фреймов, положение спецэффектов и прочее).
`
ОЖИДАНИЕ РЕКЛАМЫ...
0
29
1 год назад
Отредактирован nazarpunk
0
По сути необходимо создать таймер для всех, а запускать уже можно локально? Прям как с texttag.

По логике тут дело в хэндлах. Не создав таймер для другогих игроков номера выделяемых хэндлов разойдутся. Ради эксперимента можно создать остальным игрокам Texttag вместо таймера. Если дело в номерации хэндлов, то должно прокатить.
0
7
1 год назад
Отредактирован Brilock
0
По сути необходимо создать таймер для всех, а запускать уже можно локально? Прям как с texttag.
Именно об этом я пишу в самом начале, что так не работает. Тут смысл в том, чтобы запустить таймер у всех одновременно, но что с ним будет дальше - зависит от локального игрока.
0
5
1 год назад
0
Круто!
Чтобы оставить комментарий, пожалуйста, войдите на сайт.