Jump to content

¿hacer que n dxDrawRec cambie de color con el mouse encima?


lLinux

Recommended Posts

Buenas a todos.

Lo que quiero logar es que un dxDrawRectagle cambien de color cuando pases o pongas el mouse por encima de el... o sea lograr el mismo efecto que un botón... obteniendo posiciones del cursor...

Lo que quiero hacer es crear un botón prácticamente.

- Gracias por su atención.

Link to comment

Tengo un recurso que hace algo parecido; es algo antiguo y poco eficiente, pero te dejare el código:

local sW, sH = guiGetScreenSize() 
local lobFont = dxCreateFont ( 'Lobby/Files/LobbyFont.ttf', 0.0234375*sH ) 
local contFont = dxCreateFont ( 'Lobby/Files/ContentFont.ttf', 0.026041667*sH ) 
  
local gms = { 
[1] = { 0.04, 0.80, 0.20, 0.20 }, --Classic 
[2] = { 0.28, 0.80, 0.20, 0.20 }, --Time 
[3] = { 0.52, 0.80, 0.20, 0.20 }, --Teams 
[4] = { 0.76, 0.80, 0.20, 0.20 }  --Score 
} 
  
local gIms = { 
[1] = { 0.04*sW, 0.80*sH, 0.24*sW, sH }, --Classic 
[2] = { 0.28*sW, 0.80*sH, 0.48*sW, sH }, --Time 
[3] = { 0.52*sW, 0.80*sH, 0.72*sW, sH }, --Teams 
[4] = { 0.76*sW, 0.80*sH, 0.96*sW, sH }  --Score 
} 
  
local gColors = { 
[1] = {0, 110, 240}, 
[2] = {240, 110, 0}, 
[3] = {110, 240, 0}, 
[4] = {240, 0, 110} 
} 
  
local widgets = { 
[1] = { 0.11*sW, 0.575*sH, 0.88*sW, 0.78*sH }, --Gamemode Description 
[2] = { 0.35*sW, 0.5*sH, 0.65*sW, 0.6*sH }, --Gamemode Name 
[3] = { 0.00, 0.25, 0.9999, 0.20 }, --Middle Square 
[4] = { 0.29*sW, 0.06*sH, 0.42*sW, 0.17*sH }, --Logo 
[5] = { 0.35*sW, 0.3*sH, 0.65*sW, 0.4*sH } --Lobby Text 
} 
  
local gameNames = { 
[1] =  'Classic Battle' , 
[2] =  'Time Battle' , 
[3] =  'Cooperative',  
[4] =  'Get the Points' 
} 
  
local shortNames = { 
[1] =  'Classic\nShooting' , 
[2] =  'Time\nBattle' , 
[3] =  'Teams\nBattle',  
[4] =  'Point\nCollector' 
} 
  
local gameDescriptions = { 
[1] = 'Acaba con todos \ny evita ser #FF0000eliminado#000000!', 
[2] = '#FF0000Asesina #000000mas que nadie\n antes de que acabe el tiempo!', 
[3] = 'Protege a tu equipo\n y evita #FF0000morir#000000!', 
[4] = 'Ve consiguiendo puntos, \npero si #ff0000mueres #000000los perderas!' 
} 
  
  
local bR, bG, bB = 0, 0, 0 --Default Colored Square 
local fR, fG, fB = 0, 0, 0 
local selected = false 
  
  
showPlayerHudComponent( 'all', false ) 
local appearing = false 
alpha = 0 
  
function showLobby( show ) 
    if show then 
        addEventHandler( 'onClientRender', root, drawLobby ) 
        appearing = true 
    elseif not show then 
        appearing = false 
        setTimer( function() removeEventHandler( 'onClientRender', root, drawLobby ) end, 2590, 1 ) 
    end 
        fadeCamera( show, 2.5 ) 
        showChat( not show ) 
        showCursor( show ) 
end 
         
             
function drawLobby() 
    if appearing then 
        alpha = math.min( 255, alpha + 15 ) 
    else 
        alpha = math.max( 0, alpha - 20 ) 
    end 
            dxDrawRectangle( 0, 0, sW, sH, tocolor( 245, 245, 245, alpha ), false ) --Background 
            dxDrawRectangle( widgets[3][1]*sW, widgets[3][2]*sH, widgets[3][3]*sW, widgets[3][4]*sH, tocolor( fR, fG, fB, alpha ), false ) 
            dxDrawText( 'Lobby', widgets[5][1], widgets[5][2], widgets[5][3], widgets[5][4], tocolor( 245, 245, 245, alpha ), 1.12, lobFont, 'center', 'center' ) 
            dxDrawText( selected and gameNames[selected] or '', widgets[2][1], widgets[2][2], widgets[2][3], widgets[2][4], tocolor( fR, fG, fB, alpha ), 0.75, contFont, 'center', 'top' ) 
            dxDrawText( selected and gameDescriptions[selected] or '', widgets[1][1], widgets[1][2], widgets[1][3], widgets[1][4], tocolor( 0, 0, 0, alpha ), 0.6, contFont, 'center', 'top', false, false, false, true ) 
     
        for id =1,4 do 
            dxDrawRectangle( gms[id][1]*sW, gms[id][2]*sH, gms[id][3]*sW, gms[id][4]*sH, tocolor( gColors[id][1],gColors[id][2],gColors[id][3], alpha), false ) 
            dxDrawText( shortNames[id]..'\n(0/0)', gIms[id][1] ,gIms[id][2], gIms[id][3], gIms[id][4], tocolor( 245, 245, 245, alpha ), selected == id and math.min( 0.85, fadeSize ) or 0.6, contFont, 'center', 'center' ) 
        end 
  
        if selected then 
            fadeSize = fadeSize + 0.06 
        end 
             
        --Smooth n' Fading 
            if isCursorShowing() then 
                local sX, sY, _, _, _ = getCursorPosition() 
                --Classic 
                    if sX >= gms[1][1] and sX <= gms[1][1]+gms[1][3] and sY >= gms[1][2] and sY <= gms[1][2]+gms[1][4] then 
                        if selected ~= 1 then 
                            selected = 1 
                            bR, bG, bB = unpack( gColors[1] ) 
                            fadeSize = 0.6 
                        end 
                --Time 
                    elseif sX >= gms[2][1] and sX <= gms[2][1]+gms[2][3] and sY >= gms[2][2] and sY <= gms[2][2]+gms[2][4] then 
                        if selected ~= 2 then 
                            selected = 2 
                            bR, bG, bB = unpack( gColors[2] ) 
                            fadeSize = 0.6 
                        end          
                --Teams  
                    elseif sX >= gms[3][1] and sX <= gms[3][1]+gms[3][3] and sY >= gms[3][2] and sY <= gms[3][2]+gms[3][4] then 
                        if selected ~= 3 then 
                            selected = 3 
                            bR, bG, bB = unpack( gColors[3] ) 
                            fadeSize = 0.6 
                        end 
                --Score 
                    elseif sX >= gms[4][1] and sX <= gms[4][1]+gms[4][3] and sY >= gms[4][2] and sY <= gms[4][2]+gms[4][4] then 
                        if selected ~= 4 then 
                            selected = 4 
                            bR, bG, bB = unpack( gColors[4] ) 
                            fadeSize = 0.6 
                        end 
                    else 
                        if selected then 
                            selected = false 
                            bR, bG, bB = 0, 0, 0 
                        end 
                    end 
             
        --Rainbow Color 
                --Red 
                    if fR >= bR then 
                        fR = math.max( bR, fR - 25 ) 
                    elseif fR <= bR then 
                        fR = math.min( bR, fR + 25 ) 
                    end 
                     
                --Blue 
                    if fB >= bB then 
                        fB = math.max( bB, fB - 25 ) 
                    elseif fB <= bB then 
                        fB = math.min( bB, fB + 25 ) 
                    end 
                     
                --Green 
                    if fG >= bG then 
                        fG = math.max( bG, fG - 25 ) 
                    elseif fG <= bG then 
                        fG = math.min( bG, fG + 25 ) 
                    end 
            end 
    end 
     
    --showLobby( true ) 

Lo que hace es comparar si la posición del cursor esta dentro de las posiciones de los rectángulos dibujado. Te advierto que mi código es un tanto largo, por lo tanto, puede ser difícil de comprender al principio.

Te dejo un vídeo de su funcionamiento:

Link to comment
@Alexs Una pregunta,

¿En qué parte del código hace que el color aumente y baje la intensidad?

Es en lo de abajo que dice math.min y math.max ?

Si.

* En el futuro me abstendré de responder a tus preguntas obvias; evita hacerlas, por favor.

Hmm, disculpa si te ofendí preguntando algo obvio para ti, estaba del celular, cuando llegué a casa logré ver la función de mat.min y de math.max. Entonces, comprendí.

Gracias.

Link to comment
@Alex_Steel Como calculaste las posiciones... yo se que con getCursorPosition, pero a lo que me refiero... eso servirá en todas las resoluciones de pantalla? o toca hacer alguna ecuación matemática o algo así?

El contenido del recurso se ajusta a las distintas resoluciones de pantalla. La información referida a la posición del cursor es conseguida utilizando 'getCursorPosition' y los datos de los rectángulos están dentro de una tabla; el resto son comparaciones simples.

* Todos los datos comparados (incluso los conseguidos mediante 'getCursorPosition') son relativos a la pantalla, es decir, son valores entre 0 y 1.

Link to comment

@Alexs_Steel

he intenta hacerlo ... si cambia de color pero tambien cambia de color si lo pongo mas abajo de donde es. mira

local data = { 
    colorn = {255, 0, 0, 255}, 
    colore = {255, 255, 0, 255}, 
    cursorpos = {0.43, 0.40, 0.56, 0.47}-- x, y, x1, y1 
} 
r, g, b, a = unpack(data.colorn) 
  
addEventHandler("onClientRender", root, 
    function() 
         
        dxDrawRectangle(599, 313, 174, 52, tocolor(0, 0, 0, 255), false) 
        dxDrawRectangle(600, 314, 172, 50, tocolor(r, g, b, a), false) 
         
        if isCursorShowing() then 
            cx, cy, _, _, _ = getCursorPosition() 
             
            if cx >= data["cursorpos"][1] and cx <= data["cursorpos"][1]+data["cursorpos"][3] and cy >= data["cursorpos"][2] and cy <= data["cursorpos"][2]+data["cursorpos"][4] then 
                r, g, b, a = unpack(data.colore) 
            else 
                r, g, b, a = unpack(data.colorn) 
            end 
        end 
    end 
) 
showCursor(true) 

Disculpa si eso te parece muy noob pero en cuestiones de posiciones con cursor soy un noob entero.

Te agradeceria que me dice que salio mas y como arreglarlo.

Link to comment

No entiendo para que lo sumaste xD

  
local data = { 
    colorn = {255, 0, 0, 255}, 
    colore = {255, 255, 0, 255}, 
    cursorpos = {0.43, 0.40, 0.56, 0.47}-- x, y, x1, y1 
} 
r, g, b, a = unpack(data.colorn) 
  
addEventHandler("onClientRender", root, 
    function() 
        
        dxDrawRectangle(599, 313, 174, 52, tocolor(0, 0, 0, 255), false) 
        dxDrawRectangle(600, 314, 172, 50, tocolor(r, g, b, a), false) 
        
        if isCursorShowing() then 
            cx, cy, _, _, _ = getCursorPosition() 
            
            if cx >= data["cursorpos"][1] and cx <= data["cursorpos"][3] and cy >= data["cursorpos"][2] and cy <= data["cursorpos"][4] then 
                r, g, b, a = unpack(data.colore) 
            else 
                r, g, b, a = unpack(data.colorn) 
            end 
        end 
    end 
) 
showCursor(true) 
  

Link to comment
No entiendo para que lo sumaste xD
  
local data = { 
    colorn = {255, 0, 0, 255}, 
    colore = {255, 255, 0, 255}, 
    cursorpos = {0.43, 0.40, 0.56, 0.47}-- x, y, x1, y1 
} 
r, g, b, a = unpack(data.colorn) 
  
addEventHandler("onClientRender", root, 
    function() 
        
        dxDrawRectangle(599, 313, 174, 52, tocolor(0, 0, 0, 255), false) 
        dxDrawRectangle(600, 314, 172, 50, tocolor(r, g, b, a), false) 
        
        if isCursorShowing() then 
            cx, cy, _, _, _ = getCursorPosition() 
            
            if cx >= data["cursorpos"][1] and cx <= data["cursorpos"][3] and cy >= data["cursorpos"][2] and cy <= data["cursorpos"][4] then 
                r, g, b, a = unpack(data.colore) 
            else 
                r, g, b, a = unpack(data.colorn) 
            end 
        end 
    end 
) 
showCursor(true) 
  

En el codigo de el... lo sumo... observa bien

Link to comment
Yo hoy haciendo algo parecido pero con otra cosa lo hice como te lo puse y me funcionó, sólo que usé variables no tablas.

PD: ¿Te funcionó?

Si me funciono... lo que pasa es que con ese + tambien hay una posiciones fuera de de las del boton... no se si me entiendes

Link to comment

he encontrado algo parecido en otro topic:

Pero eso mismo hice yo... y se me sale de la zona que quiero... osea va mas haya de donde deberia de ser las posiciones.

local data = { 
    [1] = { 
        posX = 0, 
        posY = 0, 
        posW = 0, 
        posH = 0, 
        hovering = false, 
        colors = { 23,23,23,204 } 
    }, 
    [2] = { 
        posX = 0, 
        posY = 0, 
        posW = 0, 
        posH = 0, 
        hovering = false, 
        colors = { 23,23,23,204 } 
    }, 
    [3] = { 
        posX = 0, 
        posY = 0, 
        posW = 0, 
        posH = 0, 
        hovering = false, 
        colors = { 23,23,23,204 } 
    } 
} 
  
  
addEventHandler ( "onClientCursorMove", root, function ( _, _, cx, cy ) 
    for i, v in pairs ( data ) do 
        local x, y, w, h = v.posX, v.posY, v.posW, v.posH; 
        if ( cx >= x and cx <= x+w and cy >= y and cy <= y+h ) then 
            data[i].hovering = true 
        else 
            data[i].hovering = false 
        end 
    end 
end ) 

Este es el error que digo que pasa si pongo el +

PWW7wNB.jpg

Link to comment

La suma es realizada por un motivo simple referente a la función 'dxDrawRectangle'; si revisas la documentación existente notaras que para dibujar estos rectángulos se utilizan posiciones iniciales y tamaños, por lo tanto, para conseguir las posiciones finales ejecuto una suma entre la posición inicial y el tamaño, con esto consigo los datos necesarios (como ya mencioné, posición inicial y posición final del rectángulo dibujado) para realizar la comparación con la posición del cursor.

* En síntesis: mis datos son la posición inicial X, la posición inicial Y, el ancho y el largo, pero para realizar la comparación necesito la posición final X (se consigue sumando la posición inicial X con el ancho) y la posición final Y (se consigue sumando la posición inicial Y con el largo).

* Espero que esta explicación sea comprensible, en caso de que no sea así avísame y haré un diagrama que la grafique.

Link to comment

En el código que yo le di a Linux funciona bien y no hice ninguna suma. (En un recurso que hice para mi servidor hago algo parecido y es igual, tampoco hay que sumar nada)

Las sumas las hago por ejemplo para detectar cuando clickea adentro de un rectángulo DX, comparo si la posición X del cursor es más de la posición del arg1+arg3 (posición X + ancho) y si es menor a arg2+arg4 (posición Y + largo).

Link to comment
La suma es realizada por un motivo simple referente a la función 'dxDrawRectangle'; si revisas la documentación existente notaras que para dibujar estos rectángulos se utilizan posiciones iniciales y tamaños, por lo tanto, para conseguir las posiciones finales ejecuto una suma entre la posición inicial y el tamaño, con esto consigo los datos necesarios (como ya mencioné, posición inicial y posición final del rectángulo dibujado) para realizar la comparación con la posición del cursor.

* En síntesis: mis datos son la posición inicial X, la posición inicial Y, el ancho y el largo, pero para realizar la comparación necesito la posición final X (se consigue sumando la posición inicial X con el ancho) y la posición final Y (se consigue sumando la posición inicial Y con el largo).

* Espero que esta explicación sea comprensible, en caso de que no sea así avísame y haré un diagrama que la grafique.

Disculpa que sea tan ignorante, pero nadies nacio aprendido...

Segun lo que yo entendi es qe `primero necesitamos sumar la posicion x del rectangulo con el ancho del rectangulo... lo otro no lo entedi muy bien...

Me puede dar un ejemplo o algo que se me sea maas facil aprender.

-Gracias por tu ayuda y disculpa

Link to comment
En el código que yo le di a Linux funciona bien y no hice ninguna suma. (En un recurso que hice para mi servidor hago algo parecido y es igual, tampoco hay que sumar nada)

Las sumas las hago por ejemplo para detectar cuando clickea adentro de un rectángulo DX, comparo si la posición X del cursor es más de la posición del arg1+arg3 (posición X + ancho) y si es menor a arg2+arg4 (posición Y + largo).

Es distinto, en mis códigos los datos son utilizados y aprovechados en toda oportunidad, en el tuyo son ajenos al dibujado de los rectángulos e incluso inútiles en términos económicos.

* @lLinux no se me ocurre una explicación mas simple, pido al resto de mis compañeros del foro que, por favor, realicen una aclaración en términos más sencillos.

Link to comment
no se me ocurre una explicación mas simple, pido al resto de mis compañeros del foro que, por favor, realicen una aclaración en términos más sencillos.

Mira, mi problema es que no se que valores x son los que sumates el del cursor con el del rectangulo o solso los del rectangulo.

Link to comment

Logre hacer eso pero solo con:

x, y, w, h = 600, 314, 172, 50 -- dxDtae 
  
addEventHandler("onClientRender", root, 
    function() 
         
        dxDrawRectangle(599, 313, 174, 52, tocolor(0, 0, 0, 255), false) 
        dxDrawRectangle(x, y, w, h, tocolor(r, g, b, a), false) 
    end 
) 
showCursor(true) 
  
addEventHandler ( "onClientCursorMove", root, function ( _, _, cx, cy ) 
        if ( cx >= x and cx <= x+w and cy >= y and cy <= y+h ) then 
            r, g, b, a = unpack(data.colore) 
        else 
            r, g, b, a = unpack(data.colorn) 
        end 
end ) 
  

Link to comment

El código que utilizas tiene los mismo problemas que el de @Tomas, las variables están de más y no se ajustaría a otras resoluciones.

Realizare una explicación detallada de cada paso que seguí para escribir el código que publique como ejemplo:

Para comenzar, los datos de los rectángulos que se dibujan están almacenados en la siguiente tabla:

local gms = { 
[1] = { 0.04, 0.80, 0.20, 0.20 }, --Classic 
[2] = { 0.28, 0.80, 0.20, 0.20 }, --Time 
[3] = { 0.52, 0.80, 0.20, 0.20 }, --Teams 
[4] = { 0.76, 0.80, 0.20, 0.20 }  --Score 
} 

Con el fin de ejecutar esta explicación de manera amena, utilizare solo los datos que anote como 'Classic'.

[1] = { 0.04, 0.80, 0.20, 0.20 } --Classic 

La estructura de esta tabla es:

[ID] = { POSICIÓN X, POSICIÓN Y, ANCHO, ALTO } 

La "ID" es aleatoria e incluso innecesaria, pues no realizo ordenamiento alguno; el resto de los datos son:

"POSICION X": Coordenada del eje horizontal de la pantalla desde donde se origina el dibujado del rectángulo.

"POSICION Y": Coordenada del eje vertical de la pantalla desde donde se origina el dibujado del rectángulo.

"ANCHO": Valor que define el ancho del rectángulo, es decir, hasta donde se dibujara el rectángulo a partir de la coordenada en el eje horizontal (X).

"ALTO": Valor que define el alto del rectángulo, es decir, hasta donde se dibujara el rectángulo a partir de la coordenada en el eje vertical (Y).

Ahora, es necesario que se entienda lo siguiente:

local sX, sY, _, _, _ = getCursorPosition() 
                --Classic 
                    if sX >= gms[1][1] and sX <= gms[1][1]+gms[1][3] and sY >= gms[1][2] and sY <= gms[1][2]+gms[1][4] then 
                        if selected ~= 1 then 
                            selected = 1 
                            bR, bG, bB = unpack( gColors[1] ) 
                            fadeSize = 0.6 
                        end 
                   end 
  
--RECORDAR QUE LA TABLA 'gms' es: 
  
local gms = { 
[1] = { 0.04, 0.80, 0.20, 0.20 }, --Classic 
[2] = { 0.28, 0.80, 0.20, 0.20 }, --Time 
[3] = { 0.52, 0.80, 0.20, 0.20 }, --Teams 
[4] = { 0.76, 0.80, 0.20, 0.20 }  --Score 
} 

Si conoces el funcionamiento de las tablas en Lua comprenderás que esta condicional resulta en:

if sX >= 0.04 and sX <= 0.04+0.20 and sY >= 0.80 and sY <= 0.80+0.20 then 

En caso de que te preguntes por qué se utilizan valores entre 0 y 1, esto es debido a la función 'getCursorPosition':

The first two values are the 2D relative screen coordinates of the cursor: cursorX goes from 0 (left side of the screen) to 1 (right side)

Es decir: Los primeros dos valores son coordenadas bi-dimensionales del cursor relativas a la pantalla: cursorX ("sX" en mi código) va desde 0 (lado izquierdo de la pantalla) a 1 (lado derecho de la pantalla); cursorY ("sY" en mi código) va desde 0 (zona superior de la pantalla) a 1 (zona inferior de la pantalla).

Continuando con la explicación, para realizar la ubicación visual del cursor (es decir, conocer dentro de cual rectángulo esta posicionado) es necesario utilizar solo coordenadas, pero esto es un problema ya que, tal como expliqué, en la tabla están almacenadas coordenadas y valores, por lo tanto, se debe realizar una suma para convertir estos valores en coordenadas efectivas para nuestros fines:

"POSICION FINAL X": La suma entre "POSICION X" y "ANCHO".

"POSICION FINAL Y": La suma entre "POSICION Y" y "ALTO".

Espero que esto aclare todas tus dudas, en caso de que no sea así, puedes hablarme por Skype para resolver los detalles específicos y otras dudas.

Link to comment

Segun como entendi deberia de quedar asi no?

local x, y, w, h = 600, 314, 172, 50 
local color = tocolor(255, 0, 0, 255) 
  
  
addEventHandler("onClientRender", root, function() 
  
dxDrawRectangle(x, y, w, h, color, false) 
  
if isCursorShowing() then 
    sx, sy, _, _, _ = getCursorPosition() 
        if sX >= x and sX <= x+w and sY >= y and sY <= y+h then 
            color = tocolor(255, 255, 0, 255) 
        end 
    end 
end) 

Por cierto... porque a ti te quedan en tipo: "0.04, 0.80, 0.20, 0.20" y a mi en "600, 314, 172, 50"

Link to comment
  • Recently Browsing   0 members

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