Конструктор для кнопки (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
|
|
| |
|