Moveable Frame – система для перемещения фреймов мышью
Что это?
Moveable Frame – это система, которая позволяет "хватать" и перемещать фреймы интерфейса вслед за курсором мыши.
Moveable Frame – это система, которая позволяет "хватать" и перемещать фреймы интерфейса вслед за курсором мыши.
В чём проблема?
Игра не предоставляет прямого доступа к экранным координатам мыши – только к игровым (те, что на карте). Без точного позиционирования курсора на экране плавное перемещение фреймов невозможно.
Игра не предоставляет прямого доступа к экранным координатам мыши – только к игровым (те, что на карте). Без точного позиционирования курсора на экране плавное перемещение фреймов невозможно.
Решение:
Используются невидимые "пустые" фреймы размером 0.01x0.01, покрывающие весь экран сеткой. Когда мышь движется, система определяет, над каким из этих микро-фреймов находится курсор, и обновляет позицию перетаскиваемого фрейма.
Используются система мировых координат World2Screen, которая работает гораздо лучше сетки
Используются система мировых координат World2Screen, которая работает гораздо лучше сетки
World2Screen
library World2Screen
globals
real ScreenX = 0
real ScreenY = 0
endglobals
globals
real ScreenX = 0
real ScreenY = 0
endglobals
function World2Screen takes real x, real y, real z returns nothing
local real angleOfAttack = -GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK)
local real fieldOfView = GetCameraField(CAMERA_FIELD_FIELD_OF_VIEW)
local real rotation = GetCameraField(CAMERA_FIELD_ROTATION) + bj_PI
local real angleOfAttack = -GetCameraField(CAMERA_FIELD_ANGLE_OF_ATTACK)
local real fieldOfView = GetCameraField(CAMERA_FIELD_FIELD_OF_VIEW)
local real rotation = GetCameraField(CAMERA_FIELD_ROTATION) + bj_PI
local real cosAttack = Cos(angleOfAttack)
local real sinAttack = Sin(angleOfAttack)
local real cosRot = Cos(rotation)
local real sinRot = Sin(rotation)
local real sinAttack = Sin(angleOfAttack)
local real cosRot = Cos(rotation)
local real sinRot = Sin(rotation)
local real M11 = cosAttack*cosRot
local real M12 = cosAttack*sinRot
local real M13 = sinAttack
local real M21 = -sinRot
local real M22 = cosRot
local real M23 = 0
local real M31 = -cosRot*sinAttack
local real M32 = -sinAttack*sinRot
local real M33 = cosAttack
local real M12 = cosAttack*sinRot
local real M13 = sinAttack
local real M21 = -sinRot
local real M22 = cosRot
local real M23 = 0
local real M31 = -cosRot*sinAttack
local real M32 = -sinAttack*sinRot
local real M33 = cosAttack
local real dx = x - GetCameraEyePositionX()
local real dy = y - GetCameraEyePositionY()
local real dz = z - GetCameraEyePositionZ()
local real dy = y - GetCameraEyePositionY()
local real dz = z - GetCameraEyePositionZ()
local real xPrime = M11*dx + M12*dy + M13*dz
local real yPrime = M21*dx + M22*dy + M23*dz
local real zPrime = M31*dx + M32*dy + M33*dz
local real yPrime = M21*dx + M22*dy + M23*dz
local real zPrime = M31*dx + M32*dy + M33*dz
local real scaling = 1.04 / ( 2 * Tan(fieldOfView / 2) )
set ScreenX = 0.4 - (scaling * yPrime) / xPrime
set ScreenY = 0.355 - (scaling * zPrime) / xPrime
endfunction
endlibrary
set ScreenY = 0.355 - (scaling * zPrime) / xPrime
endfunction
endlibrary
Из нового в переписанной версии с Lua на vJass:
- Расширенные границы – фреймы можно перемещать *за пределы стандартной зоны 0.0–0.8*.
Проблема с оптимизацией решена
- Теперь система создает всего 106 хэндлов
Невозможно сделать движение фрейма с мышкой 1к1, потому что событие Mouse Move срабатывает примерно не чаще чем раз в 0.15 сек
Думаю эту систему можно сделать ещё более плавной, если будут идеи дайте знать в комментариях
Скачать карту:
FrameGrid (Больше не используется)
library FrameGrid requires MoveAbleFrame
struct structFrame
framehandle array GridFrames[4800]
framehandle array GridFrames2[4800]
integer LastFrame = 0
timer Timer
real FramesEachCol
hashtable Coords
integer index = 0
method setFrameCoords takes framehandle frame, real x, real y returns nothing
call SaveReal(Coords, GetHandleId(frame), 0, x)
call SaveReal(Coords, GetHandleId(frame), 1, y)
endmethod
method GetFrameCoordsX takes framehandle frame returns real
return LoadReal(Coords, GetHandleId(frame), 0)
endmethod
method GetFrameCoordsY takes framehandle frame returns real
return LoadReal(Coords, GetHandleId(frame), 1)
endmethod
endstruct
globals
structFrame FrameGrid
framehandle Boss = null
endglobals
/*function updateSimple takes nothing returns nothing
local framehandle value
local integer index = 0
if BlzFrameIsVisible(FrameGrid.Boss) then
call BJDebugMsg("updateSimple BlzFrameIsVisible")
loop
exitwhen index == FrameGrid.LastFrame + 1
set value = FrameGrid.GridFrames2[index]
if BlzFrameIsVisible(value) then
call moveFrame(FrameGrid.GetFrameCoordsX(FrameGrid.GridFrames2[index]),FrameGrid.GetFrameCoordsY(FrameGrid.GridFrames2[index]), true)
return
endif
set index = index + 1
endloop
endif
endfunction*/
function update2 takes nothing returns nothing
local integer yA = FrameGrid.LastFrame
local integer yB = FrameGrid.LastFrame
if BlzFrameIsVisible(Boss) then
loop
exitwhen (yA < 0 and yB >= 4800)
if yA >= 0 then
if BlzFrameIsVisible(FrameGrid.GridFrames2[yA]) then
set FrameGrid.LastFrame = yA
call BJDebugMsg("update: trying to move " + BlzFrameGetName(FrameGrid.GridFrames2[yA]))
call moveFrame(FrameGrid.GetFrameCoordsX(FrameGrid.GridFrames2[yA]),FrameGrid.GetFrameCoordsY(FrameGrid.GridFrames2[yA]), true)
return
endif
set yA = yA - 1
endif
if BlzFrameIsVisible(FrameGrid.GridFrames2[yB]) then
set FrameGrid.LastFrame = yB
call BJDebugMsg("update: trying to move" + BlzFrameGetName(FrameGrid.GridFrames2[yB]))
call moveFrame(FrameGrid.GetFrameCoordsX(FrameGrid.GridFrames2[yB]),FrameGrid.GetFrameCoordsY(FrameGrid.GridFrames2[yB]), true)
return
else
set yB = yB + 1
endif
endloop
endif
endfunction
function HideBossFrame takes nothing returns nothing
call BlzFrameSetVisible(Boss, false)
endfunction
globals
framehandle newButton
framehandle tooltipButton
endglobals
function onGameStart2 takes nothing returns nothing
local real xSize = 0.01
local real ySize = 0.01
local real yStart = ySize/2
local real xStart = xSize/2
local real x = -0.134
local real y
call PolledWait2(0.01)
set FrameGrid = structFrame.create()
set FrameGrid.Coords = InitHashtable()
set FrameGrid.Timer = CreateTimer()
call TimerStart(FrameGrid.Timer, 0.01, true, function update2)
set Boss = BlzCreateFrameByType("BUTTON", "FrameGridBoss", BlzGetFrameByName("ConsoleUIBackdrop", 0),"",0)
set FrameGrid.FramesEachCol = 0.6 / ySize
loop
exitwhen x>0.932
set y = yStart
loop
exitwhen y>=0.6
set newButton = BlzCreateFrameByType("FRAME", "FRAME" + I2S(FrameGrid.index), Boss,"",0)
set tooltipButton = BlzCreateFrameByType("FRAME", "FRAME" + I2S(FrameGrid.index), Boss,"",0)
call BlzFrameSetAbsPoint(newButton, FRAMEPOINT_CENTER, x, y)
call BlzFrameSetSize(newButton, xSize, ySize)
call BlzFrameSetTooltip(newButton, tooltipButton)
call BlzFrameSetEnable(newButton, false)
call BlzFrameSetEnable(tooltipButton, false)
call FrameGrid.setFrameCoords(newButton,x,y)
call FrameGrid.setFrameCoords(tooltipButton,x,y)
set FrameGrid.GridFrames2[FrameGrid.index] = tooltipButton
set FrameGrid.GridFrames[FrameGrid.index] = newButton
set FrameGrid.index = FrameGrid.index + 1
set y = y + ySize
endloop
set x = x + xSize
endloop
call BlzFrameSetVisible(Boss, false)
call onGameStart()
endfunction
endlibrary
MoveAbleFrame (Основной)
library MoveAbleFrame initializer onTriggerInit requires World2Screen
globals
real targetX = 0.0
real targetY = 0.0
real currentX = 0.0
real currentY = 0.0
real moveSpeed = 0.04 // от 0 до 1: выше — быстрее, ниже — плавнее
real prevTargetX = 0.0
real prevTargetY = 0.0
real deltaX = 0.0
real deltaY = 0.0
endglobals
struct structMoveAbleFrame
boolean Enabled = true
framehandle Frame = null
framehandle PlayerHoveredFrame
framepointtype FramePoint
trigger TriggerFrameEnter
triggeraction TriggerFrameEnterAction
trigger TriggerFrameLeave
triggeraction TriggerFrameLeaveAction
trigger MouseClickTrigger
triggeraction MouseClickTriggerAction
trigger MouseReleaseTrigger
triggeraction MouseReleaseTriggerAction
trigger MOUSE_MOVE_Trigger
triggeraction MOUSE_MOVE_TriggerAction
endstruct
globals
structMoveAbleFrame MoveAbleFrame
endglobals
function enable takes player p, boolean flag returns boolean
if GetLocalPlayer() == p then
if flag == null then
set MoveAbleFrame.Enabled = not MoveAbleFrame.Enabled
else
set MoveAbleFrame.Enabled = flag
endif
endif
return MoveAbleFrame.Enabled
endfunction
function setup takes framehandle frame returns nothing
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameEnter, frame, FRAMEEVENT_MOUSE_ENTER)
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameLeave , frame, FRAMEEVENT_MOUSE_LEAVE)
endfunction
function startMoving takes framehandle frame, framepointtype framePoint returns nothing
set MoveAbleFrame.Frame = frame
if framePoint == null then
set framePoint = FRAMEPOINT_CENTER
endif
set MoveAbleFrame.FramePoint = framePoint
endfunction
function moveFrame takes real x, real y returns nothing
call BJDebugMsg("moveFrame: called x=" + R2S(x) + " y=" + R2S(y))
call BlzFrameClearAllPoints(MoveAbleFrame.Frame)
call BlzFrameSetAbsPoint(MoveAbleFrame.Frame, MoveAbleFrame.FramePoint, x, y)
endfunction
function GetTriggerPlayerHoveredFrame takes nothing returns nothing
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
set GetTriggerName_DEBUG = "TriggerFrameEnter"
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = BlzGetTriggerFrame()
endif
endfunction
function GetTriggerPlayerHoveredFrameNull takes nothing returns nothing
set GetTriggerName_DEBUG = "TriggerFrameLeave"
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = null
endif
endfunction
globals
location moveLoc = Location(0, 0)
boolean flag = false
endglobals
function MouseClick takes nothing returns nothing
local player p = GetTriggerPlayer()
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real z
call updateDebugFrame()
set GetFunctionName_DEBUG = "MouseClick"
set GetTriggerName_DEBUG = "MouseClickTrigger"
call MoveLocation(moveLoc, x, y)
set z = GetLocationZ(moveLoc)
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
if MoveAbleFrame.PlayerHoveredFrame != null then
//call BJDebugMsg("MouseClick: frame is not null: " + BlzFrameGetName(MoveAbleFrame.PlayerHoveredFrame))
if MoveAbleFrame.Enabled then
if GetLocalPlayer() == p then
set flag = true
call startMoving(MoveAbleFrame.PlayerHoveredFrame, FRAMEPOINT_CENTER)
call BlzFrameSetEnable(MoveAbleFrame.PlayerHoveredFrame, false)
call World2Screen(x,y,z)
set mouseX = ScreenX
set mouseY = ScreenY
set mouseX_prev = ScreenX
set mouseY_prev = ScreenY
set currentX = ScreenX
set currentY = ScreenY
set interpProgress = 1.0
endif
endif
else
//call BJDebugMsg("MouseClick: PlayerHoveredFrame is null")
endif
endif
endfunction
function MouseRelease takes nothing returns nothing
set flag = false
set GetFunctionName_DEBUG = "MouseRelease"
set GetTriggerName_DEBUG = "MouseReleaseTrigger"
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
if MoveAbleFrame.Frame != null then
call BlzFrameSetEnable(MoveAbleFrame.Frame, true)
endif
endif
endfunction
function PolledWait2 takes real time returns nothing
local timer t
local real R
if time>0. then
set t = CreateTimer()
call TimerStart(t,time,false,null)
loop
set R=TimerGetRemaining(t)
exitwhen R<=0.
call TriggerSleepAction(R)
endloop
call DestroyTimer(t)
set t=null
endif
endfunction
globals
real mouseX = 0.0
real mouseY = 0.0
real mouseX_prev = 0.0
real mouseY_prev = 0.0
real mouseX_interp = 0.0
real mouseY_interp = 0.0
real interpProgress = 1.0
real interpSpeed = 0
endglobals
function OnMouseMove takes nothing returns nothing
local real newX = BlzGetTriggerPlayerMouseX()
local real newY = BlzGetTriggerPlayerMouseY()
set GetFunctionName_DEBUG = "OnMouseMove"
set mouseX_prev = mouseX
set mouseY_prev = mouseY
set mouseX = newX
set mouseY = newY
set interpProgress = 0.0
endfunction
function update2 takes nothing returns nothing
local real dist
local real dynamicSpeed
local real dx
local real dy
local real distMouse
if flag == true then
call updateDebugFrame()
set GetFunctionName_DEBUG = "update2"
set dx = mouseX - mouseX_prev
set dy = mouseY - mouseY_prev
set distMouse = SquareRoot(dx * dx + dy * dy)
set interpSpeed = 0.1 + distMouse * 0.6
set interpProgress = interpProgress + interpSpeed
if interpProgress > 1.0 then
set interpProgress = 1.0
endif
set mouseX_interp = mouseX_prev + (mouseX - mouseX_prev) * interpProgress
set mouseY_interp = mouseY_prev + (mouseY - mouseY_prev) * interpProgress
set targetX = mouseX_interp
set targetY = mouseY_interp
set dist = SquareRoot((targetX - currentX)*(targetX - currentX) + (targetY - currentY)*(targetY - currentY))
set dynamicSpeed = moveSpeed + dist * 0.2
if dynamicSpeed > 0.08 then
set dynamicSpeed = 0.08
endif
set currentX = currentX + (targetX - currentX) * dynamicSpeed
set currentY = currentY + (targetY - currentY) * dynamicSpeed
call moveFrame(currentX, currentY)
endif
endfunction
function CoordsMouse takes nothing returns nothing
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real z
set GetFunctionName_DEBUG = "CoordsMouse"
set GetTriggerName_DEBUG = "MOUSE_MOVE_Trigger"
if flag == true then
call MoveLocation(moveLoc, x, y)
set z = GetLocationZ(moveLoc)
call World2Screen(x,y,z)
set mouseX_prev = mouseX
set mouseY_prev = mouseY
set mouseX = ScreenX
set mouseY = ScreenY
set interpProgress = 0.0
endif
endfunction
function onTriggerInit takes nothing returns nothing
local integer playerIndex = 0
local timer Timer = CreateTimer()
local timer Timer2 = CreateTimer()
call PolledWait2(0.01)
set MoveAbleFrame = structMoveAbleFrame.create()
set MoveAbleFrame.TriggerFrameEnter = CreateTrigger()
set MoveAbleFrame.TriggerFrameEnterAction = TriggerAddAction(MoveAbleFrame.TriggerFrameEnter,function GetTriggerPlayerHoveredFrame)
set MoveAbleFrame.TriggerFrameLeave = CreateTrigger()
set MoveAbleFrame.TriggerFrameLeaveAction = TriggerAddAction(MoveAbleFrame.TriggerFrameLeave, function GetTriggerPlayerHoveredFrameNull)
set MoveAbleFrame.MouseClickTrigger = CreateTrigger()
set MoveAbleFrame.MouseClickTriggerAction = TriggerAddAction(MoveAbleFrame.MouseClickTrigger, function MouseClick)
set MoveAbleFrame.MouseReleaseTrigger = CreateTrigger()
set MoveAbleFrame.MouseReleaseTriggerAction = TriggerAddAction(MoveAbleFrame.MouseReleaseTrigger, function MouseRelease)
set MoveAbleFrame.MOUSE_MOVE_Trigger = CreateTrigger()
set MoveAbleFrame.MOUSE_MOVE_TriggerAction = TriggerAddAction(MoveAbleFrame.MOUSE_MOVE_Trigger, function CoordsMouse)
loop
exitwhen playerIndex == GetBJMaxPlayers()
call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseClickTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_DOWN)
call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseReleaseTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_UP)
call TriggerRegisterPlayerEvent(MoveAbleFrame.MOUSE_MOVE_Trigger, Player(playerIndex), EVENT_PLAYER_MOUSE_MOVE)
set playerIndex = playerIndex + 1
endloop
call ExecuteFunc("onGameStart")
call TimerStart(Timer, 0.003, true, function update2)
endfunction
endlibrary
>> MoveAbleFrame 2 (Второй вариант)
library MoveAbleFrame initializer onTriggerInit requires World2Screen
globals
real targetX = 0.0
real targetY = 0.0
real currentX = 0.0
real currentY = 0.0
real moveSpeed = 0.04 // от 0 до 1: выше — быстрее, ниже — плавнее
real prevTargetX = 0.0
real prevTargetY = 0.0
real deltaX = 0.0
real deltaY = 0.0
endglobals
struct structMoveAbleFrame
boolean Enabled = true
framehandle Frame = null
framehandle PlayerHoveredFrame
framepointtype FramePoint
trigger TriggerFrameEnter
triggeraction TriggerFrameEnterAction
trigger TriggerFrameLeave
triggeraction TriggerFrameLeaveAction
trigger MouseClickTrigger
triggeraction MouseClickTriggerAction
trigger MouseReleaseTrigger
triggeraction MouseReleaseTriggerAction
trigger MOUSE_MOVE_Trigger
triggeraction MOUSE_MOVE_TriggerAction
endstruct
globals
structMoveAbleFrame MoveAbleFrame
endglobals
function enable takes player p, boolean flag returns boolean
if GetLocalPlayer() == p then
if flag == null then
set MoveAbleFrame.Enabled = not MoveAbleFrame.Enabled
else
set MoveAbleFrame.Enabled = flag
endif
endif
return MoveAbleFrame.Enabled
endfunction
function setup takes framehandle frame returns nothing
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameEnter, frame, FRAMEEVENT_MOUSE_ENTER)
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameLeave , frame, FRAMEEVENT_MOUSE_LEAVE)
endfunction
function startMoving takes framehandle frame, framepointtype framePoint returns nothing
set MoveAbleFrame.Frame = frame
if framePoint == null then
set framePoint = FRAMEPOINT_CENTER
endif
set MoveAbleFrame.FramePoint = framePoint
endfunction
function moveFrame takes real x, real y returns nothing
call BJDebugMsg("moveFrame: called x=" + R2S(x) + " y=" + R2S(y))
call BlzFrameClearAllPoints(MoveAbleFrame.Frame)
call BlzFrameSetAbsPoint(MoveAbleFrame.Frame, MoveAbleFrame.FramePoint, x, y)
endfunction
function GetTriggerPlayerHoveredFrame takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = BlzGetTriggerFrame()
endif
endfunction
function GetTriggerPlayerHoveredFrameNull takes nothing returns nothing
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = null
endif
endfunction
globals
location moveLoc = Location(0, 0)
boolean flag = false
endglobals
function MouseClick takes nothing returns nothing
local player p = GetTriggerPlayer()
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real z
call MoveLocation(moveLoc, x, y)
set z = GetLocationZ(moveLoc)
call BJDebugMsg("MouseClick")
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
if MoveAbleFrame.PlayerHoveredFrame != null then
call BJDebugMsg("MouseClick: frame is not null: " + BlzFrameGetName(MoveAbleFrame.PlayerHoveredFrame))
if MoveAbleFrame.Enabled then
if GetLocalPlayer() == p then
set flag = true // Перемещение только если действительно кликнули по фрейму
call startMoving(MoveAbleFrame.PlayerHoveredFrame, FRAMEPOINT_CENTER)
call BlzFrameSetEnable(MoveAbleFrame.PlayerHoveredFrame, false)
call World2Screen(x,y,z)
endif
endif
else
call BJDebugMsg("MouseClick: PlayerHoveredFrame is null")
endif
endif
endfunction
function MouseRelease takes nothing returns nothing
call BJDebugMsg("MouseRelease")
set flag = false
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
if MoveAbleFrame.Frame != null then
call BlzFrameSetEnable(MoveAbleFrame.Frame, true)
endif
endif
endfunction
function PolledWait2 takes real time returns nothing
local timer t
local real R
if time>0. then
set t = CreateTimer()
call TimerStart(t,time,false,null)
loop
set R=TimerGetRemaining(t)
exitwhen R<=0.
call TriggerSleepAction(R)
endloop
call DestroyTimer(t)
set t=null
endif
endfunction
function update2 takes nothing returns nothing
local real dist
local real dynamicSpeed
if flag == true then
set dist = SquareRoot((targetX - currentX)*(targetX - currentX) + (targetY - currentY)*(targetY - currentY))
set dynamicSpeed = moveSpeed + dist * 0.4
if dynamicSpeed > 0.08 then
set dynamicSpeed = 0.08
endif
// Плавное приближение к целевой позиции
set currentX = currentX + (targetX - currentX) * moveSpeed
set currentY = currentY + (targetY - currentY) * moveSpeed
call moveFrame(currentX, currentY)
endif
endfunction
function CoordsMouse takes nothing returns nothing
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real speedLimit = 0.25
local real deltaLength = SquareRoot(deltaX * deltaX + deltaY * deltaY)
local real z
if flag == true then
call MoveLocation(moveLoc, x, y)
set z = GetLocationZ(moveLoc)
call World2Screen(x,y,z)
set deltaX = ScreenX - prevTargetX
set deltaY = ScreenY - prevTargetY
if deltaLength > speedLimit then
set deltaX = deltaX * speedLimit / deltaLength
set deltaY = deltaY * speedLimit / deltaLength
endif
set targetX = ScreenX + deltaX * 1.4
set targetY = ScreenY + deltaY * 1.4
set prevTargetX = ScreenX
set prevTargetY = ScreenY
endif
endfunction
function onTriggerInit takes nothing returns nothing
local integer playerIndex = 0
local timer Timer = CreateTimer()
local timer Timer2 = CreateTimer()
call PolledWait2(0.01)
set MoveAbleFrame = structMoveAbleFrame.create()
set MoveAbleFrame.TriggerFrameEnter = CreateTrigger()
set MoveAbleFrame.TriggerFrameEnterAction = TriggerAddAction(MoveAbleFrame.TriggerFrameEnter,function GetTriggerPlayerHoveredFrame)
set MoveAbleFrame.TriggerFrameLeave = CreateTrigger()
set MoveAbleFrame.TriggerFrameLeaveAction = TriggerAddAction(MoveAbleFrame.TriggerFrameLeave, function GetTriggerPlayerHoveredFrameNull)
set MoveAbleFrame.MouseClickTrigger = CreateTrigger()
set MoveAbleFrame.MouseClickTriggerAction = TriggerAddAction(MoveAbleFrame.MouseClickTrigger, function MouseClick)
set MoveAbleFrame.MouseReleaseTrigger = CreateTrigger()
set MoveAbleFrame.MouseReleaseTriggerAction = TriggerAddAction(MoveAbleFrame.MouseReleaseTrigger, function MouseRelease)
set MoveAbleFrame.MOUSE_MOVE_Trigger = CreateTrigger()
set MoveAbleFrame.MOUSE_MOVE_TriggerAction = TriggerAddAction(MoveAbleFrame.MOUSE_MOVE_Trigger, function CoordsMouse)
loop
exitwhen playerIndex == GetBJMaxPlayers()
call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseClickTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_DOWN)
call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseReleaseTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_UP)
call TriggerRegisterPlayerEvent(MoveAbleFrame.MOUSE_MOVE_Trigger, Player(playerIndex), EVENT_PLAYER_MOUSE_MOVE)
set playerIndex = playerIndex + 1
endloop
call ExecuteFunc("onGameStart")
call TimerStart(Timer, 0.003, true, function update2)
endfunction
endlibrary
MoveAbleFrame 3 (Можно сделать явно более плавно из-за таймера 0.001)
library MoveAbleFrame initializer onTriggerInit requires World2Screen
globals
real targetX = 0.0
real targetY = 0.0
real currentX = 0.0
real currentY = 0.0
real moveSpeed = 0.02 // от 0 до 1: выше — быстрее, ниже — плавнее
real prevTargetX = 0.0
real prevTargetY = 0.0
real deltaX = 0.0
real deltaY = 0.0
endglobals
struct structMoveAbleFrame
boolean Enabled = true
framehandle Frame = null
framehandle PlayerHoveredFrame
framepointtype FramePoint
trigger TriggerFrameEnter
triggeraction TriggerFrameEnterAction
trigger TriggerFrameLeave
triggeraction TriggerFrameLeaveAction
trigger MouseClickTrigger
triggeraction MouseClickTriggerAction
trigger MouseReleaseTrigger
triggeraction MouseReleaseTriggerAction
trigger MOUSE_MOVE_Trigger
triggeraction MOUSE_MOVE_TriggerAction
endstruct
globals
structMoveAbleFrame MoveAbleFrame
endglobals
function enable takes player p, boolean flag returns boolean
if GetLocalPlayer() == p then
if flag == null then
set MoveAbleFrame.Enabled = not MoveAbleFrame.Enabled
else
set MoveAbleFrame.Enabled = flag
endif
endif
return MoveAbleFrame.Enabled
endfunction
function setup takes framehandle frame returns nothing
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameEnter, frame, FRAMEEVENT_MOUSE_ENTER)
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameLeave , frame, FRAMEEVENT_MOUSE_LEAVE)
endfunction
function startMoving takes framehandle frame, framepointtype framePoint returns nothing
set MoveAbleFrame.Frame = frame
if framePoint == null then
set framePoint = FRAMEPOINT_CENTER
endif
set MoveAbleFrame.FramePoint = framePoint
endfunction
function moveFrame takes real x, real y returns nothing
//call BJDebugMsg("moveFrame: called x=" + R2S(x) + " y=" + R2S(y))
call BlzFrameClearAllPoints(MoveAbleFrame.Frame)
call BlzFrameSetAbsPoint(MoveAbleFrame.Frame, MoveAbleFrame.FramePoint, x, y)
endfunction
function GetTriggerPlayerHoveredFrame takes nothing returns nothing
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
set GetTriggerName_DEBUG = "TriggerFrameEnter"
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = BlzGetTriggerFrame()
endif
endfunction
function GetTriggerPlayerHoveredFrameNull takes nothing returns nothing
set GetTriggerName_DEBUG = "TriggerFrameLeave"
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = null
endif
endfunction
globals
location moveLoc = Location(0, 0)
boolean flag = false
endglobals
function MouseClick takes nothing returns nothing
local player p = GetTriggerPlayer()
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real z
call updateDebugFrame()
set GetFunctionName_DEBUG = "MouseClick"
set GetTriggerName_DEBUG = "MouseClickTrigger"
call MoveLocation(moveLoc, x, y)
set z = GetLocationZ(moveLoc)
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
if MoveAbleFrame.PlayerHoveredFrame != null then
//call BJDebugMsg("MouseClick: frame is not null: " + BlzFrameGetName(MoveAbleFrame.PlayerHoveredFrame))
if MoveAbleFrame.Enabled then
if GetLocalPlayer() == p then
set flag = true
call startMoving(MoveAbleFrame.PlayerHoveredFrame, FRAMEPOINT_CENTER)
call BlzFrameSetEnable(MoveAbleFrame.PlayerHoveredFrame, false)
call World2Screen(x,y,z)
set mouseX = ScreenX
set mouseY = ScreenY
set mouseX_prev = ScreenX
set mouseY_prev = ScreenY
set currentX = ScreenX
set currentY = ScreenY
set interpProgress = 1.0
endif
endif
else
//call BJDebugMsg("MouseClick: PlayerHoveredFrame is null")
endif
endif
endfunction
function MouseRelease takes nothing returns nothing
set flag = false
set GetFunctionName_DEBUG = "MouseRelease"
set GetTriggerName_DEBUG = "MouseReleaseTrigger"
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
if MoveAbleFrame.Frame != null then
call BlzFrameSetEnable(MoveAbleFrame.Frame, true)
endif
endif
endfunction
function PolledWait2 takes real time returns nothing
local timer t
local real R
if time>0. then
set t = CreateTimer()
call TimerStart(t,time,false,null)
loop
set R=TimerGetRemaining(t)
exitwhen R<=0.
call TriggerSleepAction(R)
endloop
call DestroyTimer(t)
set t=null
endif
endfunction
globals
real mouseX = 0.0
real mouseY = 0.0
real mouseX_prev = 0.0
real mouseY_prev = 0.0
real mouseX_interp = 0.0
real mouseY_interp = 0.0
real interpProgress = 1.0
real interpSpeed = 0
endglobals
function OnMouseMove takes nothing returns nothing
local real newX = BlzGetTriggerPlayerMouseX()
local real newY = BlzGetTriggerPlayerMouseY()
set GetFunctionName_DEBUG = "OnMouseMove"
set mouseX_prev = mouseX
set mouseY_prev = mouseY
set mouseX = newX
set mouseY = newY
set interpProgress = 0.0
endfunction
function update2 takes nothing returns nothing
local real dist
local real dynamicSpeed
local real dx
local real dy
local real distMouse
if flag == true then
call updateDebugFrame()
set GetTriggerName_DEBUG = "onTriggerInit"
set GetFunctionName_DEBUG = "update2"
set dx = mouseX - mouseX_prev
set dy = mouseY - mouseY_prev
set distMouse = SquareRoot(dx * dx + dy * dy)
set interpSpeed = 0.04 + distMouse * 0.3
set interpProgress = interpProgress + interpSpeed
if interpProgress > 1.0 then
set interpProgress = 1.0
endif
set mouseX_interp = mouseX_prev + (mouseX - mouseX_prev) * interpProgress
set mouseY_interp = mouseY_prev + (mouseY - mouseY_prev) * interpProgress
set targetX = mouseX_interp
set targetY = mouseY_interp
set dist = SquareRoot((targetX - currentX)*(targetX - currentX) + (targetY - currentY)*(targetY - currentY))
set dynamicSpeed = moveSpeed + dist * 0.1
if dynamicSpeed > 0.05 then
set dynamicSpeed = 0.05
endif
set currentX = currentX + (targetX - currentX) * dynamicSpeed
set currentY = currentY + (targetY - currentY) * dynamicSpeed
call moveFrame(currentX, currentY)
endif
endfunction
function CoordsMouse takes nothing returns nothing
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real z
set GetFunctionName_DEBUG = "CoordsMouse"
set GetTriggerName_DEBUG = "MOUSE_MOVE_Trigger"
if flag == true then
call MoveLocation(moveLoc, x, y)
set z = GetLocationZ(moveLoc)
call World2Screen(x,y,z)
set mouseX_prev = mouseX
set mouseY_prev = mouseY
set mouseX = ScreenX
set mouseY = ScreenY
set interpProgress = 0.0
endif
endfunction
function onTriggerInit takes nothing returns nothing
local integer playerIndex = 0
local timer Timer = CreateTimer()
local timer Timer2 = CreateTimer()
call PolledWait2(0.01)
set MoveAbleFrame = structMoveAbleFrame.create()
set MoveAbleFrame.TriggerFrameEnter = CreateTrigger()
set MoveAbleFrame.TriggerFrameEnterAction = TriggerAddAction(MoveAbleFrame.TriggerFrameEnter,function GetTriggerPlayerHoveredFrame)
set MoveAbleFrame.TriggerFrameLeave = CreateTrigger()
set MoveAbleFrame.TriggerFrameLeaveAction = TriggerAddAction(MoveAbleFrame.TriggerFrameLeave, function GetTriggerPlayerHoveredFrameNull)
set MoveAbleFrame.MouseClickTrigger = CreateTrigger()
set MoveAbleFrame.MouseClickTriggerAction = TriggerAddAction(MoveAbleFrame.MouseClickTrigger, function MouseClick)
set MoveAbleFrame.MouseReleaseTrigger = CreateTrigger()
set MoveAbleFrame.MouseReleaseTriggerAction = TriggerAddAction(MoveAbleFrame.MouseReleaseTrigger, function MouseRelease)
set MoveAbleFrame.MOUSE_MOVE_Trigger = CreateTrigger()
set MoveAbleFrame.MOUSE_MOVE_TriggerAction = TriggerAddAction(MoveAbleFrame.MOUSE_MOVE_Trigger, function CoordsMouse)
loop
exitwhen playerIndex == GetBJMaxPlayers()
call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseClickTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_DOWN)
call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseReleaseTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_UP)
call TriggerRegisterPlayerEvent(MoveAbleFrame.MOUSE_MOVE_Trigger, Player(playerIndex), EVENT_PLAYER_MOUSE_MOVE)
set playerIndex = playerIndex + 1
endloop
call ExecuteFunc("onGameStart")
call TimerStart(Timer, 0.001, true, function update2)
endfunction
endlibrary
<<
Код для тестирования системы
library Testb
private function click takes nothing returns nothing
call BJDebugMsg("click " + BlzFrameGetName(BlzGetTriggerFrame()))
endfunction
private function enter takes nothing returns nothing
// call BJDebugMsg("enter " + BlzFrameGetName(BlzGetTriggerFrame()))
endfunction
function onGameStart takes nothing returns nothing
local framehandle gameUI = BlzGetFrameByName("ConsoleUIBackdrop", 0)
local trigger t = CreateTrigger()
local trigger t2 = CreateTrigger()
local framehandle b
call TriggerAddAction(t, function click)
call TriggerAddAction(t2, function enter)
set b = BlzCreateFrameByType("GLUETEXTBUTTON", "b 1", gameUI, "ScriptDialogButton", 0)
call BlzFrameSetAbsPoint(b, FRAMEPOINT_CENTER, 0.55, 0.4)
call BlzFrameSetText(b, "b 1")
call setup(b)
call BlzTriggerRegisterFrameEvent(t, b, FRAMEEVENT_CONTROL_CLICK)
call BlzTriggerRegisterFrameEvent(t2, b, FRAMEEVENT_MOUSE_ENTER)
set b = BlzCreateFrameByType("GLUETEXTBUTTON", "b 2", gameUI, "ScriptDialogButton", 0)
call BlzFrameSetAbsPoint(b, FRAMEPOINT_CENTER, 0.55, 0.35)
call BlzFrameSetText(b, "b 2")
call setup(b)
call BlzTriggerRegisterFrameEvent(t, b, FRAMEEVENT_CONTROL_CLICK)
call BlzTriggerRegisterFrameEvent(t2, b, FRAMEEVENT_MOUSE_ENTER)
set b = BlzCreateFrameByType("GLUETEXTBUTTON", "b 3", gameUI, "ScriptDialogButton", 0)
call BlzFrameSetAbsPoint(b, FRAMEPOINT_CENTER, 0.55, 0.45)
call BlzFrameSetText(b, "b 3")
call setup(b)
call BlzTriggerRegisterFrameEvent(t, b, FRAMEEVENT_CONTROL_CLICK)
call BlzTriggerRegisterFrameEvent(t2, b, FRAMEEVENT_MOUSE_ENTER)
//call enable(GetLocalPlayer(),true)
call BJDebugMsg(GetPlayerName(GetLocalPlayer()))
call BJDebugMsg("onGameStart END")
endfunction
endlibrary
array в параметрах функций нельзя))
Что за нейронка? на Deepseek и ChatGPT не похожа )
Ред. darkowlom
Мда, забыл я джазз за 10 лет, оказывается)
Думаю переделать под корректный синтаксис можно, если время появится попробую рефоржед поставить и поколдовать над скриптом, если сам не переделаешь к тому времени
Хотя, еще на балнсе пару баксов есть, можно твой коммент прислать, пусть исправляет)
Ред. darkowlom
Ред. darkowlom
Ред. darkowlom
Ред. darkowlom
Ред. Koladik
Ред. darkowlom
Ред. darkowlom
Ред. darkowlom
Ред. darkowlom
real targetX = 0.0
real targetY = 0.0
real currentX = 0.0
real currentY = 0.0
real moveSpeed = 0.04 от 0 до 1: выше — быстрее, ниже — плавнее
real prevTargetX = 0.0
real prevTargetY = 0.0
real deltaX = 0.0
real deltaY = 0.0
endglobals
boolean Enabled = true
framehandle Frame = null
framehandle PlayerHoveredFrame
framepointtype FramePoint
trigger TriggerFrameEnter
triggeraction TriggerFrameEnterAction
trigger TriggerFrameLeave
triggeraction TriggerFrameLeaveAction
trigger MouseClickTrigger
triggeraction MouseClickTriggerAction
trigger MouseReleaseTrigger
triggeraction MouseReleaseTriggerAction
trigger MOUSE_MOVE_Trigger
triggeraction MOUSE_MOVE_TriggerAction
endstruct
structMoveAbleFrame MoveAbleFrame
endglobals
if GetLocalPlayer() == p then
if flag == null then
set MoveAbleFrame.Enabled = not MoveAbleFrame.Enabled
else
set MoveAbleFrame.Enabled = flag
endif
endif
return MoveAbleFrame.Enabled
endfunction
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameEnter, frame, FRAMEEVENT_MOUSE_ENTER)
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameLeave , frame, FRAMEEVENT_MOUSE_LEAVE)
endfunction
set MoveAbleFrame.Frame = frame
if framePoint == null then
set framePoint = FRAMEPOINT_CENTER
endif
set MoveAbleFrame.FramePoint = framePoint
endfunction
call BJDebugMsg("moveFrame: called x=" + R2S(x) + " y=" + R2S(y))
call BlzFrameClearAllPoints(MoveAbleFrame.Frame)
call BlzFrameSetAbsPoint(MoveAbleFrame.Frame, MoveAbleFrame.FramePoint, x, y)
endfunction
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
set GetTriggerName_DEBUG = "TriggerFrameEnter"
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = BlzGetTriggerFrame()
endif
endfunction
set GetTriggerName_DEBUG = "TriggerFrameLeave"
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = null
endif
endfunction
location moveLoc = Location(0, 0)
boolean flag = false
endglobals
local player p = GetTriggerPlayer()
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real z
call updateDebugFrame()
set GetFunctionName_DEBUG = "MouseClick"
set GetTriggerName_DEBUG = "MouseClickTrigger"
call MoveLocation(moveLoc, x, y)
set z = GetLocationZ(moveLoc)
if MoveAbleFrame.PlayerHoveredFrame != null then
call BJDebugMsg("MouseClick: frame is not null: " + BlzFrameGetName(MoveAbleFrame.PlayerHoveredFrame))
if MoveAbleFrame.Enabled then
if GetLocalPlayer() == p then
set flag = true
call startMoving(MoveAbleFrame.PlayerHoveredFrame, FRAMEPOINT_CENTER)
call BlzFrameSetEnable(MoveAbleFrame.PlayerHoveredFrame, false)
call World2Screen(x,y,z)
set mouseX = ScreenX
set mouseY = ScreenY
set mouseX_prev = ScreenX
set mouseY_prev = ScreenY
set currentX = ScreenX
set currentY = ScreenY
set interpProgress = 1.0
endif
endif
else
call BJDebugMsg("MouseClick: PlayerHoveredFrame is null")
endif
endif
endfunction
set flag = false
set GetFunctionName_DEBUG = "MouseRelease"
set GetTriggerName_DEBUG = "MouseReleaseTrigger"
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
if MoveAbleFrame.Frame != null then
call BlzFrameSetEnable(MoveAbleFrame.Frame, true)
endif
endif
endfunction
local timer t
local real R
if time>0. then
set t = CreateTimer()
call TimerStart(t,time,false,null)
loop
set R=TimerGetRemaining(t)
exitwhen R<=0.
call TriggerSleepAction(R)
endloop
call DestroyTimer(t)
set t=null
endif
endfunction
real mouseX = 0.0
real mouseY = 0.0
real mouseX_prev = 0.0
real mouseY_prev = 0.0
real mouseX_interp = 0.0
real mouseY_interp = 0.0
real interpProgress = 1.0
real interpSpeed = 0
endglobals
local real newX = BlzGetTriggerPlayerMouseX()
local real newY = BlzGetTriggerPlayerMouseY()
set GetFunctionName_DEBUG = "OnMouseMove"
set mouseX_prev = mouseX
set mouseY_prev = mouseY
set mouseY = newY
set interpProgress = 0.0
endfunction
local real dist
local real dynamicSpeed
local real dx
local real dy
local real distMouse
call updateDebugFrame()
set GetFunctionName_DEBUG = "update2"
set dx = mouseX - mouseX_prev
set dy = mouseY - mouseY_prev
set distMouse = SquareRoot(dx * dx + dy * dy)
if interpProgress > 1.0 then
set interpProgress = 1.0
endif
set mouseY_interp = mouseY_prev + (mouseY - mouseY_prev) * interpProgress
set targetY = mouseY_interp
set dynamicSpeed = moveSpeed + dist * 0.2
if dynamicSpeed > 0.08 then
set dynamicSpeed = 0.08
endif
set currentY = currentY + (targetY - currentY) * dynamicSpeed
endif
endfunction
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real z
set GetFunctionName_DEBUG = "CoordsMouse"
set GetTriggerName_DEBUG = "MOUSE_MOVE_Trigger"
if flag == true then
call MoveLocation(moveLoc, x, y)
set z = GetLocationZ(moveLoc)
call World2Screen(x,y,z)
set mouseY_prev = mouseY
set mouseX = ScreenX
set mouseY = ScreenY
set interpProgress = 0.0
endif
endfunction
local integer playerIndex = 0
local timer Timer = CreateTimer()
local timer Timer2 = CreateTimer()
call PolledWait2(0.01)
set MoveAbleFrame = structMoveAbleFrame.create()
set MoveAbleFrame.TriggerFrameEnter = CreateTrigger()
set MoveAbleFrame.TriggerFrameEnterAction = TriggerAddAction(MoveAbleFrame.TriggerFrameEnter,function GetTriggerPlayerHoveredFrame)
set MoveAbleFrame.TriggerFrameLeave = CreateTrigger()
set MoveAbleFrame.TriggerFrameLeaveAction = TriggerAddAction(MoveAbleFrame.TriggerFrameLeave, function GetTriggerPlayerHoveredFrameNull)
set MoveAbleFrame.MouseClickTriggerAction = TriggerAddAction(MoveAbleFrame.MouseClickTrigger, function MouseClick)
set MoveAbleFrame.MouseReleaseTrigger = CreateTrigger()
set MoveAbleFrame.MouseReleaseTriggerAction = TriggerAddAction(MoveAbleFrame.MouseReleaseTrigger, function MouseRelease)
set MoveAbleFrame.MOUSE_MOVE_Trigger = CreateTrigger()
set MoveAbleFrame.MOUSE_MOVE_TriggerAction = TriggerAddAction(MoveAbleFrame.MOUSE_MOVE_Trigger, function CoordsMouse)
exitwhen playerIndex == GetBJMaxPlayers()
call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseClickTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_DOWN)
call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseReleaseTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_UP)
call TriggerRegisterPlayerEvent(MoveAbleFrame.MOUSE_MOVE_Trigger, Player(playerIndex), EVENT_PLAYER_MOUSE_MOVE)
set playerIndex = playerIndex + 1
endloop
call ExecuteFunc("onGameStart")
call TimerStart(Timer, 0.003, true, function update2)
endfunction
real targetX = 0.0
real targetY = 0.0
real currentX = 0.0
real currentY = 0.0
real moveSpeed = 0.02 от 0 до 1: выше — быстрее, ниже — плавнее
real prevTargetX = 0.0
real prevTargetY = 0.0
real deltaX = 0.0
real deltaY = 0.0
endglobals
boolean Enabled = true
framehandle Frame = null
framehandle PlayerHoveredFrame
framepointtype FramePoint
trigger TriggerFrameEnter
triggeraction TriggerFrameEnterAction
trigger TriggerFrameLeave
triggeraction TriggerFrameLeaveAction
trigger MouseClickTrigger
triggeraction MouseClickTriggerAction
trigger MouseReleaseTrigger
triggeraction MouseReleaseTriggerAction
trigger MOUSE_MOVE_Trigger
triggeraction MOUSE_MOVE_TriggerAction
endstruct
structMoveAbleFrame MoveAbleFrame
endglobals
if GetLocalPlayer() == p then
if flag == null then
set MoveAbleFrame.Enabled = not MoveAbleFrame.Enabled
else
set MoveAbleFrame.Enabled = flag
endif
endif
return MoveAbleFrame.Enabled
endfunction
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameEnter, frame, FRAMEEVENT_MOUSE_ENTER)
call BlzTriggerRegisterFrameEvent(MoveAbleFrame.TriggerFrameLeave , frame, FRAMEEVENT_MOUSE_LEAVE)
endfunction
set MoveAbleFrame.Frame = frame
if framePoint == null then
set framePoint = FRAMEPOINT_CENTER
endif
set MoveAbleFrame.FramePoint = framePoint
endfunction
call BJDebugMsg("moveFrame: called x=" + R2S(x) + " y=" + R2S(y))
call BlzFrameClearAllPoints(MoveAbleFrame.Frame)
call BlzFrameSetAbsPoint(MoveAbleFrame.Frame, MoveAbleFrame.FramePoint, x, y)
endfunction
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
set GetTriggerName_DEBUG = "TriggerFrameEnter"
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = BlzGetTriggerFrame()
endif
endfunction
set GetTriggerName_DEBUG = "TriggerFrameLeave"
if GetLocalPlayer() == GetTriggerPlayer() then
set MoveAbleFrame.PlayerHoveredFrame = null
endif
endfunction
location moveLoc = Location(0, 0)
boolean flag = false
endglobals
local player p = GetTriggerPlayer()
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real z
call updateDebugFrame()
set GetFunctionName_DEBUG = "MouseClick"
set GetTriggerName_DEBUG = "MouseClickTrigger"
call MoveLocation(moveLoc, x, y)
set z = GetLocationZ(moveLoc)
if MoveAbleFrame.PlayerHoveredFrame != null then
call BJDebugMsg("MouseClick: frame is not null: " + BlzFrameGetName(MoveAbleFrame.PlayerHoveredFrame))
if MoveAbleFrame.Enabled then
if GetLocalPlayer() == p then
set flag = true
call startMoving(MoveAbleFrame.PlayerHoveredFrame, FRAMEPOINT_CENTER)
call BlzFrameSetEnable(MoveAbleFrame.PlayerHoveredFrame, false)
call World2Screen(x,y,z)
set mouseX = ScreenX
set mouseY = ScreenY
set mouseX_prev = ScreenX
set mouseY_prev = ScreenY
set currentX = ScreenX
set currentY = ScreenY
set interpProgress = 1.0
endif
endif
else
call BJDebugMsg("MouseClick: PlayerHoveredFrame is null")
endif
endif
endfunction
set flag = false
set GetFunctionName_DEBUG = "MouseRelease"
set GetTriggerName_DEBUG = "MouseReleaseTrigger"
if BlzGetTriggerPlayerMouseButton() == MOUSE_BUTTON_TYPE_RIGHT then
if MoveAbleFrame.Frame != null then
call BlzFrameSetEnable(MoveAbleFrame.Frame, true)
endif
endif
endfunction
local timer t
local real R
if time>0. then
set t = CreateTimer()
call TimerStart(t,time,false,null)
loop
set R=TimerGetRemaining(t)
exitwhen R<=0.
call TriggerSleepAction(R)
endloop
call DestroyTimer(t)
set t=null
endif
endfunction
real mouseX = 0.0
real mouseY = 0.0
real mouseX_prev = 0.0
real mouseY_prev = 0.0
real mouseX_interp = 0.0
real mouseY_interp = 0.0
real interpProgress = 1.0
real interpSpeed = 0
endglobals
local real newX = BlzGetTriggerPlayerMouseX()
local real newY = BlzGetTriggerPlayerMouseY()
set GetFunctionName_DEBUG = "OnMouseMove"
set mouseX_prev = mouseX
set mouseY_prev = mouseY
set mouseY = newY
set interpProgress = 0.0
endfunction
local real dist
local real dynamicSpeed
local real dx
local real dy
local real distMouse
call updateDebugFrame()
set GetTriggerName_DEBUG = "onTriggerInit"
set GetFunctionName_DEBUG = "update2"
set dx = mouseX - mouseX_prev
set dy = mouseY - mouseY_prev
set distMouse = SquareRoot(dx * dx + dy * dy)
if interpProgress > 1.0 then
set interpProgress = 1.0
endif
set mouseY_interp = mouseY_prev + (mouseY - mouseY_prev) * interpProgress
set targetY = mouseY_interp
set dynamicSpeed = moveSpeed + dist * 0.1
if dynamicSpeed > 0.05 then
set dynamicSpeed = 0.05
endif
set currentY = currentY + (targetY - currentY) * dynamicSpeed
endif
endfunction
local real x = BlzGetTriggerPlayerMouseX()
local real y = BlzGetTriggerPlayerMouseY()
local real z
set GetFunctionName_DEBUG = "CoordsMouse"
set GetTriggerName_DEBUG = "MOUSE_MOVE_Trigger"
if flag == true then
call MoveLocation(moveLoc, x, y)
set z = GetLocationZ(moveLoc)
call World2Screen(x,y,z)
set mouseY_prev = mouseY
set mouseX = ScreenX
set mouseY = ScreenY
set interpProgress = 0.0
endif
endfunction
local integer playerIndex = 0
local timer Timer = CreateTimer()
local timer Timer2 = CreateTimer()
call PolledWait2(0.01)
set MoveAbleFrame = structMoveAbleFrame.create()
set MoveAbleFrame.TriggerFrameEnter = CreateTrigger()
set MoveAbleFrame.TriggerFrameEnterAction = TriggerAddAction(MoveAbleFrame.TriggerFrameEnter,function GetTriggerPlayerHoveredFrame)
set MoveAbleFrame.TriggerFrameLeave = CreateTrigger()
set MoveAbleFrame.TriggerFrameLeaveAction = TriggerAddAction(MoveAbleFrame.TriggerFrameLeave, function GetTriggerPlayerHoveredFrameNull)
set MoveAbleFrame.MouseClickTriggerAction = TriggerAddAction(MoveAbleFrame.MouseClickTrigger, function MouseClick)
set MoveAbleFrame.MouseReleaseTrigger = CreateTrigger()
set MoveAbleFrame.MouseReleaseTriggerAction = TriggerAddAction(MoveAbleFrame.MouseReleaseTrigger, function MouseRelease)
set MoveAbleFrame.MOUSE_MOVE_Trigger = CreateTrigger()
set MoveAbleFrame.MOUSE_MOVE_TriggerAction = TriggerAddAction(MoveAbleFrame.MOUSE_MOVE_Trigger, function CoordsMouse)
exitwhen playerIndex == GetBJMaxPlayers()
call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseClickTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_DOWN)
call TriggerRegisterPlayerEvent(MoveAbleFrame.MouseReleaseTrigger, Player(playerIndex), EVENT_PLAYER_MOUSE_UP)
call TriggerRegisterPlayerEvent(MoveAbleFrame.MOUSE_MOVE_Trigger, Player(playerIndex), EVENT_PLAYER_MOUSE_MOVE)
set playerIndex = playerIndex + 1
endloop
call ExecuteFunc("onGameStart")
call TimerStart(Timer, 0.001, true, function update2)
endfunction
P.S продолжаю эксперименты в попытках обойти задержку события, может что-то накопаю
Надо будет понять есть ли ещё варианты, ну и применить как-то для более идеальной плавности :)