Среда, 13 Ноября 2024, 10:54

Приветствую Вас Гость

[ Новые сообщения · Игроделы · Правила · Поиск ]
  • Страница 1 из 1
  • 1
Конструктор для кнопки (ImageButton), Love2D
burlachenkoДата: Понедельник, 25 Января 2016, 21:20 | Сообщение # 1
постоянный участник
Сейчас нет на сайте
Здравствуйте всем, есть пример рабочей кнопки, но для удобства хотелось бы иметь "библиотеку-конструктор", может кто-то помочь?
Код

click = love.audio.newSource("Click.mp3", "static")  -- звук клик, при нажатии на кнопку "старт", ресурс и путь к нему
start = love.graphics.newImage("start_n.png") -- бекграунд нормальной кнопки
starthover = love.graphics.newImage("start_nn.png") --бекграунд кнопки под курсором
xoffset = 150 -- положение кнопки start по координате "x"
yoffset = 230 -- положение кнопки start по координате "y"

isHover = false -- начальное условие, при котором над кнопкой нет курсора

function love.draw()
              if isHover then
      love.graphics.draw(starthover, xoffset, yoffset) -- кнопка старт- меняется бекграунд кнопки, если над ней курсор
   else
      love.graphics.draw(start, xoffset, yoffset) -- кнопка старт - нормальный бекграунд кнопки, если над ней нет курсора
   end

end

function love.update(dt)

      local data = start:getData()   -- Получаем координаты кнопки, для клика по-ней
     
      function love.mousepressed(mx, my)   
        if ((mx - xoffset) > 0) and ((mx - xoffset) <= data:getWidth() - 1) and ((my - yoffset) > 0) and ((my - yoffset) <= data:getHeight() - 1) then
            click:play() -- проигрываем звук при нажатии на кнопку
   
        end
    end
          
     isHover = false
   --local data = start:getData()
   local mx, my = love.mouse.getPosition()
   if ((mx - xoffset) > 0) and ((mx - xoffset) <= data:getWidth() - 1) and ((my - yoffset) > 0) and ((my - yoffset) <= data:getHeight() - 1) then
      local r, g, b, a = data:getPixel(mx - xoffset - 1, my - yoffset - 1)
      
   isHover = not (a == 1) -- если (a == 0) - прозрачность учитывается
   end

end


могу выложить "love" файл если нужно. Заранее спасибо


MaximTG
sfabrikanДата: Вторник, 26 Января 2016, 07:46 | Сообщение # 2
БЕЗУМЕЦ!!!
Сейчас нет на сайте
burlachenko, здравствуйте. Я бы мог предложить свою кнопку.
Код

utton = {}

function utton:create(x,y,id)
local t = {}
t.toch = false
t.x = x
t.y = y
t.id = id
return setmetatable(t,{__index = self})
end

function utton:update(dt)
    self.toch = false
    local x = love.mouse.getX(); local y = love.mouse.getY()
    if x > self.x and x < self.x + self.id:getWidth()and y < self.y + self.id:getHeight() and y > self.y then
  self.toch = true
    end
end

function utton:draw()
love.graphics.setColor(255,255,255)
if self.toch then
    love.graphics.setColor(0,255,255)
end
love.graphics.draw(self.id,self.x,self.y)
end

function utton:mpress(x,y)
    if self.toch then
  self.toch = false
  return true
    end
return false
end


Это использования кнопки
Код

function love.load()
    button = utton:create(100,100, "Какая нибудь картиночка")
end
function love.update(dt)
    button:update(dt)
end
function love.draw()
    button:draw()
end
function love.mousepressed(x, y)
    if button:mpress(x,y) then
  print("Super Button Pressed!!!")
    end
end


Это я

Сообщение отредактировал sfabrikan - Вторник, 26 Января 2016, 07:48
burlachenkoДата: Вторник, 26 Января 2016, 19:47 | Сообщение # 3
постоянный участник
Сейчас нет на сайте
Здравствуйте sfabrikan, если честно, быстрого ответа не ожидал, за что особая благодарность).
Спасибо за вашу кнопку, все работает без проблем, сейчас "модуль" выглядит так:

Код


utton = {}

function utton:create(x,y,image,imagehover)
local t = {}
t.toch = false
t.x = x
t.y = y
t.image = love.graphics.newImage(image)
t.imagehover = love.graphics.newImage(imagehover)
return setmetatable(t,{__index = self})
end

function utton:update(dt)
    self.toch = false
    local x = love.mouse.getX(); local y = love.mouse.getY()
    if x > self.x and x < self.x + self.image:getWidth()and y < self.y + self.image:getHeight() and y > self.y then
  self.toch = true
    end
end

function utton:draw()
     love.graphics.draw(self.image,self.x,self.y)
     --love.graphics.setColor(255,255,255)
if self.toch then
    --love.graphics.setColor(0,255,255)
    love.graphics.draw(self.imagehover,self.x,self.y)
end
--love.graphics.draw(self.image,self.x,self.y)
end

function utton:mpress(x,y)
    if self.toch then
  self.toch = false
  return true
    end
return false
end



А теперь ещё вопрос, есть какаято возможность включать и выключать реакцию на прозрачность?


MaximTG

Сообщение отредактировал burlachenko - Вторник, 26 Января 2016, 19:47
LetsOffBrainsДата: Вторник, 26 Января 2016, 19:57 | Сообщение # 4
Project SoRDeLKa
Сейчас нет на сайте
Не вижу в коде действий с прозрачностью. Что имеется ввиду под "реакцией на прозрачность"?
Изменение прозрачности при взаимодействии или может отсутствие реакции при каком-то уровне прозрачности кнопки?






Сообщение отредактировал LetsOffBrains - Вторник, 26 Января 2016, 20:02
burlachenkoДата: Вторник, 26 Января 2016, 20:19 | Сообщение # 5
постоянный участник
Сейчас нет на сайте
Здравствуйте LetsOffBrains, в самом верху (первый пост) есть пример где прозрачность учитывается или не учитывается при наведении на "картинку-кнопку", а именно в строчке

Код

isHover = not (a == 1) -- если (a == 0) - прозрачность учитывается


просто я не знаю как из того примера сделать конструктор кнопок)

http://rghost.ru/6nGFRLMgd - здесь лежит пример с кнопкой-картинкой, у которой есть прозрачность и она учитывается.


MaximTG

Сообщение отредактировал burlachenko - Вторник, 26 Января 2016, 20:20
sfabrikanДата: Среда, 27 Января 2016, 09:19 | Сообщение # 6
БЕЗУМЕЦ!!!
Сейчас нет на сайте
Долго понять не мог "Реакция на прозрачность", пришлось гуглить и наткнулся на анализ мочи.

Возможно я понял что вы имели ввиду

Код


function rtopacy(opacy) --Функция реакцию на прозрачность, если у какой-то фиговины есть прозрачность, функция выведет true
      if opacy < 255 then
        return true
      end
return false
end


Использование
Код

function love.load()
alfacolor = 255
timer = 10
end

function love.update(dt)
timer = timer - dt
if timer <= 0 then
    alfacolor = alfacolor/5
    timer = 10
end

if rtopacy(alfacolor) then
     print("Prozrachnost\'!!!!!!")
end
end


Добавлено (27 января 2016, 09:19)
---------------------------------------------
И да я заметил у вас ошибку в этом блоке
Код

function utton:draw()
     love.graphics.draw(self.image,self.x,self.y)
     --love.graphics.setColor(255,255,255)
if self.toch then
    --love.graphics.setColor(0,255,255)
    love.graphics.draw(self.imagehover,self.x,self.y)
end
--love.graphics.draw(self.image,self.x,self.y)
end

Лучше исправьте на такое, так как судя по вашему коду, у вас в случае наведения мышки вторая картинка просто рисуется по верх первой.
Код

function utton:draw()
if self.toch then
    love.graphics.draw(self.imagehover,self.x,self.y)
else
    love.graphics.draw(self.image,self.x,self.y)
end
end


Это я

Сообщение отредактировал sfabrikan - Среда, 27 Января 2016, 09:20
burlachenkoДата: Среда, 27 Января 2016, 21:16 | Сообщение # 7
постоянный участник
Сейчас нет на сайте
К сожаления sfabrikan вы не поняли про прозрачность, это моя вина, так как я не смог донести "мысль"). За ошибку в блоке спасибо, хотя и не принципиально, так как в визуальном плане все выглядит одинаково, но если это хоть как-то оптимизирует игру я использую ваш вариант.

Ну а теперь попробую про "прозрачность" кнопки ещё раз.

У нас уже есть "кнопка-картинка", она состоит из двух изображений, одинаковых по размеру (х,у), кнопка умеет реагировать на курсор, который попадает в пределы её "площади" (а именно - меняет свой бекграунд (например на картинку - 2) когда курсор над кнопкой и возвращает бекграунд в исходное состояние (меняет на картинку - 1), когда курсор за пределами площади кнопки.

Теперь такая ситуация - фон для кнопки с прозрачностью (png), как в том примере, который я разместил выше, есть ли возможность заставить реагировать "кнопку-картинку" (то есть менять бекграунд) только когда курсор над не прозрачной областью? Если можно, можно ли этот параметр указывать отдельно для каждой кнопки?

Ну и ещё один вопрос мне не хватает знаний добавить функции типа "OnHover", то есть "если курсор над кнопкой, тогда такое действие", помогите пожалуйста если не сложно)


MaximTG
sfabrikanДата: Среда, 27 Января 2016, 22:47 | Сообщение # 8
БЕЗУМЕЦ!!!
Сейчас нет на сайте
burlachenko, переберите imagedata по пикселям от 0 до конца изображения по х и у. То есть r, g, b, a = ImageData:getPixel( x, y ).
Вот и все.

Добавлено (27 января 2016, 22:47)
---------------------------------------------

Цитата burlachenko ()
Ну и ещё один вопрос мне не хватает знаний добавить функции типа "OnHover", то есть "если курсор над кнопкой, тогда такое действие", помогите пожалуйста если не сложно)

В кнопке которую я кидал выше уже есть подобное в update


Это я
burlachenkoДата: Четверг, 28 Января 2016, 20:57 | Сообщение # 9
постоянный участник
Сейчас нет на сайте
Представляю результат совместных трудов):

кнопка получилась так

Код


-- button library

button ={}

function button:create(x,y,image,imagehover)
local t = {}
t.isHover = false
t.x = x
t.y = y
t.image = love.graphics.newImage(image)
t.imagehover = love.graphics.newImage(imagehover)
return setmetatable(t,{__index = self})
end

function button:update(dt)

     local data = self.image:getData()
     self.isHover = false
      --function love.mousepressed(mx, my)
   local mx = love.mouse.getX(); local my = love.mouse.getY()
        if ((mx - self.x) > 0) and ((mx - self.x) <= data:getWidth() - 1) and ((my - self.y) > 0) and ((my - self.y) <= data:getHeight() - 1) then
     self.isHover = true
   --  end

end

   self.isHover = false
   local data = self.image:getData()

     -- local mx, my = love.mouse.getPosition()
   if ((mx - self.x) > 0) and ((mx - self.x) <= data:getWidth() - 1) and ((my - self.y) > 0) and ((my - self.y) <= data:getHeight() - 1) then
      local r, g, b, a = data:getPixel(mx - self.x - 1, my - self.y - 1)
   --loadstring(button.action)()
    click:play()  
   self.isHover = not (a == 0) -- если (a == 0) - прозрачность учитывается
   end
    
end

function button:draw()

   if self.isHover then
      love.graphics.draw(self.imagehover,self.x,self.y) -- кнопка старт- меняется бекграунд кнопки, если над ней курсор
   else
      love.graphics.draw(self.image,self.x,self.y) -- кнопка старт - нормальный бекграунд кнопки, если над ней нет курсора
   end

end

function button:mpress(x,y)
    if self.isHover then
  self.isHover = false
  return true
    end
return false
end



сам "main" файл выглядит так:

Код


require "button"

function love.load()

click = love.audio.newSource("Click.mp3", "static")

Start = button:create(200, 200, "start_n.png", "start_nn.png")

end

function love.update(dt)

   Start:update(dt)
   
end

function love.draw()

    Start:draw()
           
end

function love.mousepressed(mx, my)
   if  love.mouse.isDown(1) then
    if Start:mpress(x, y) then
  --print("Super Button Pressed!!!")
    click:play()
    end
    end
end

function love.mouse.getPosition()

      click:play()
   
end



Из этого видно, что я не совсем разобрался с реакцией "isHover" для любого действия и для "конкретной" кнопки, то есть если у нас на сцене будет 10 таких кнопок и на каждую при "isHover" нужно задать какое то действие (переход на другую сцену, печать текста, или проиграть звук), то такой вариант не "прокатит" (можно указать что делать при "isHover" для определенной кнопки?)

Здесь реакция на "прозрачность" уже есть, как добавить такой пункт "настройки" для отдельной кнопки? (в последнем примере там параметр указан в самой "библиотеке", то есть он применяется сразу ко всем кнопкам, что не всегда нужно). Теоретически можно подключить еще один "файл-библиотеки"кнопки (такой-же) но с другим параметром и использовать их при потребности, но даже я понимаю что решение "плохо пахнет")

Ну и проблема которую я ждал) При наведении курсора (в моем примере), должен проиграть "клик", один раз, вместо этого "у нас счелкает" без перерыва, пока курсор над кнопкой, я так догадываюсь что это связано с "процессом" в function button:update(dt), но пока не догадываюсь как решить эту проблему (не только руки растут не "от-туда"))
Если устали отвечать, не обижусь) заранее спасибо.


MaximTG
LetsOffBrainsДата: Понедельник, 01 Февраля 2016, 13:51 | Сообщение # 10
Project SoRDeLKa
Сейчас нет на сайте
Само нажатие на кнопку ловить в mouserelesed можно, 1 раз выполняется.

В луа функции - это переменные(хотя не суть). Ты можешь задать кнопке переменную func и указать в ней нужную тебе функцию в конструкторе, а затем при нажатии выполнять func().

Как-то так:
Код
move_x = function (a) a.x = a.x + 10 end

oa = object_a:new(100, 100, move_x)

function object_a:new(x, y, f)
local t = {}
t.x = x or 100
t.y = y or 100
t.Hover = false
t.f = f
return setmetatable(t,{__index = self})
end

function object_a:click()
if self.Hover then self.f(self) end
end





Сообщение отредактировал LetsOffBrains - Понедельник, 01 Февраля 2016, 13:51
sfabrikanДата: Понедельник, 01 Февраля 2016, 14:11 | Сообщение # 11
БЕЗУМЕЦ!!!
Сейчас нет на сайте
LetsOffBrains, извините, но я хочу придраться! У nil не может быть ключей!

Это я

Сообщение отредактировал sfabrikan - Понедельник, 01 Февраля 2016, 14:13
burlachenkoДата: Вторник, 02 Февраля 2016, 20:44 | Сообщение # 12
постоянный участник
Сейчас нет на сайте
Спасибо за ответ LetsOffBrains, но я не понял где на него вопрос), но всё равно за внимание и потраченное время спасибо.

MaximTG
Snake174Дата: Четверг, 14 Апреля 2016, 11:06 | Сообщение # 13
участник
Сейчас нет на сайте
Обновлённая кнопка. Вдруг кому-нибудь пригодится.

Код

local Button = {}

function Button:new(o)
  local t = {}
  t.callbacks = {}
  t.pos = Vector( 0, 0 )
  t.size = Vector( 0, 0 )
  t.img = nil
  t.imgH = nil
  t.data = {}
  t.isHover = false
  t.triggerInOut = false
  t.triggerClick = false

  if o.pos ~= nil then
    t.pos = o.pos
  end

  if o.size ~= nil then
    t.size = o.size
  end

  if o.img ~= nil then
    t.img = love.graphics.newImage( o.img )
    local data = t.img:getData()
    data:mapPixel(
      function( x, y, r, g, b, a )
        if a == 255 then
          t.data[ tostring(x) .. "-" .. tostring(y) ] = true
        end

        return r, g, b, a
      end
    )
    data = nil
  end

  if o.imgH ~= nil then
    t.imgH = love.graphics.newImage( o.imgH )
  end

  return setmetatable( t, { __index = self } )
end

function Button:draw()
  local img = self.img

  if self.isHover then
    img = self.imgH
  end

  love.graphics.draw(
    img,
    self.pos.x,
    self.pos.y,
    0,
    1,
    1
  )
end

function Button:update( dt )
  local mx, my = Input.mousePos().x - self.pos.x, Input.mousePos().y - self.pos.y

  if self.data[ tostring( mx ) .. "-" .. tostring( my ) ] then
    self.isHover = true
  else
    self.isHover = false
  end

  if self.isHover and not self.triggerClick and Input.mouseDown(1) then
    self.triggerClick = true

    if self.callbacks["click"] then
      (self.callbacks["click"])()
    end
  elseif self.isHover and self.triggerClick and Input.mouseUp(1) then
    self.triggerClick = false
  end

  if self.isHover and not self.triggerInOut then
    self.triggerInOut = true

    if self.callbacks["mousein"] then
      (self.callbacks["mousein"])()
    end
  elseif not self.isHover and self.triggerInOut then
    self.triggerInOut = false

    if self.callbacks["mouseout"] then
      (self.callbacks["mouseout"])()
    end
  end
end

function Button:click(f)
  self.callbacks["click"] = f
end

function Button:mouseIn(f)
  self.callbacks["mousein"] = f
end

function Button:mouseOut(f)
  self.callbacks["mouseout"] = f
end

return Button


Не следует обманывать инспектора
Pipmak Assistant
Love2D Exporter
Love2D-Helpers
Old Consoles Games
burlachenkoДата: Среда, 20 Апреля 2016, 20:48 | Сообщение # 14
постоянный участник
Сейчас нет на сайте
Спасибо Snake174

MaximTG
  • Страница 1 из 1
  • 1
Поиск:

Все права сохранены. GcUp.ru © 2008-2024 Рейтинг