功能需求:
选兵界面包含的功能:
(1) 玩家拥有的出征队列以列表的形式展示.
(2)选中一支出征队列,显示队列英雄的属性头像模型等, 显示士兵列表,士兵有滑动条可以滑动选择上阵数量.
(3)根据出征队列预先设置的上阵士兵情况,提供自动补兵功能.
(4)退出编辑界面判断提示自动保存出征队列数据功能.
(5)动态刷新战斗力等属性.
设计思路: 把复杂功能拆分成几块,每块既独立又相互联系.
入口UI:
FullPanel_FleetGroupEditor
模块:
英雄模块:FlagModule (英雄相关功能)
滑动模块:SlideModule (士兵相关功能)
出征队列列表模块:QueueModule (出征队列列表功能)
其他元素模块:OtherModule (其他动态刷新的属性功能)
用lua实现, 具体代码如下:(只写了框架, 相当于写了骨架, 细节都是血肉,在对应脚本里面增加就行)
require "Global"
---@class FullPanel_FleetGroupEditor
local class = class(PanelBase)
----------------------------------------------------- 舰队编组入口
--[[
LuaTable queueModule
LuaTable flagModule
LuaTable slideModule
LuaTable otherModule
]]--
----------------------------------------------------- 内部方法
function class:CreateOrRefreshFlagModule(data)
self.flagModule:SetData(data)
end
function class:CreateOrRefreshSlideModule(data)
self.slideModule:SetData(data)
end
function class:CreateOrRefreshOtherModule(data)
self.otherModule:SetData(data)
end
function class:CreateQueueModule(callback, index)
self.queueModule:SetData(callback, index)
end
--[[
舰队编组的数据
shipList = {gid1 = 100, gid2 = 200..}
flagGid = gid
]]--
function class:InitUI()
local callback = function(data)
self:CreateOrRefreshFlagModule(data)
self:CreateOrRefreshSlideModule(data)
--self:CreateOrRefreshOtherModule(data)
end
self:CreateQueueModule(callback, self.index)
end
function class:Start()
self.index = self.metaData or 1
logYellow('self.index: '.. tostring(self.index))
self:InitUI()
end
----------------------------------------------------- 外部方法
return class
require "Global"
---@class FlagModule
local class = class()
----------------------------------------------------- 旗舰模块
--[[
UITexture texture
UISprite icon
UILabel name
UILabel level
UISlider progress
LuaTable skillTable
]]--
----------------------------------------------------- 内部方法
function class:RefreshUI()
local gid = self.data.flagGid
local texName = 'flagship_tex_' .. gid .. '.png'
local tex = ResManager.Instance:GetTexture(texName)
self.texture.mainTexture = tex
UpdateSpriteByItemType(gid, self.icon)
self.name.text = MultiLanguage:GetGIDName(gid)
self.level.text = 'III'
self.progress.value = 0.5
self.skillTable:SetData(self.data)
end
----------------------------------------------------- 外部方法
function class:SetData(data)
self.data = data
self:RefreshUI()
end
function class:OnReplaceFlag()
end
function class:OnDetails()
end
return class
require "Global"
---@class FlagModuleSkill
local class = class()
----------------------------------------------------- 旗舰技能
--[[
UIGrid grid
GameObject itemObj
]]--
----------------------------------------------------- 内部方法
function class:RefreshUI()
for i = 1, 5 do
local item = CreateLuaTableItem(self.grid.gameObject, self.itemObj.gameObject)
item:SetData()
end
end
----------------------------------------------------- 外部方法
function class:SetData(data)
self.data = data
self:RefreshUI()
end
return class
require "Global"
---@class FlagModuleSkillItem
local class = class()
----------------------------------------------------- 旗舰技能item
--[[
UISprite icon -- 旗舰技能icon
UISprite unlock -- 未解锁
]]--
----------------------------------------------------- 内部方法
--[[
skillId int
unlock boolean 解锁
level 等级
isEquip 装备/技能
]]--
function class:RefreshUI()
local conf
if self.isEquip then
conf = ConfigsManager:GetWeaponConfig(self.gid, self.level)
else
conf = ConfigsManager:GetFlagShipSkillConfigs():GetConfig(self.gid, self.level)
end
UpdateUISprite(conf.icon, self.icon)
SetObjActive(self.unlock, not self.unlock)
end
----------------------------------------------------- 外部方法
function class:SetData(gid, level, unlock, isEquip)
self.gid = gid
self.level = level
self.unlock = unlock
self.isEquip = isEquip
self:RefreshUI()
end
function class:OnClick()
local position = item.transform:TransformPoint(300, 350, 0)
ViewManager:PushPanel("FlagshipSKillInfoMessageBox.prefab", {self.gid, self.level, position})
end
return class
require "Global"
---@class OtherModule
local class = class()
----------------------------------------------------- 其他模块
--[[
UILabel fleetName
UILabel label1
UILabel label2
UILabel label3
UILabel label4
]]--
----------------------------------------------------- 内部方法
function class:CalculateLabel1()
end
function class:CalculateLabel2()
end
function class:CalculateLabel3()
end
function class:CalculateLabel4()
end
function class:RefreshUI()
self.fleetName.text = ''
self.label1.text = self:CalculateLabel1()
self.label2.text = self:CalculateLabel2()
self.label3.text = self:CalculateLabel3()
self.label4.text = self:CalculateLabel4()
end
----------------------------------------------------- 外部方法
function class:SetData(data)
self.data = data
self:RefreshUI()
end
function class:OnModifyName()
end
function class:OnRecord()
end
function class:OnAutoFill()
end
function class:OnSave()
end
function class:OnReset()
end
return class
require "Global"
---@class QueueModule
local class = class()
----------------------------------------------------- 队列模块
--[[
UIGrid grid
GameObject itemObj
]]--
----------------------------------------------------- 内部方法
function class:Callback(data, item)
if self.currentItem then
self.currentItem:SetSelected(false)
end
if self.callback then
self.callback(data)
end
self.currentItem = item
end
function class:CreateItem(data, selected)
local callback = function(data, item)
self:Callback(data, item)
end
local item = CreateLuaTableItem(self.grid.gameObject, self.itemObj.gameObject)
item:SetData(data, selected, callback)
if selected then
self:Callback(data, item)
end
end
function class:Create()
for index = 1, 8 do
--local data = PresetTroopDatas:GetTroopData(index)
local data = {shipList = {}, flagGid = 10020001}
self:CreateItem(data, self.index == index)
end
end
----------------------------------------------------- 外部方法
--[[
callback: 选择item回调
]]--
function class:SetData(callback, index)
self.callback = callback
self.index = index
self:Create()
end
return class
require "Global"
---@class QueueModuleItem
local class = class()
----------------------------------------------------- 出征舰队选择
--[[
GameObject selectEff -- 选中效果
UISprite icon -- 舰队logo
UISprite action -- 行军行为
UISprite selected -- 选择效果
UISprite fleetState -- 舰队状态
]]--
----------------------------------------------------- 内部方法
function class:RefreshUI()
self:SetSelected(self.isSelect)
end
----------------------------------------------------- 外部方法
--[[
callback 点击回调
]]--
function class:SetData(data, isSelect, callback)
self.data = data
self.isSelect = isSelect
self.callback = callback
self:RefreshUI()
end
function class:OnClick()
self:SetSelected(true)
if self.callback then
self.callback(self.data, self)
end
end
function class:SetSelected(selected)
SetObjActive(self.selected, selected)
end
return class
require "Global"
---@class SlideComponent
local class = class()
----------------------------------------------------- 滑动组件
--[[
UILabel CountText -- 程序设置数量
UIInput CountInput -- 玩家输入数量
UILabel totalLabel -- 总数
]]--
----------------------------------------------------- 内部方法
function class:InitComponent()
self.slider = self.gameObject:GetComponent(UISlider)
if self.CountInput then
self.CountInput.keyboardType = UIInput.KeyboardType.NumberPad
end
self.totalLabel.text = self.maxNum
end
----------------------------------------------------- 外部方法
function class:Init(maxNum, callback)
self.maxNum = maxNum
self.callback = callback
self:InitComponent()
end
-- interface --
function class:SetSliderEnabled(enabled)
local boxs = self.gameObject:GetComponentsInChildren(BoxCollider)
for i = 1, #boxs do
SetButtonEnabled(boxs[i].gameObject, enabled)
end
end
function class:GetCount()
return Int(self.slider.value * self.maxNum + 0.5)
end
function class:GetTotalCount()
return self.maxNum
end
function class:SetPercent(percent)
self.slider.value = percent / 100
if self.callback then
self.callback(percent)
end
end
function class:SetCount(current)
if self.maxNum == 0 then
self.slider.value = 1
else
self.slider.value = current / self.maxNum
end
end
function class:OnSubBtnClick()
self.slider.value = self.slider.value - 1/self.maxNum
end
function class:OnPlusBtnClick()
self.slider.value = self.slider.value + 1/self.maxNum
end
function class:OnValueChange()
if not self.maxNum then return end
local newvalue = Int(self.slider.value * self.maxNum + 0.5)
if self.CountInput then
self.CountInput.value = newvalue
end
if self.CountText then
self.CountText.text = newvalue
end
if self.callback then
if self.dontCallbackOnTime then
self.dontCallbackOnTime = nil
else
self.callback(newvalue, self.luaTable)
end
end
end
function class:OnSubmitValue()
local inputValue = 0
if self.CountInput then
inputValue = self.CountInput.value
end
if inputValue == '' or inputValue == '0' then
inputValue = 0
else
inputValue = (tonumber(inputValue) > self.maxNum and self.maxNum) or tonumber(inputValue)
end
if self.CountInput then
self.CountInput.value = inputValue
end
if self.maxNum == 0 then
self.slider.value = 0
else
self.slider.value = inputValue / self.maxNum
end
end
return class
require "Global"
---@class SlideModule
local class = class()
----------------------------------------------------- 滑动模块
--[[
UIGrid grid
GameObject itemObj
]]--
----------------------------------------------------- 内部方法
function class:Sort()
end
--[[
inUnm: 上阵的数量
allNum: 拥有总数 (未上阵的 + 上阵的)
]]--
function class:GetTroopList()
local data = {gid = 10010001, inNum = 10, allNum = 100}
local data2 = {gid = 10010001, inNum = 20, allNum = 300}
local data3 = {gid = 10010001, inNum = 30, allNum = 500}
local list = {data, data2, data3}
return list
end
function class:GetItem(index, gid, inNum, allNum)
if not self.list then self.list = {} end
local item = self.list[index]
if not item then
item = CreateLuaTableItem(self.grid.gameObject, self.itemObj.gameObject)
self.list[#self.list + 1] = item
end
item:SetData(gid, inNum, allNum)
end
function class:CreateOrRefresh()
local list = self:GetTroopList()
for index = 1, #list do
local gid = list[index].gid
local inNum = list[index].inNum
local allNum = list[index].allNum
self:GetItem(index, gid, inNum, allNum)
end
end
----------------------------------------------------- 外部方法
function class:SetData(data, callback)
self.data = data
self.callback = callback
self:CreateOrRefresh()
end
return class
require "Global"
---@class SlideModuleItem
local class = class()
----------------------------------------------------- 滑动item
--[[
LuaTable slideComponent -- 滑动组件
UISprite icon -- 舰船图标
UILabel level -- 舰船等级
UILabel name -- 舰船名称
]]--
----------------------------------------------------- 内部方法
----------------------------------------------------- 外部方法
function class:SetData(gid, inNum, allNum)
local callback = function()
end
self.slideComponent:Init(allNum, callback)
self.slideComponent:SetCount(inNum)
end
return class