Добавлен jasonrus96
Вот небольшой кусок кода с кнопкой и функцией клика по кнопке с покупкой предмета, как? можно сделать массив примерно на 15 предметов чтоб не создавать функцию клика для каждой кнопки c выдачей заранее подготовленного предмета.
private function click takes nothing returns nothing
if GetPlayerState(GetOwningPlayer(udg_UnitBody[GetConvertedPlayerId(GetTriggerPlayer())]), PLAYER_STATE_RESOURCE_GOLD) >= 80 then
call SetPlayerStateBJ( GetOwningPlayer(udg_UnitBody[GetConvertedPlayerId(GetTriggerPlayer())]), PLAYER_STATE_RESOURCE_GOLD, ( GetPlayerState(GetOwningPlayer(udg_UnitBody[GetConvertedPlayerId(GetTriggerPlayer())]), PLAYER_STATE_RESOURCE_GOLD) - 80 ) )
call UnitAddItemByIdSwapped(udg_Items[1],udg_UnitBody[GetConvertedPlayerId(GetTriggerPlayer())] )
else
call DisplayTextToForce( GetForceOfPlayer(GetOwningPlayer(udg_UnitBody[GetConvertedPlayerId(GetTriggerPlayer())])), "Нету деняг!!" )
endif
endfunction
private function initSs takes integer id returns nothing
local trigger Click = CreateTrigger()
local trigger Click2 = CreateTrigger()
local player p = GetOwningPlayer(GetTriggerUnit())
set gameUIS = BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0)
set butS[1] = BlzCreateSimpleFrame("Pistol", gameUIS, 0)
call BlzFrameSetAbsPoint(butS[1], FRAMEPOINT_CENTER, 0.1, 0.5)
call BlzTriggerRegisterFrameEvent(Click, butS[1], FRAMEEVENT_CONTROL_CLICK)
call TriggerAddAction(Click, function click)
set text1[1] = BlzCreateFrame("PistolText1", gameUIS, 0, 0)
call BlzFrameSetAbsPoint(text1[1], FRAMEPOINT_CENTER, 0.1, 0.47)
set text2[1] = BlzCreateFrame("PistolText2", gameUIS, 0, 0)
call BlzFrameSetAbsPoint(text2[1], FRAMEPOINT_CENTER, 0.1, 0.46)
call BlzFrameSetVisible(butS[1], false)
call BlzFrameSetVisible(text1[1], false)
call BlzFrameSetVisible(text2[1], false)
if GetLocalPlayer() == p then
call BlzFrameSetVisible(butS[1], false)
call BlzFrameSetVisible(text1[1], false)
call BlzFrameSetVisible(text2[1], false)
endif
set Click = null
set Click2 = null
set p = null
endfunction
Принятый ответ
Сразу хочу сказать, что события фреймов в рефе багованные, после патча 1.33 вдвойне багованные, здесь каждый выкручивается как может, но без компромиссов тут не обойтись, как и при любой разработке на рефе чего-то интереснее базовой милишки. Вроде в этой карте автор что-то смог толково сделать, рекомендую посмотреть магазин/инвентарь там. Ещё есть вариант перекатиться на южапи, отсутствие проблем там никто вроде не гарантирует, но там есть перспективы в развитии апи, в отличие от рефа, где разрабы заняты фиксом нежити.
По-моему, событие клика сейчас не особо жалуют, вроде делают через Enter и Leave, но я особо не в курсе.
Я пробую магазин делать я заранее сделал переменные для нужных мне предметов накидал код и заметил что под каждую кнопку нужно функцию клика делать и прикинул что код станет гигантским из за этого.
Нам нужен цикл. Создать какую-то базовую функцию для создания кнопки, вызвать её нужное количество раз, и у нас будет нужное количество кнопок.
Не обязательно на каждую кнопку делать свой триггер, и свою функцию обработки события, это можно сделать в одном триггере, и в одной функции, всё что нужно — это повесить на каждую кнопку своё событие. Естественно, событие можно добавить прямо в этом же цикле, где мы создаём кнопки. В триггере останется лишь получить триггернувшийся фрейм, и узнать связанный с ним предмет, который, естественно, нужно связать заранее, например в массиве.
Не обязательно на каждую кнопку делать свой триггер, и свою функцию обработки события, это можно сделать в одном триггере, и в одной функции, всё что нужно — это повесить на каждую кнопку своё событие. Естественно, событие можно добавить прямо в этом же цикле, где мы создаём кнопки. В триггере останется лишь получить триггернувшийся фрейм, и узнать связанный с ним предмет, который, естественно, нужно связать заранее, например в массиве.
Набросаю пример на луа, ибо не умею в джасс. Ну это так, база, в мультиплеерную карту как готовое решение это не пойдёт, да и в синглплеерную тоже из-за сломанных в рефе сейвов, чивоуштам. На каждую кнопку создал четыре фрейма. Для отслеживания клика используем тип "BUTTON", его прикроем сверху типом "BACKDROP". Ну и два текстовых фрейма для тултипа и стоимости.
код
-- Список доступных для продажи предметов, 15 штук
ItemDB = {'afac', 'spsh', 'ajen', 'bgst', 'belv', 'bspd', 'cnob', 'ratc','rat6','rat9', 'clfm', 'clsd', 'crys', 'dsum', 'rst1'}
FrameToItem = {} -- в будущем заполним эту таблицу, связав фреймы с кодами итемов
Buttons = {} -- в будущем заполним эту таблицу, связав фреймы со стоимостью итемов
CancelShopFrame = nil -- тут будет кнопка выхода из магазина
function Init()
hero = CreateUnit(GetLocalPlayer(), FourCC('Hpal'), 0, 0, 0) --герой, которому будем выдавать предметы
SetPlayerState(GetLocalPlayer(), PLAYER_STATE_RESOURCE_GOLD, 30000) --накинем голды
initShop() --создадим магазин
end
function initShop()
local size = 0.03 --размер кнопки
local startX, y = 0.5, 0.5 --начальная позиция
local rows, columns = 4, 4 --количество рядов и столбов
local deltaX, deltaY = 0.05, -0.05 --расстояние между кнопками
local counter = 1 --счётчик предметов
local triggor = CreateTrigger()
for r = 1, rows do --ряды
y = y + deltaY
for c = 1, columns do --столбцы
local x = startX + deltaX * (c - 1)
if counter >= 16 then -- 16-ую позицию использует для кнопки выхода
CancelShopFrame = createButton(x, y, size, "ReplaceableTextures\\CommandButtons\\btncancel", "Exit shop", "")
BlzTriggerRegisterFrameEvent(triggor, CancelShopFrame, FRAMEEVENT_CONTROL_CLICK)
break
end
local item = ItemDB[counter] -- получили равкод итема
local text, path = getItemInfo(item)
local cost = math.random(1, 7000) -- в моём примере цена будет рандомная
local button = createButton(x, y, size, path, text, ""..cost)
BlzTriggerRegisterFrameEvent(triggor, button, FRAMEEVENT_CONTROL_CLICK)
FrameToItem[button] = item --записали пару "фрейм = равкод предмета"
Buttons[button] = cost --записали пару "фрейм = стоимость предмета"
counter = counter + 1
end
end
TriggerAddCondition(triggor, Condition(clickToShopFrame))
end
function getItemInfo(id) --вернёт иконку и тултип предмета из РО
--увы, это можно сделать только создав экземпляр предмета, в идеале эти данные ещё бы записать куда, а можно и заранее написать прямо в коде
local item = CreateItem(FourCC(id), 10000, 10000)
local text = BlzGetItemTooltip(item)
local path = BlzGetItemIconPath(item)
RemoveItem(item)
return text, path
end
function clickToShopFrame() -- здесь обрабатываем событие из триггора
local frame = BlzGetTriggerFrame()
resetFrame(frame) --клик по фрейму блокирует события клавы, так что такой костылёк может пригодиться, но не обязательно
if frame == CancelShopFrame then
for k, v in pairs(Buttons) do
BlzFrameSetVisible(k, false)
end
BlzFrameSetVisible(frame, false)
return
end
sellItem(frame)
end
function resetFrame(fr)
BlzFrameSetEnable(fr, false)
BlzFrameSetEnable(fr, true)
end
function sellItem(frame)
-- Здесь мы проверяем голду и делаем что-нибудь с предметом
local gold = PLAYER_STATE_RESOURCE_GOLD
local currentGold = GetPlayerState(GetLocalPlayer(), gold)
local cost = Buttons[frame] --получили цену предмета
if cost <= currentGold then
SetPlayerState(GetLocalPlayer(), gold, GetPlayerState(GetLocalPlayer(), gold) - cost)
local item = CreateItem(FourCC(FrameToItem[frame]), 10000, 10000)
if not UnitAddItem(hero, item) then -- если в инвентаре нет места, то создаём рядом
SetItemPosition(item, GetUnitX(hero), GetUnitY(hero))
end
outputItemInfo(item, cost)
return
end
print "Not enough gold!"
end
function outputItemInfo(item, cost)
print("Received a |c0000FF80"..GetItemName(item).. "|r worth |c00FFFF00"..cost.."|r gold")
end
function createButton(x, y, size, iconPath, tooltipText, cost)
-- Достаточно одного фрейма-кнопки, но для красоты и функциональности можно добавить всё что угодно
-- В данном случае создаёт кнопку, иконку-бекдроп, тултип и текст фрейм для отображения стоимости
local button = BlzCreateFrameByType("BUTTON", "", BlzGetOriginFrame(ORIGIN_FRAME_GAME_UI, 0), "ScoreScreenTabButtonTemplate", 0)
local icon = BlzCreateFrameByType("BACKDROP", "", button, "", 0)
BlzFrameSetAllPoints(icon, button) --икнока будет полностью закрывать кнопку
BlzFrameSetAbsPoint(button, FRAMEPOINT_CENTER, x, y)
BlzFrameSetSize(button, size, size)
BlzFrameSetTexture(icon, iconPath, 0, false)
local tooltip = BlzCreateFrameByType("TEXT", "", button, "", 0)
BlzFrameSetTooltip(button, tooltip)
BlzFrameSetPoint(tooltip, FRAMEPOINT_BOTTOMLEFT, button, FRAMEPOINT_TOP, 0, 0)
BlzFrameSetEnable(tooltip, false)
BlzFrameSetText(tooltip, "|c00FFFF00"..tooltipText.."|r")
local costFrame = BlzCreateFrameByType("TEXT", "", button, "", 0)
BlzFrameSetPoint(costFrame, FRAMEPOINT_TOPLEFT, button, FRAMEPOINT_BOTTOMLEFT, 0, 0)
BlzFrameSetPoint(costFrame, FRAMEPOINT_BOTTOMRIGHT, button, FRAMEPOINT_BOTTOMRIGHT, 0, -0.01)
BlzFrameSetEnable(costFrame, false)
BlzFrameSetText(costFrame, cost)
BlzFrameSetTextAlignment(costFrame, TEXT_JUSTIFY_CENTER, TEXT_JUSTIFY_MIDDLE)
return button, icon, tooltip, costFrame
end
На джассе примерно то же самое, только хуже.
Результат на видео и в карте.
Загруженные файлы
`
ОЖИДАНИЕ РЕКЛАМЫ...
Чтобы оставить комментарий, пожалуйста, войдите на сайт.
Отредактирован MpW
Отредактирован MpW
Отредактирован Makeba
Не обязательно на каждую кнопку делать свой триггер, и свою функцию обработки события, это можно сделать в одном триггере, и в одной функции, всё что нужно — это повесить на каждую кнопку своё событие. Естественно, событие можно добавить прямо в этом же цикле, где мы создаём кнопки. В триггере останется лишь получить триггернувшийся фрейм, и узнать связанный с ним предмет, который, естественно, нужно связать заранее, например в массиве.