кратко: существуют экранные координаты (координаты на экране), так и мировые координаты (координаты на карте). Нам нужно вычислить координаты курсора мыши на экране. Близзард предоставили нам только нативки определения курсора мыши на карте.
Move Able Frame - система, которая позволяет перемещать фрейм за курсором мыши. Проблема вот в чем, игра не может нам выдать координаты мыши на экране, мы можем получить только координаты мыши на карте, которые недавно преподнесли разработчики игры. Мы не сможем переместить фрейм, не зная текущие координаты мыши на экране. Проблема была решена таким образом, создаются невидимые пустые-фреймы. Ранее был похожий пример. Когда курсор мыши наводят на фрейм, реагирует триггер. Но как этот пример поможет решить проблемы? А тут можно использовать этот же метод, только весь экран делим на клеточки. весь экран разбит на сетку фреймами 0,01x0,01 маленькие фреймы. Полный экран это 0.8, 0.6, получается фреймов 80x60=4800
Когда вы перемещает курсор мыши, вы всегда будете знать в какую часть экрана расположен курсор мыши. Когда курсор попадает внутри фрейма, вы будете знать в какой части экрана лежит курсор благодаря событиям фреймов
источник <= тут есть карта с lua-кодом, а в комментах коды jass и пр
memhack <= с такой проблемой возиться не нужно на старых патчах 1.26-1.27
mouse camera system еще один <= тут придумана система. только тут управление камерой фреймами. А не определение координат положения мыши. Возможно, тут на основе данных можно вращать не камеру, а мышь.
snippet-mouse-utility <= тут используют систему для нахождения игровых координат (не экранных!!!). Считают, что использовать нативки для определения курсора мыши плохо или неудобно, тк они используют события, а события движения мыши реагируют не чаще 0.15 сек.
framenet <= ну и еще один пример
источник <= тут есть карта с lua-кодом, а в комментах коды jass и пр
memhack <= с такой проблемой возиться не нужно на старых патчах 1.26-1.27
mouse camera system еще один <= тут придумана система. только тут управление камерой фреймами. А не определение координат положения мыши. Возможно, тут на основе данных можно вращать не камеру, а мышь.
snippet-mouse-utility <= тут используют систему для нахождения игровых координат (не экранных!!!). Считают, что использовать нативки для определения курсора мыши плохо или неудобно, тк они используют события, а события движения мыши реагируют не чаще 0.15 сек.
framenet <= ну и еще один пример
Move Able Frame - это ресурс Lua, который позволяет пользователю перемещать фреймы с помощью перетаскивания (drag and drop). Другого применения кроме как перетаскивания не найти. Пользователь щелкает правой кнопкой мыши фрейм, и пока он удерживает правую кнопку мыши, фрейм будет следовать за мышью. Только фреймы, поддерживающие событие Frame Mouse Enter, могут быть перемещены с помощью этого ресурса. Он использует модифицированную версию глобального init от Bribe.
lua код - инициируем базу данных фреймов
--[[FrameGrid by Tasyen
--Got that Idea from CanFight, he mentioned something about a FPS game in which he clustered the screen with Frames to know the mouse position.
function FrameGrid.show(flag, player)
show/hide the grid for player nil or GetLocalPlayer affect all players
--]]
FrameGrid = {}
FrameGrid.Boss = nil --the parent hide/show it to enable/disable the functionality of this system.
FrameGrid.GridFrames = {} --all grid frames
FrameGrid.GridFrames2 = {} --the tooltip frames of the grid
FrameGrid.LastFrame = 0 --the index of the frame hovered by the mouse, might be incorrect sometimes
onGameStart(function()
-- print("FrameGrid.Init")
FrameGrid.Timer = CreateTimer()
TimerStart(FrameGrid.Timer, 0.01, true, FrameGrid.update)
--the Grid Boss Frame its a BUTTON so it can have a higher Frame Level.
--This Frame is used as on/off, when showing it the FrameGrid becomes active while it does nothing when Boss is disabled.
FrameGrid.Boss = BlzCreateFrameByType("BUTTON", "FrameGridBoss", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0),"",0)
--be above other frames, using this allows to move into other frames but also stops their mouse enter events while FrameGrid is active.
--I wasn't able to change this value at a later time hence there is no swap for this.
--BlzFrameSetLevel(FrameGrid.Boss, 7)
local xSize = 0.01 --dont go to low
local ySize = 0.01 --dont go to low
local yStart = ySize/2
local xStart = xSize/2
FrameGrid.FramesEachCol = 0.6 / ySize
for x = xStart, 0.8, xSize do
for y = yStart, 0.6, ySize do
local newButton = BlzCreateFrameByType("FRAME", "", FrameGrid.Boss,"",0)
local tooltipButton = BlzCreateFrameByType("FRAME", "", FrameGrid.Boss,"",0)
BlzFrameSetAbsPoint(newButton, FRAMEPOINT_CENTER, x, y)
BlzFrameSetSize(newButton, xSize, ySize)
BlzFrameSetTooltip(newButton, tooltipButton)
BlzFrameSetEnable(newButton, false)
BlzFrameSetEnable(tooltipButton, false)
FrameGrid[newButton] = {x, y}
FrameGrid[tooltipButton] = {x, y}
table.insert(FrameGrid.GridFrames, newButton)
table.insert(FrameGrid.GridFrames2, tooltipButton)
end
end
BlzFrameSetVisible(FrameGrid.Boss, false)
end)
Подвижная система такая:
lua код - проверяем
--[[
MoveAbleFrame (Mini) by Tasyen
MoveAbleFrame allows to drag&drop frames you have setuped to be moveable. This System is async do not use anthing of it in a sync manner. (Mini) does not save frame positions
function MoveAbleFrame.setup(frame)
makes this frame moveable by user with drag and drop, only works on frameTypes supporting FRAMEEVENT_MOUSE_ENTER and FRAMEEVENT_MOUSE_LEAVE
has to be called sync cause it creates events, unlike the other userMoveAbleFrame functions which should be used async
The user changed position can be saved in a file and loaded. The frames are identyfied by the order, they were added to userMoveAbleFrame.
Means when adding new userMoveAbleFrames not to the end (order wise), then a saved File can move a wrong frame when loading an File saved with an old version.
function MoveAbleFrame.enable(player[, flag])
(dis)allows drag and drop moveable Frames for player, use GetLocalPlayer() to affect all players
can be called without flag in such a case the current value is negated. true <-> false
this has no impact on current done drag&dropping
returns the value of MoveAbleFrame.Enabled
--]]
MoveAbleFrame = {}
MoveAbleFrame.Enabled = false --only when this is true, right clicking will have an effect on frames
MoveAbleFrame.Frame = nil -- the Frame beeing Moved
MoveAbleFrame.FramePoint = nil -- the FramePoint Frame is posed with nil = CENTER
function MoveAbleFrame.startMoving(frame, framePoint)
MoveAbleFrame.Frame = frame
if not framePoint then
framePoint = FRAMEPOINT_CENTER
end
MoveAbleFrame.FramePoint = framePoint
FrameGrid.show(true)
end
function MoveAbleFrame.moveFrame(x, y, finish)
BlzFrameClearAllPoints(MoveAbleFrame.Frame)
BlzFrameSetAbsPoint(MoveAbleFrame.Frame, MoveAbleFrame.FramePoint, x, y)
if finish then
FrameGrid.show(false)
end
end
function MoveAbleFrame.enable(player, flag)
if GetLocalPlayer() == player then
if flag == nil then
MoveAbleFrame.Enabled = not MoveAbleFrame.Enabled
else
MoveAbleFrame.Enabled = flag
end
end
return MoveAbleFrame.Enabled
end
function MoveAbleFrame.setup(frame)
if not MoveAbleFrame[frame] then
MoveAbleFrame[frame] = true
BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameEnter, frame, FRAMEEVENT_MOUSE_ENTER) --enable the hover feature
BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameLeave , frame, FRAMEEVENT_MOUSE_LEAVE)
end
end
onTriggerInit(function()
xpcall(function()
-- print("MoveAbleFrame.Init")
--this is the FrameEnter Event trigger, every moveable Frame calls it, when entering remember the entere Frame
MoveAbleFrame.TriggerFrameEnter = CreateTrigger()
MoveAbleFrame.TriggerFrameEnterAction = TriggerAddAction(MoveAbleFrame.TriggerFrameEnter, function()
if GetLocalPlayer() == GetTriggerPlayer() then
MoveAbleFrame.PlayerHoveredFrame = BlzGetTriggerFrame()
end
end)
MoveAbleFrame.TriggerFrameLeave = CreateTrigger()
MoveAbleFrame.TriggerFrameLeaveAction = TriggerAddAction(MoveAbleFrame.TriggerFrameLeave, function()
if GetLocalPlayer() == GetTriggerPlayer() then
MoveAbleFrame.PlayerHoveredFrame = nil
end
end)
MoveAbleFrame.MouseClickTrigger = CreateTrigger()
MoveAbleFrame.MouseClickTriggerAction = TriggerAddAction(MoveAbleFrame.MouseClickTrigger, function()
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
local player = GetTriggerPlayer()
if MoveAbleFrame.PlayerHoveredFrame then
--UI Edit Mode start moving that frame
if MoveAbleFrame.Enabled then
if GetLocalPlayer() == player then
MoveAbleFrame.startMoving(MoveAbleFrame.PlayerHoveredFrame)
--disable the moving frame so it does not send mouse enter events, is more accurate to move and other frames are better respecected
BlzFrameSetEnable(MoveAbleFrame.PlayerHoveredFrame, false)
end
end
end
end
end)
MoveAbleFrame.MouseReleaseTrigger = CreateTrigger()
MoveAbleFrame.MouseReleaseTriggerAction = TriggerAddAction(MoveAbleFrame.MouseReleaseTrigger, function()
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
--reenable the movedFrame, if there is one
if MoveAbleFrame.Frame then
BlzFrameSetEnable(MoveAbleFrame.Frame, true)
end
--UI Edit Mode start moving that frame
FrameGrid.show(false, GetTriggerPlayer())
end
end)
for playerIndex = 0, GetBJMaxPlayers()-1,1 do
TriggerRegisterPlayerEvent(MoveAbleFrame.MouseClickTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_DOWN)
TriggerRegisterPlayerEvent(MoveAbleFrame.MouseReleaseTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_UP)
end
end, err)
end)
Проблема вот в чем, перемещение за курсором происходит рывками, как на gif-ке. Для того, чтобы получить сглаживание, необходимо следить за таймингами и уменьшать размер сетки, короче сделать размер фрейма еще меньше, чем было ранее (w=0.01, h=0.01). Но при создании сетки меньше чем 80x60 в сотни раз, мне комп говорит пока, и игра зависает сильно.
Нужно придумать такую систему, где либо используется минимальное число фреймов, и при этом при перемещении нет рывков.
Нужно придумать такую систему, где либо используется минимальное число фреймов, и при этом при перемещении нет рывков.
Мне удавалось найти такие сочетания. Легко дебаг быстро определял координаты мыши. Однако, перемещения фреймов всегда происходят с задержками, рывками или зависаниями-дерганием. Замечал, что нативные функции фреймов медлительны. Для того, чтобы переместить его, делает с задержкой. Для того, чтобы скрыть/отобразить - тоже какая-то задержка. Появления подсказок - тоже не сразу появляются, на этом строится вся система отлова мыши. Ребята с хгм мне объяснили, что задержка происходит из-за синхронизации. Поэтому перетаскивания мб с рывками.
Еще проблема в том, что сетка часто накрывая экран, прячет куда-то дефолтный интерфейс. Происходит это из-за подобранного родителя. Если родителя ConsoleUIBackdrop подобрать, то у меня исчезают все кроме CommandBar. Дефотный можно заменить другим.
А еще главное требование - возможность кликать свободно по экрану. Посмотрел многие системы, и у некоторых проблемы с свободными кликами по карте: в точку, юниты, декор, итемы. Сетка накрывает сверху, и поэтому никак не выделить объекты на карте. Клики идут по фреймам сетки. Можно сделать зазор в данной точке, как только обнаруживается положение курсора, но это оч плохо работает. Задержками.
Способы оптимизации
Метод с уменьшением числа фреймов (!!не оптимизирована!!)
пример мы создаем фрейм размером 1 x 1. Пример экран забит 5x5 фреймами - 25 фреймов
мы можем уменьшить в несколько раз. Пример 5 горизонтальных фрейма (5x1) и 5 вертикальных фрейма (1x5). В итоге 5+5=10 фреймов
это сильно помогло бы уменьшить число фреймов. Вместо 80x60=4800 фреймов выше, могли бы сократить до 80+60=140 фреймов.
это сильно помогло бы уменьшить число фреймов. Вместо 80x60=4800 фреймов выше, могли бы сократить до 80+60=140 фреймов.
вывод: этот метод оптимизации плохой. Фреймы друг на друга наслаиваются, и вычислить можно только фрейм с высоким уровнем. Вам нужно будет перключать горизонтальную сетку - для проверки координаты y. А потом на вертикальную - для определния координаты x. А в промежутках отключать нужные фреймы (x,y), чтобы мышка могла кликать
Но тут то прокол: частота появления подсказок, короче нужно время для появления подсказки, нужен таймер с 0.01-0.02 сек. Когда вы отключаете выбранный фрейм, подсказка этого фрейма должна перестать работать. курсор перепрыгивает на другой фрейм, и подсказка сменяется. Смена происходит не сразу. Поэтому нужна задержка.
существует два таймера: основной и дополнительный. основной таймер каждые 1/3 сек запускает процесс проверки. здесь сразу же включаем показ горизонтальной сетки, через 0.01-0.02 сек доп таймером проверяем в каком горизонтальном фрейме лежит, и сразу же выключаем горизонтальную сетку и включаем вертикальную. через 0.01-0.02 сек доп таймером проверяем в каком вертикальном фрейм расположен, и сразу же выключаем. так мы получаем координаты x,y. Явный изврат с задержками, но что поделать то. Можно уменьшить, но главное вы поняли как работать с этим.
Вывод: Но такое очень плохо работает, дело в том, что фокус с фреймов снимается не сразу, обновляется не сразу, может что-то не обновится. И я все равно не смог сделать сглаживание, рывками перемещается. Тут со временем проблемы, каждый 0.03 сек запускает процесс проверки (включили сетку x), и еще два раза запускаем последовательно таймер 0.02 (проверили ось x, и выключили сетку x, включили сетку y потом задержка -> проверили ось y, выключили сетку).
существует два таймера: основной и дополнительный. основной таймер каждые 1/3 сек запускает процесс проверки. здесь сразу же включаем показ горизонтальной сетки, через 0.01-0.02 сек доп таймером проверяем в каком горизонтальном фрейме лежит, и сразу же выключаем горизонтальную сетку и включаем вертикальную. через 0.01-0.02 сек доп таймером проверяем в каком вертикальном фрейм расположен, и сразу же выключаем. так мы получаем координаты x,y. Явный изврат с задержками, но что поделать то. Можно уменьшить, но главное вы поняли как работать с этим.
Вывод: Но такое очень плохо работает, дело в том, что фокус с фреймов снимается не сразу, обновляется не сразу, может что-то не обновится. И я все равно не смог сделать сглаживание, рывками перемещается. Тут со временем проблемы, каждый 0.03 сек запускает процесс проверки (включили сетку x), и еще два раза запускаем последовательно таймер 0.02 (проверили ось x, и выключили сетку x, включили сетку y потом задержка -> проверили ось y, выключили сетку).
кода и образцов не осталось.
вариант с зазорами (!!не работает!!)
кратко: не сказал бы, что плохо работает. Но и идеальным сложно назвать, пытался сделать объекты на карте максимально кликабельными, но такого сложно осуществить (в месте появления курсора фрейм исчезает, и появляется, как только курсор покидает область. В момент клика мб фрейм может не успеть исчезнуть). Размер сетки теперь можно уменьшить, что повысит точность. Но и проблемы остаются. Дело в том, что рывки все равно остаются, как бы не решали этот вопрос. Но зато они едва заметны. Тут зависит от того, как часто обновляется подсказка. Именно от этого зависит обновление информации. Если бы она сразу обновлялась, тогда не было никаких претензии, и создали бы идеальный костыль.
Можно переделать этот способ - создать зазоры между фреймами. типа так:
Можно переделать этот способ - создать зазоры между фреймами. типа так:
Вывод: пробовал использовать данный метод. Особое внимание - уменьшены фреймы до 1600 для сетки 0.001x0/001. Вроде работает хорошо, координаты быстро отображает. Но как только пытаешься двигать кнопку за курсором, то тут же возникают проблемы. Внимает забирает на себя эта кнопка, если только ее не отключить, и отключенной двигать. Вторая проблема (очень-очень важна!) - когда курсор лежит на вертикальном фрейме, я могу вдоль оси y двигать, не касаясь других, и почему то никак не замечаю изменения вдоль оси y - недостаток огромный.
Не знаю стоило ли скидывать код сюда?
II Метод разбивать фреймы на группы/секторы
Еще можно попробовать разбить экран на секторы. Изначально на весь экран создают сетку фреймов. Обычно когда у вас на экране очень много фреймов, у вас подлагивает. Стоит их отключить, спрятать. У отключенных фреймов не работают события, и у вас не должно подлагивать. Часть фреймов привязывают к одному большому фрейму, и так разбиваем на секторы. Когда курсор мыши входит в сектор, то включаем этот сетку сектора, а сетку старого отключаем. Надо просто включать часть фреймов и отключать другую часть.
Тут можно различными способами разбивать на секторы. Тут как вы хотите, так и будет. Есть различные варианты, я создал в качестве примера самый простой способ. Можно разбить экран на большую сетку 6x3 из 18 фреймов, каждый из которых может состоят из еще меньшей сетки. Как только курсор оказывается в одном из 18 больших фреймов, меняем большой фрейм на маленькую сетку. Маленькая сетка вычисляется по формуле, и зависит от размера size.
Мы прячем, и меняем так выбранный курсором фрейм на меньшую сетку, таким образом переключая с одного на другого. Дело в том, что не сразу меняется подсказка, нужна задержка 0.01-0.02 сек. Чем больше у вас сеток (большая, средняя, маленькая сетки фреймов), тем больше переключении => была самая большая 18, в одном из больших переключили на среднюю сетку => можно сделать еще переключения с средней на меньшую, если вам важна точность.
Можно по разному создавать систему. В одной из системы я видел как парень Nelloy создает сетку из 18 фреймов.
Мы прячем, и меняем так выбранный курсором фрейм на меньшую сетку, таким образом переключая с одного на другого. Дело в том, что не сразу меняется подсказка, нужна задержка 0.01-0.02 сек. Чем больше у вас сеток (большая, средняя, маленькая сетки фреймов), тем больше переключении => была самая большая 18, в одном из больших переключили на среднюю сетку => можно сделать еще переключения с средней на меньшую, если вам важна точность.
Можно по разному создавать систему. В одной из системы я видел как парень Nelloy создает сетку из 18 фреймов.
lua код
do
local InitGlobalsOrigin = InitGlobals -- хукаем функцию InitGlobals
function InitGlobals()
InitGlobalsOrigin()
--инициируем сетку
function PXTODPI()
return 0.6 / BlzGetLocalClientHeight()
end
function DPITOPX()
return BlzGetLocalClientHeight() / 0.6
end
function FrameBoundWidth()
return (BlzGetLocalClientWidth()-BlzGetLocalClientHeight()/600*800)/2
end
function GetScreenPosX(x)
return (-FrameBoundWidth()+x)*PXTODPI()
end
function GetScreenPosY(y)
return y*PXTODPI()
end
function ScreenRelativeX(x)
return (x * DPITOPX()) * (0.8/BlzGetLocalClientWidth())
end
--print("инициируем большую сетку")
--родитель большой сетки, короче всего экрана
local parent = BlzGetFrameByName("ConsoleUIBackdrop", 0)
--фрейм-кнопки
local btns = {}
--фрейм-подсказки
local tools = {}
--координаты
local CoordXParentFrame = {}
local CoordYParentFrame = {}
local CoordXFrame = {}
local CoordYFrame = {}
--координата нижнего-левого угла
local startx = GetScreenPosX(0.0)
local starty = GetScreenPosY(0.0)
--скалированный размер
local ScaleSizeX = (startx^2)^0.5
--размеры экрана
local width = GetScreenPosX(BlzGetLocalClientWidth())+ScaleSizeX
local height = GetScreenPosY(BlzGetLocalClientHeight())
print("ширина: "..width.." ,высота: "..height)
--БОЛЬШАЯ СЕТКА
--кол-во строк и столбцов
local COLS = 6
local ROWS = 3
print("число строк: "..COLS.." ,число столбцов: "..ROWS)
local xsize = width/6
local ysize = height/3
--МАЛЕНЬКАЯ СЕТКА
local size = 0.01
local countx = xsize/size
local county = ysize/size
local xoffset = size/2
local yoffset = size/2
local sbtns = {}
local stools = {}
--
print("стартовые размеры экрана: "..startx..","..starty )
BlzHideOriginFrames (true)
BlzFrameSetScale(BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),5), 0.001)
for x = 1, COLS do
btns[x] = {}
tools[x] = {}
for y = 1, ROWS do
local sx =startx+(xsize*(x-1))
local sy =starty+(ysize*(y-1))
btns[x][y] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(btns[x][y], 25)
BlzFrameSetAbsPoint(btns[x][y], FRAMEPOINT_BOTTOMLEFT, sx, sy)
BlzFrameSetSize(btns[x][y], xsize, ysize)
tools[x][y] = BlzCreateFrameByType("FRAME", "FaceFrame", parent, "", 0)
BlzFrameSetAlpha(tools[x][y], 0)
BlzFrameSetAbsPoint(tools[x][y], FRAMEPOINT_BOTTOMLEFT, 0, 0)
BlzFrameSetSize(tools[x][y], 0, 0)
CoordXParentFrame[GetHandleId(btns[x][y])] = sx
CoordYParentFrame[GetHandleId(btns[x][y])] = sy
BlzFrameSetTooltip(btns[x][y], tools[x][y])
end
end
local grid = BlzCreateFrameByType("FRAME", "FaceFrame", parent, "", 0)
BlzFrameSetAlpha(grid, 0)
BlzFrameSetAbsPoint(grid, FRAMEPOINT_BOTTOMLEFT, 0, 0)
BlzFrameSetSize(grid, size, size)
--BlzFrameSetVisible(grid, false)
for ax = 1, countx do
sbtns[ax] = {}
stools[ax] = {}
for ay = 1, county do
sbtns[ax][ay] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", grid, "ScriptDialogButton", 0)
BlzFrameSetAlpha(sbtns[ax][ay], 25)
BlzFrameSetPoint(sbtns[ax][ay], FRAMEPOINT_CENTER, grid, FRAMEPOINT_BOTTOMLEFT, (size*(ax-1))+xoffset, (size*(ay-1))+xoffset)
BlzFrameSetSize(sbtns[ax][ay], size, size)
--BlzFrameSetVisible(sbtns[ax][ay], false)
stools[ax][ay] = BlzCreateFrameByType("FRAME", "FaceFrame", parent, "", 0)
BlzFrameSetAlpha(stools[ax][ay], 0)
BlzFrameSetAbsPoint(stools[ax][ay], FRAMEPOINT_CENTER, 0, 0)
BlzFrameSetSize(stools[ax][ay], 0, 0)
--BlzFrameSetVisible(stools[ax][ay], false)
CoordXFrame[GetHandleId(sbtns[ax][ay])] = (size*(ax-1))+xoffset
CoordYFrame[GetHandleId(sbtns[ax][ay])] = (size*(ay-1))+xoffset
BlzFrameSetTooltip(sbtns[ax][ay], stools[ax][ay])
end
end
function ShowGrid(parent,show)
local count = BlzFrameGetChildrenCount(parent)-1
for i = 1, count do
BlzFrameSetVisible(BlzFrameGetChild(parent,i),show)
end
--if show then
-- print("включить мелкую сетку "..CoordXParentFrame[GetHandleId(parent)]..","..CoordYParentFrame[GetHandleId(parent)])
--else
-- print("выключить мелкую сетку "..CoordXParentFrame[GetHandleId(parent)]..","..CoordYParentFrame[GetHandleId(parent)])
--end
end
local frameblock = nil
local lastframe = nil
local sx
local sy
TimerStart(CreateTimer(),0.2,true,function()
local b = true
for x = 1, COLS do
for y = 1, ROWS do
local found = BlzFrameIsVisible(tools[x][y]) and lastframe ~= btns[x][y]
if (found) then
print("найден курсор в секторе "..x..","..y)
if lastframe ~= nil then
b = false
BlzFrameSetVisible(lastframe,true)
end
lastframe = btns[x][y]
sx =CoordXParentFrame[GetHandleId(lastframe)]
sy =CoordYParentFrame[GetHandleId(lastframe)]
print(sx..","..sy)
BlzFrameSetAbsPoint(grid, FRAMEPOINT_BOTTOMLEFT, sx, sy)
BlzFrameSetVisible(lastframe,false)
do return end
end
end
end
if b then
for ax = 1, countx do
for ay = 1, county do
local found = BlzFrameIsVisible(stools[ax][ay])
if (found) then
if frameblock ~= sbtns[ax][ay] then
BlzFrameSetVisible(frameblock,true)
frameblock = sbtns[ax][ay]
BlzFrameSetVisible(frameblock,false)
print(CoordXParentFrame[GetHandleId(lastframe)]+CoordXFrame[GetHandleId(frameblock)]..","..CoordYParentFrame[GetHandleId(lastframe)]+CoordYFrame[GetHandleId(frameblock)])
do return end
end
end
end
end
end
end)
local MouseDown = CreateTrigger()
TriggerRegisterPlayerMouseEventBJ( MouseDown, Player(0), bj_MOUSEEVENTTYPE_DOWN )
TriggerAddAction( MouseDown, function ()
BlzFrameSetVisible(grid,false)
end)
local MouseUp = CreateTrigger()
TriggerRegisterPlayerMouseEventBJ( MouseUp, Player(0), bj_MOUSEEVENTTYPE_UP )
TriggerAddAction( MouseUp, function ()
BlzFrameSetVisible(grid,true)
end)
end
end
Вывод:
проблемы те же. задержки, также плохо со свободным кликом по карте.
проблемы те же. задержки, также плохо со свободным кликом по карте.
III Метод создать рамку вокруг курсора
В середине квадрата должен находится курсор мыши. Вокруг него 8 фреймов, когда курсор входит в один из них, то засекается tooltips, и сдвигаем. Короче квадрат должен двигаться за курсором. Как только вы пытаетесь сдвинуть курсор, то квадрат перемещается за курсором.
Недостаток: это работает очень плохо. Дело в том, что всплывающая подсказка (tooltip) появляется не сразу. И стоит быстро прокрутить мышь, и все. Курсор теперь лежит не внутри. Решение: растянуть на весь экран (см. ниже скрин). Тогда вы точно сможете найти координаты. Однако, обновляется не сразу. И эти фреймы теперь нельзя сделать прозрачными, придется использовать пустой шаблон вместо ScriptDialogButton. Вам нужно будет убрать “ScriptDialogButton”, чтобы они стали невидимыми
Недостаток: это работает очень плохо. Дело в том, что всплывающая подсказка (tooltip) появляется не сразу. И стоит быстро прокрутить мышь, и все. Курсор теперь лежит не внутри. Решение: растянуть на весь экран (см. ниже скрин). Тогда вы точно сможете найти координаты. Однако, обновляется не сразу. И эти фреймы теперь нельзя сделать прозрачными, придется использовать пустой шаблон вместо ScriptDialogButton. Вам нужно будет убрать “ScriptDialogButton”, чтобы они стали невидимыми
Недостаток: прямоугольная система из 8 фреймов перемещается не мгновенно. Стоит крутануть мышью из одного угла в другой угол экрана, то центр этих фреймов перемещается со скоростью b/interval. b - размер квадрата, interval - время таймера не меньше 0.01. Чем меньше размер b, тем выше точность, и одновременно, долгое перемещение. А вот interval зависим от tooltip, если сделать меньше 0.01, то подсказка не успевает скрыться, а уже таймер обработает несколько раз, что может вылететь за пределы экрана.
Иногда может дергаться, прыгать туда-туда. Причины неизвестны, возможна проблемы с размерами. Вот хотел заснять видео-пример, но при съемке прыгает. Поэтому мне и не удалось снять
lua код
do
local real = MarkGameStarted
function MarkGameStarted()
real()
local b = 0.01 --размер квадрата
local c = 0.8
local h = 0.6
local a = b*3 --размер квадрата
local offset = b
local cx,cy = 0.4,0.3 --координаты центра квадрата
local parent = BlzGetFrameByName("ConsoleUIBackdrop", 0)
local gameUI = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)
local btns = {}
local tools = {}
local CoordX = {}
local CoordY = {}
--Верхний левый угол
btns[1] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(btns[1], 25)
BlzFrameSetAbsPoint(btns[1], FRAMEPOINT_BOTTOMRIGHT,cx-b,cy+b)
BlzFrameSetLevel(btns[1], 2)
BlzFrameSetSize(btns[1], c, h)
CoordX[GetHandleId(btns[1])]=cx-offset
CoordY[GetHandleId(btns[1])]=cy+offset
--верхний фрейм
btns[2] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(btns[2], 25)
BlzFrameSetPoint(btns[2], FRAMEPOINT_BOTTOMLEFT, btns[1],FRAMEPOINT_BOTTOMRIGHT,0,0)
BlzFrameSetLevel(btns[2], 2)
BlzFrameSetSize(btns[2], b, h)
CoordX[GetHandleId(btns[2])]=cx
CoordY[GetHandleId(btns[2])]=cy+offset
--Верхний правый угол
btns[3] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(btns[3], 25)
BlzFrameSetPoint(btns[3], FRAMEPOINT_BOTTOMLEFT, btns[2],FRAMEPOINT_BOTTOMRIGHT,0,0)
BlzFrameSetLevel(btns[3], 2)
BlzFrameSetSize(btns[3], c, h)
CoordX[GetHandleId(btns[3])]=cx+offset
CoordY[GetHandleId(btns[3])]=cy+offset
--правый фрейм
btns[4] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(btns[4], 25)
BlzFrameSetPoint(btns[4], FRAMEPOINT_TOPLEFT, btns[3],FRAMEPOINT_BOTTOMLEFT,0,0)
BlzFrameSetLevel(btns[4], 2)
BlzFrameSetSize(btns[4], c, b)
CoordX[GetHandleId(btns[4])]=cx+offset
CoordY[GetHandleId(btns[4])]=cy
--нижний правый угол
btns[5] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(btns[5], 25)
BlzFrameSetPoint(btns[5], FRAMEPOINT_TOPRIGHT, btns[4],FRAMEPOINT_BOTTOMRIGHT,0,0)
BlzFrameSetLevel(btns[5], 2)
BlzFrameSetSize(btns[5], c, h)
CoordX[GetHandleId(btns[5])]=cx+offset
CoordY[GetHandleId(btns[5])]=cy-offset
--нижний фрейм
btns[6] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(btns[6], 25)
BlzFrameSetPoint(btns[6], FRAMEPOINT_TOPRIGHT, btns[5],FRAMEPOINT_TOPLEFT,0,0)
BlzFrameSetLevel(btns[6], 2)
BlzFrameSetSize(btns[6], b, h)
CoordX[GetHandleId(btns[6])]=cx
CoordY[GetHandleId(btns[6])]=cy-offset
--нижний левый угол
btns[7] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(btns[7], 0)
BlzFrameSetPoint(btns[7], FRAMEPOINT_TOPRIGHT, btns[6],FRAMEPOINT_TOPLEFT,0,0)
BlzFrameSetLevel(btns[7], 2)
BlzFrameSetSize(btns[7], c, h)
CoordX[GetHandleId(btns[7])]=cx-offset
CoordY[GetHandleId(btns[7])]=cy-offset
--левый фрейм
btns[8] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(btns[8], 25)
BlzFrameSetPoint(btns[8], FRAMEPOINT_BOTTOMLEFT, btns[7],FRAMEPOINT_TOPLEFT,0,0)
BlzFrameSetLevel(btns[8], 2)
BlzFrameSetSize(btns[8], c, b)
CoordX[GetHandleId(btns[8])]=cx-offset
CoordY[GetHandleId(btns[8])]=cy
for i = 1, 8 do
tools[i] = BlzCreateFrameByType("FRAME", "FaceFrame", parent, "", 0)
BlzFrameSetAlpha(tools[i], 0)
BlzFrameSetAbsPoint(tools[i], FRAMEPOINT_BOTTOMLEFT, 0, 0)
BlzFrameSetLevel(tools[i], 2)
BlzFrameSetSize(tools[i], 0, 0)
BlzFrameSetVisible(tools[i], false)
BlzFrameSetTooltip(btns[i], tools[i])
end
--фитсируем курсор мышь в центре экрана
TimerStart(CreateTimer(),0.1,false,function()
BlzSetMousePos(BlzGetLocalClientWidth()/2, BlzGetLocalClientHeight()/2)
--и таймером теперь чекаем
TimerStart(CreateTimer(),0.01,true,function()
for i = 1, 8 do
local found = BlzFrameIsVisible(tools[i])
if (found) then
--BlzFrameSetVisible(tools[i], false)
cx = CoordX[GetHandleId(btns[i])]
cy = CoordY[GetHandleId(btns[i])]
print("найден курсор в секторе "..cx..","..cy)
BlzFrameSetAbsPoint(btns[1], FRAMEPOINT_BOTTOMRIGHT,cx-b,cy+b)
CoordX[GetHandleId(btns[1])]=cx-offset
CoordY[GetHandleId(btns[1])]=cy+offset
--BlzFrameSetAbsPoint(btns[2], FRAMEPOINT_LEFT,cx,cy+offset)
CoordX[GetHandleId(btns[2])]=cx
CoordY[GetHandleId(btns[2])]=cy+offset
--BlzFrameSetAbsPoint(btns[3], FRAMEPOINT_LEFT,cx+offset,cy+offset)
CoordX[GetHandleId(btns[3])]=cx+offset
CoordY[GetHandleId(btns[3])]=cy+offset
--BlzFrameSetAbsPoint(btns[4], FRAMEPOINT_LEFT,cx+offset,cy)
CoordX[GetHandleId(btns[4])]=cx+offset
CoordY[GetHandleId(btns[4])]=cy
--BlzFrameSetAbsPoint(btns[5], FRAMEPOINT_LEFT,cx+offset,cy-offset)
CoordX[GetHandleId(btns[5])]=cx+offset
CoordY[GetHandleId(btns[5])]=cy-offset
--BlzFrameSetAbsPoint(btns[6], FRAMEPOINT_LEFT,cx,cy-offset)
CoordX[GetHandleId(btns[6])]=cx+offset
CoordY[GetHandleId(btns[6])]=cy-offset
--BlzFrameSetAbsPoint(btns[7], FRAMEPOINT_LEFT,cx-offset,cy-offset)
CoordX[GetHandleId(btns[7])]=cx-offset
CoordY[GetHandleId(btns[7])]=cy-offset
--BlzFrameSetAbsPoint(btns[8], FRAMEPOINT_LEFT,cx-offset,cy)
CoordX[GetHandleId(btns[8])]=cx-offset
CoordY[GetHandleId(btns[8])]=cy
break
end
end
end)
end)
end
end
На видео не удалось это записать. дергаются че-то при записи. без записи работает норм.
IV Метод объединенный
Решил попробовать объединить II и III методы.
lua код
do
local InitGlobalsOrigin = InitGlobals -- хукаем функцию InitGlobals
function InitGlobals()
InitGlobalsOrigin()
--инициируем сетку
function PXTODPI()
return 0.6 / BlzGetLocalClientHeight()
end
function DPITOPX()
return BlzGetLocalClientHeight() / 0.6
end
function FrameBoundWidth()
return (BlzGetLocalClientWidth()-BlzGetLocalClientHeight()/600*800)/2
end
function GetScreenPosX(x)
return (-FrameBoundWidth()+x)*PXTODPI()
end
function GetScreenPosY(y)
return y*PXTODPI()
end
function ScreenRelativeX(x)
return (x * DPITOPX()) * (0.8/BlzGetLocalClientWidth())
end
--print("инициируем большую сетку")
--родитель большой сетки, короче всего экрана
local parent = BlzGetFrameByName("ConsoleUIBackdrop", 0)
--фрейм-кнопки
local btns = {}
--фрейм-подсказки
local tools = {}
--координаты
local CoordXParentFrame = {}
local CoordYParentFrame = {}
local CoordXFrame = {}
local CoordYFrame = {}
--координата нижнего-левого угла
local startx = GetScreenPosX(0.0)
local starty = GetScreenPosY(0.0)
--скалированный размер
local ScaleSizeX = (startx^2)^0.5
--размеры экрана
local width = GetScreenPosX(BlzGetLocalClientWidth())+ScaleSizeX
local height = GetScreenPosY(BlzGetLocalClientHeight())
print("ширина: "..width.." ,высота: "..height)
--БОЛЬШАЯ СЕТКА
--кол-во строк и столбцов
local COLS = 6
local ROWS = 3
print("число строк: "..COLS.." ,число столбцов: "..ROWS)
local xsize = width/6
local ysize = height/3
--МАЛЕНЬКАЯ СЕТКА
local size = 0.01
local countx = xsize/size
local county = ysize/size
local xoffset = size/2
local yoffset = size/2
local sbtns = {}
local stools = {}
--
print("стартовые размеры экрана: "..startx..","..starty )
BlzHideOriginFrames (true)
BlzFrameSetScale(BlzFrameGetChild(BlzGetFrameByName("ConsoleUI",0),5), 0.001)
for x = 1, COLS do
btns[x] = {}
tools[x] = {}
for y = 1, ROWS do
local sx =startx+(xsize*(x-1))
local sy =starty+(ysize*(y-1))
btns[x][y] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(btns[x][y], 25)
BlzFrameSetAbsPoint(btns[x][y], FRAMEPOINT_BOTTOMLEFT, sx, sy)
BlzFrameSetLevel(btns[x][y], 4)
BlzFrameSetSize(btns[x][y], xsize, ysize)
tools[x][y] = BlzCreateFrameByType("FRAME", "FaceFrame", parent, "", 0)
BlzFrameSetAlpha(tools[x][y], 0)
BlzFrameSetAbsPoint(tools[x][y], FRAMEPOINT_BOTTOMLEFT, 0, 0)
BlzFrameSetSize(tools[x][y], 0, 0)
CoordXParentFrame[GetHandleId(btns[x][y])] = sx
CoordYParentFrame[GetHandleId(btns[x][y])] = sy
BlzFrameSetTooltip(btns[x][y], tools[x][y])
end
end
local b = 0.01 --размер квадрата
local c = width/6--0.8
local h = height/3--0.6
local a = b*3 --размер квадрата
local offset = b
local cx,cy = 0.4,0.3 --координаты центра квадрата
local sbtns = {}
local stools = {}
local CoordX = {}
local CoordY = {}
--Верхний левый угол
sbtns[1] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(sbtns[1], 25)
BlzFrameSetAbsPoint(sbtns[1], FRAMEPOINT_BOTTOMRIGHT,cx-b,cy+b)
BlzFrameSetSize(sbtns[1], c, h)
CoordX[GetHandleId(sbtns[1])]=cx-offset
CoordY[GetHandleId(sbtns[1])]=cy+offset
--верхний фрейм
sbtns[2] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(sbtns[2], 25)
BlzFrameSetPoint(sbtns[2], FRAMEPOINT_BOTTOMLEFT, sbtns[1],FRAMEPOINT_BOTTOMRIGHT,0,0)
BlzFrameSetSize(sbtns[2], b, h)
CoordX[GetHandleId(sbtns[2])]=cx
CoordY[GetHandleId(sbtns[2])]=cy+offset
--Верхний правый угол
sbtns[3] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(sbtns[3], 25)
BlzFrameSetPoint(sbtns[3], FRAMEPOINT_BOTTOMLEFT, sbtns[2],FRAMEPOINT_BOTTOMRIGHT,0,0)
BlzFrameSetSize(sbtns[3], c, h)
CoordX[GetHandleId(sbtns[3])]=cx+offset
CoordY[GetHandleId(sbtns[3])]=cy+offset
--правый фрейм
sbtns[4] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(sbtns[4], 25)
BlzFrameSetPoint(sbtns[4], FRAMEPOINT_TOPLEFT, sbtns[3],FRAMEPOINT_BOTTOMLEFT,0,0)
BlzFrameSetSize(sbtns[4], c, b)
CoordX[GetHandleId(sbtns[4])]=cx+offset
CoordY[GetHandleId(sbtns[4])]=cy
--нижний правый угол
sbtns[5] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(sbtns[5], 25)
BlzFrameSetPoint(sbtns[5], FRAMEPOINT_TOPRIGHT, sbtns[4],FRAMEPOINT_BOTTOMRIGHT,0,0)
BlzFrameSetSize(sbtns[5], c, h)
CoordX[GetHandleId(sbtns[5])]=cx+offset
CoordY[GetHandleId(sbtns[5])]=cy-offset
--нижний фрейм
sbtns[6] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(sbtns[6], 25)
BlzFrameSetPoint(sbtns[6], FRAMEPOINT_TOPRIGHT, sbtns[5],FRAMEPOINT_TOPLEFT,0,0)
BlzFrameSetSize(sbtns[6], b, h)
CoordX[GetHandleId(sbtns[6])]=cx
CoordY[GetHandleId(sbtns[6])]=cy-offset
--нижний левый угол
sbtns[7] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(sbtns[7], 0)
BlzFrameSetPoint(sbtns[7], FRAMEPOINT_TOPRIGHT, sbtns[6],FRAMEPOINT_TOPLEFT,0,0)
BlzFrameSetSize(sbtns[7], c, h)
CoordX[GetHandleId(sbtns[7])]=cx-offset
CoordY[GetHandleId(sbtns[7])]=cy-offset
--левый фрейм
sbtns[8] = BlzCreateFrameByType("GLUETEXTBUTTON", "MyButton", parent, "ScriptDialogButton", 0)
BlzFrameSetAlpha(sbtns[8], 25)
BlzFrameSetPoint(sbtns[8], FRAMEPOINT_BOTTOMLEFT, sbtns[7],FRAMEPOINT_TOPLEFT,0,0)
BlzFrameSetSize(sbtns[8], c, b)
CoordX[GetHandleId(sbtns[8])]=cx-offset
CoordY[GetHandleId(sbtns[8])]=cy
for i = 1, 8 do
stools[i] = BlzCreateFrameByType("FRAME", "FaceFrame", parent, "", 0)
BlzFrameSetAlpha(stools[i], 0)
BlzFrameSetAbsPoint(stools[i], FRAMEPOINT_BOTTOMLEFT, 0, 0)
BlzFrameSetLevel(stools[i], 5)
BlzFrameSetLevel(sbtns[i], 6)
BlzFrameSetSize(stools[i], 0, 0)
--BlzFrameSetVisible(sbtns[i], false)
BlzFrameSetVisible(stools[i], false)
BlzFrameSetTooltip(sbtns[i], stools[i])
end
local frameblock = nil
local lastframe = nil
local sx
local sy
TimerStart(CreateTimer(),0.1,true,function()
for x = 1, COLS do
for y = 1, ROWS do
local found = BlzFrameIsVisible(tools[x][y]) and lastframe ~= btns[x][y]
if (found) then
print("найден курсор в секторе "..x..","..y)
if GetHandleId(lastframe)>0 then
BlzFrameSetVisible(lastframe,true)
end
lastframe = btns[x][y]
sx =CoordXParentFrame[GetHandleId(lastframe)]
sy =CoordYParentFrame[GetHandleId(lastframe)]
print(sx..","..sy)
BlzFrameSetAbsPoint(sbtns[1], FRAMEPOINT_BOTTOMRIGHT, sx, sy)
CoordX[GetHandleId(sbtns[1])]=sx-offset
CoordY[GetHandleId(sbtns[1])]=sy+offset
CoordX[GetHandleId(sbtns[2])]=sx
CoordY[GetHandleId(sbtns[2])]=sy+offset
CoordX[GetHandleId(sbtns[3])]=sx+offset
CoordY[GetHandleId(sbtns[3])]=sy+offset
CoordX[GetHandleId(sbtns[4])]=sx+offset
CoordY[GetHandleId(sbtns[4])]=sy
CoordX[GetHandleId(sbtns[5])]=sx+offset
CoordY[GetHandleId(sbtns[5])]=sy-offset
CoordX[GetHandleId(sbtns[6])]=sx+offset
CoordY[GetHandleId(sbtns[6])]=sy-offset
CoordX[GetHandleId(sbtns[7])]=sx-offset
CoordY[GetHandleId(sbtns[7])]=sy-offset
CoordX[GetHandleId(sbtns[8])]=sx-offset
CoordY[GetHandleId(sbtns[8])]=sy
BlzFrameSetVisible(lastframe,false)
do return end
end
end
end
end)
TimerStart(CreateTimer(),0.01,true,function()
for i = 1, 8 do
local found = BlzFrameIsVisible(stools[i])
if (found) then
--BlzFrameSetVisible(stools[i], false)
cx = CoordX[GetHandleId(sbtns[i])]
cy = CoordY[GetHandleId(sbtns[i])]
print("найден курсор в секторе "..cx..","..cy)
BlzFrameSetAbsPoint(sbtns[1], FRAMEPOINT_BOTTOMRIGHT,cx-b,cy+b)
CoordX[GetHandleId(sbtns[1])]=cx-offset
CoordY[GetHandleId(sbtns[1])]=cy+offset
--BlzFrameSetAbsPoint(sbtns[2], FRAMEPOINT_LEFT,cx,cy+offset)
CoordX[GetHandleId(sbtns[2])]=cx
CoordY[GetHandleId(sbtns[2])]=cy+offset
--BlzFrameSetAbsPoint(sbtns[3], FRAMEPOINT_LEFT,cx+offset,cy+offset)
CoordX[GetHandleId(sbtns[3])]=cx+offset
CoordY[GetHandleId(sbtns[3])]=cy+offset
--BlzFrameSetAbsPoint(sbtns[4], FRAMEPOINT_LEFT,cx+offset,cy)
CoordX[GetHandleId(sbtns[4])]=cx+offset
CoordY[GetHandleId(sbtns[4])]=cy
--BlzFrameSetAbsPoint(sbtns[5], FRAMEPOINT_LEFT,cx+offset,cy-offset)
CoordX[GetHandleId(sbtns[5])]=cx+offset
CoordY[GetHandleId(sbtns[5])]=cy-offset
--BlzFrameSetAbsPoint(sbtns[6], FRAMEPOINT_LEFT,cx,cy-offset)
CoordX[GetHandleId(sbtns[6])]=cx+offset
CoordY[GetHandleId(sbtns[6])]=cy-offset
--BlzFrameSetAbsPoint(sbtns[7], FRAMEPOINT_LEFT,cx-offset,cy-offset)
CoordX[GetHandleId(sbtns[7])]=cx-offset
CoordY[GetHandleId(sbtns[7])]=cy-offset
--BlzFrameSetAbsPoint(sbtns[8], FRAMEPOINT_LEFT,cx-offset,cy)
CoordX[GetHandleId(sbtns[8])]=cx-offset
CoordY[GetHandleId(sbtns[8])]=cy
break
end
end
end)
end
end
V Метод - использовать scrollbar (недоработка, просто идея)
Заметил, что когда нажимают на полоску, то ползунок (кнопка) перемещается туда, где мышь. Сам размер полосы можно задать, триггером можно зафиксировать значение между min b max. И сам scrollbar можно было растянуть на весь экран. Теоретически можно было сделать. Как триггером кликнуть фрейм? Нашел только BlzFrameClick(frame), но пока что не знаю, что за фрейм
Другие варианты
Или использовать какую нибудь вычислительную математику для конверта мировых в экранных.
Можно использовать фрейм курсора мыши, там просто нужно прикрепить к курсору фрейм нативкой BlzFrameSetPoint. И че-то не понимаю, как из нее можно получить координаты экрана. Ведь фреймовые нативки не имеют нужных нативок по выдаче координат окна.
Другой вариант использовать
DGUI - в этой системе есть конверт из мировых координат в оконные координаты. Или наоборот, из оконных в мировые. Однако, оно написано на Vjass, на рефордет оно прекрасно открывается.
PanelSystem - очень похожее на DGUI
Lua-wgeometry - эта 3D библиотека. Просто переписанная с DGUI. хотя библиотека очень топовая. По этой
DGUI - в этой системе есть конверт из мировых координат в оконные координаты. Или наоборот, из оконных в мировые. Однако, оно написано на Vjass, на рефордет оно прекрасно открывается.
PanelSystem - очень похожее на DGUI
Lua-wgeometry - эта 3D библиотека. Просто переписанная с DGUI. хотя библиотека очень топовая. По этой
Пока самый идеальный - это пример с хайва или тут. Пример с хайва хоть и рывками смещается, но они едва заметны. Пока не ясно насколько сильно просаживается fps, и нагружает компьютер. На пустой карте вообще не ощутимо. Предлагается автором карты включать/выключать в нужный момент родительский фрейм, чтобы отключить сетку.
Ее можно включать в нужный момент. Пример зельеварения, у вас есть ягода, которую нужно перенести в колбу. Пока можно сделать костылями это:
или стандартным способом с сеткой фреймов - просто перемещаем фрейм ягоды за курсором, а потом отпускаем ПКМ. И тут вам нужно отследить отпускание по колбе. Можно отслеживание вход курсора мыши в фрейм колбы.
или стандартным способом с сеткой фреймов - просто перемещаем фрейм ягоды за курсором, а потом отпускаем ПКМ. И тут вам нужно отследить отпускание по колбе. Можно отслеживание вход курсора мыши в фрейм колбы.
ВАРИАНТ НЕ РАБОЧИЙ
- есть другой вариант: здесь нам не нужна сетка. спрятать фрейм курсора, и нацепить BlzFrameSetPoint к курсору фрейм ягоды. И как только вы протащите фрейм к колбе, и кликнете по колбе. Сам курсор должен вернуться в норму. ВАРИАНТ НЕ РАБОТАЕТ: фрейм курсора, который мы нашли ранее, я не знаю что это. К нему нельзя привязать фрейм, а если можно, то игра вылетает. Поэтому никак нам не обратиться к нему
- Можно попробовать сдвинуть фрейм по BlzGetTriggerPlayerMouseX() и BlzGetTriggerPlayerMouseY(). ВАРИАНТ НЕ БУДЕТ РАБОТАТЬ: не забывайте, что эти функции выдают игровые координаты. нужно затем перевести в экранные.
- Можно изменить изображение курсора. Проблема как его заменить? И потом ловим вхождение курсор в фрейм, и отпускание ПКМ. Можно попробовать спрятать курсор. А вместо него попробовать двигать image, раз не получить экранные координаты, берем игровые.
Зная игровые координаты, некоторые можете перемещать скажем image:
function BlzGetTriggerPlayerMouseX() end -- (native)
---@return real
function BlzGetTriggerPlayerMouseY() end -- (native)
---@return location
function BlzGetTriggerPlayerMousePosition() end -- (native)
Дальше должен быть разбор устройства камеры. И вывод. Но не стал сюда выводить. Тк я не совсем уверен, и не знаю как конвертить экранные и мировые.