Jump to content

How to get positions from another function?


spaghetti1337

Recommended Posts

I want to get the dxDrawRectangleBox's position from Panel function inside the onClick function, how can I do that?

 

function Panel()
    local cameraX, cameraY, cameraZ = getCameraMatrix();
    
    for element, value in pairs(renderCache) do
        local distance = value["distance"]
		   if distance <= maxDistance then
            local boneX, boneY, boneZ = getElementPosition(element);
            local size = 1 - (distance / maxDistance);
            local screenX, screenY = getScreenFromWorldPosition(boneX, boneY, boneZ + (1.1));

            if screenX and screenY then
                local alpha = interpolateBetween(0,0,0,255, 0, 0, size, "Linear")
                local text = "Text"
                local length = dxGetTextWidth(text, size, font) + 15 * size
                local x = length
                local y = 25 * size;
                dxDrawRectangleBox(screenX - x/2, screenY - y / 2, x, y, tocolor(20,20,20,alpha * 0.7)); --- I want to put these positions inside the isMouseInPosition function 
                dxDrawText(text, screenX, screenY, screenX, screenY, tocolor(255,255,255,alpha), size, font, "center", "center");
            end
        end
    end
end


function isMouseInPosition ( x, y, width, height )
	if ( not isCursorShowing( ) ) then
		return false
	end
    local sx, sy = guiGetScreenSize ( )
    local cx, cy = getCursorPosition ( )
    local cx, cy = ( cx * sx ), ( cy * sy )
    if ( cx >= x and cx <= x + width ) and ( cy >= y and cy <= y + height ) then
        return true
    else
        return false
    end
end


function onClick(button, state)
	if (button == "left") and (state == "up") then
		if isMouseInPosition() then --- I want to put the position here which is in the "Panel" function
			 outputChatBox ("click")
		end
	end
end
addEventHandler( "onClientClick", root, onClick )

 

Link to comment

You either recalculate the positions of the rectangles inside the onClick function or you remember their positions inside of objects like Lua tables.

If you have control over the contents of "renderCache" then you can create rectangle information structures inside of them. Here is an idea (conceptual code):

local clickable_rectangles = {}
local clickable_rect_by_elem = {}
local font = "clear"

local function createClickableRectangle(element)
  local rect = {}
  local size = -- TODO
  
  function rect.getPosition()
    local x = -- TODO
    local y = -- TODO
    
    return x, y
  end
  
  function rect.getSize()
    local w, h = -- TODO
    
    return w, h
  end
  
  table.insert(clickable_rectangles, rect)
  clickable_rect_by_elem[element] = rect
  
  return rect
end

...

function Panel()
    local cameraX, cameraY, cameraZ = getCameraMatrix();
    
    for element, value in pairs(renderCache) do
        local distance = value["distance"]
		   if distance <= maxDistance then
            local boneX, boneY, boneZ = getElementPosition(element);
            local size = 1 - (distance / maxDistance);
            local screenX, screenY = getScreenFromWorldPosition(boneX, boneY, boneZ + (1.1));

            if screenX and screenY then
                local alpha = interpolateBetween(0,0,0,255, 0, 0, size, "Linear")
                local text = "Text"
                local length = dxGetTextWidth(text, size, font) + 15 * size
                local rect = clickable_rect_by_elem[ element ]
                -- TODO: is there always a rectangle?
                local x, y = rect.getPosition()
                local w, h = rect.getSize()
                dxDrawRectangleBox(x, y, w, h, tocolor(20,20,20,alpha * 0.7)); --- I want to put these positions inside the isMouseInPosition function 
                dxDrawText(text, screenX, screenY, screenX, screenY, tocolor(255,255,255,alpha), size, font, "center", "center");
            end
        end
    end
end


function isMouseInPosition ( x, y, width, height )
	if ( not isCursorShowing( ) ) then
		return false
	end
    local sx, sy = guiGetScreenSize ( )
    local cx, cy = getCursorPosition ( )
    local cx, cy = ( cx * sx ), ( cy * sy )
    if ( cx >= x and cx <= x + width ) and ( cy >= y and cy <= y + height ) then
        return true
    else
        return false
    end
end


function onClick(button, state)
	if (button == "left") and (state == "up") then
        for m,n in ipairs(clickable_rectangles) do
            local x, y = n.getPosition()
            local w, h = n.getSize()
            if isMouseInPosition(x, y, w, h) then --- I want to put the position here which is in the "Panel" function
                 outputChatBox ("click")
            end
        end
	end
end
addEventHandler( "onClientClick", root, onClick )

By the way, did you mean "dxDrawRectangle" instead of "dxDrawRectangleBox" ?

Edited by The_GTA
Link to comment
1 hour ago, The_GTA said:

You either recalculate the positions of the rectangles inside the onClick function or you remember their positions inside of objects like Lua tables.

If you have control over the contents of "renderCache" then you can create rectangle information structures inside of them. Here is an idea (conceptual code):

local clickable_rectangles = {}
local clickable_rect_by_elem = {}
local font = "clear"

local function createClickableRectangle(element)
  local rect = {}
  local size = -- TODO
  
  function rect.getPosition()
    local x = -- TODO
    local y = -- TODO
    
    return x, y
  end
  
  function rect.getSize()
    local w, h = -- TODO
    
    return w, h
  end
  
  table.insert(clickable_rectangles, rect)
  clickable_rect_by_elem[element] = rect
  
  return rect
end

...

function Panel()
    local cameraX, cameraY, cameraZ = getCameraMatrix();
    
    for element, value in pairs(renderCache) do
        local distance = value["distance"]
		   if distance <= maxDistance then
            local boneX, boneY, boneZ = getElementPosition(element);
            local size = 1 - (distance / maxDistance);
            local screenX, screenY = getScreenFromWorldPosition(boneX, boneY, boneZ + (1.1));

            if screenX and screenY then
                local alpha = interpolateBetween(0,0,0,255, 0, 0, size, "Linear")
                local text = "Text"
                local length = dxGetTextWidth(text, size, font) + 15 * size
                local rect = clickable_rect_by_elem[ element ]
                -- TODO: is there always a rectangle?
                local x, y = rect.getPosition()
                local w, h = rect.getSize()
                dxDrawRectangleBox(x, y, w, h, tocolor(20,20,20,alpha * 0.7)); --- I want to put these positions inside the isMouseInPosition function 
                dxDrawText(text, screenX, screenY, screenX, screenY, tocolor(255,255,255,alpha), size, font, "center", "center");
            end
        end
    end
end


function isMouseInPosition ( x, y, width, height )
	if ( not isCursorShowing( ) ) then
		return false
	end
    local sx, sy = guiGetScreenSize ( )
    local cx, cy = getCursorPosition ( )
    local cx, cy = ( cx * sx ), ( cy * sy )
    if ( cx >= x and cx <= x + width ) and ( cy >= y and cy <= y + height ) then
        return true
    else
        return false
    end
end


function onClick(button, state)
	if (button == "left") and (state == "up") then
        for m,n in ipairs(clickable_rectangles) do
            local x, y = n.getPosition()
            local w, h = n.getSize()
            if isMouseInPosition(x, y, w, h) then --- I want to put the position here which is in the "Panel" function
                 outputChatBox ("click")
            end
        end
	end
end
addEventHandler( "onClientClick", root, onClick )

By the way, did you mean "dxDrawRectangle" instead of "dxDrawRectangleBox" ?

No, I have a function which named dxDrawRectangleBox and draws a custom box.

 

Well, I stored the positions with setElementData I know that is not the best way and I don't know it will cause some lags for the players or no because it's update the elementdata everytime when he is inside the distance and looking around, currently works fine and doesn't laggy

Edited by spaghetti1337
Link to comment
1 hour ago, spaghetti1337 said:

No, I have a function which named dxDrawRectangleBox and draws a custom box.

 

Well, I stored the positions with setElementData I know that is not the best way and I don't know it will cause some lags for the players or no because it's update the elementdata everytime when he is inside the distance and looking around, currently works fine and doesn't laggy

That is fine, on the pretext that every triangle that is clickable has first been displayed on the screen. There could be a one-frame delay in clicking your rectangles.

The optimal approach is sharing the variables or sharing the code, as mentioned.

setElementData is a very useful function for attaching data to MTA elements. I can recommend you this function if you want to synchronize data across resources or even across the network to clients or the server.

Link to comment

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...