local mainWindow = GUI:Win_Create("MenuWindow", 0, 0, 0, 0, false, false, true, false, false, false, 1)
-- 一级菜单配置
local primaryMenus = {
{x = 50, y = 300, width = 100, height = 40, text = "菜单1"},
{x = 50, y = 250, width = 100, height = 40, t
🤖 回答引擎: 前端Lua |
🕒 时间: 2026-02-27 01:28:03 |
👁️ 阅读: 21
我来帮你修改这个二级菜单系统,让一级菜单和二级菜单在同一列,并且其他一级菜单会跟着有动画效果。
```lua
local mainWindow = GUI:Win_Create("MenuWindow", 0, 0, 0, 0, false, false, true, false, false, false, 1)
-- 一级菜单配置(调整位置,留出二级菜单空间)
local primaryMenus = {
{x = 50, y = 400, width = 100, height = 40, text = "菜单1"},
{x = 50, y = 350, width = 100, height = 40, text = "菜单2"},
{x = 50, y = 300, width = 100, height = 40, text = "菜单3"},
{x = 50, y = 250, width = 100, height = 40, text = "菜单4"},
{x = 50, y = 200, width = 100, height = 40, text = "菜单5"}
}
-- 二级菜单配置(每个一级菜单对应3个二级菜单)
local secondaryMenus = {
-- 菜单1的二级菜单
{
{x = 50, y = 360, width = 100, height = 30, text = "子项1-1"},
{x = 50, y = 330, width = 100, height = 30, text = "子项1-2"},
{x = 50, y = 300, width = 100, height = 30, text = "子项1-3"}
},
-- 菜单2的二级菜单
{
{x = 50, y = 310, width = 100, height = 30, text = "子项2-1"},
{x = 50, y = 280, width = 100, height = 30, text = "子项2-2"},
{x = 50, y = 250, width = 100, height = 30, text = "子项2-3"}
},
-- 菜单3的二级菜单
{
{x = 50, y = 260, width = 100, height = 30, text = "子项3-1"},
{x = 50, y = 230, width = 100, height = 30, text = "子项3-2"},
{x = 50, y = 200, width = 100, height = 30, text = "子项3-3"}
},
-- 菜单4的二级菜单
{
{x = 50, y = 210, width = 100, height = 30, text = "子项4-1"},
{x = 50, y = 180, width = 100, height = 30, text = "子项4-2"},
{x = 50, y = 150, width = 100, height = 30, text = "子项4-3"}
},
-- 菜单5的二级菜单
{
{x = 50, y = 160, width = 100, height = 30, text = "子项5-1"},
{x = 50, y = 130, width = 100, height = 30, text = "子项5-2"},
{x = 50, y = 100, width = 100, height = 30, text = "子项5-3"}
}
}
-- 存储所有创建的控件
local primaryButtons = {}
local secondaryPanels = {}
local menuPositions = {} -- 存储每个菜单的位置信息
-- 创建一级菜单
for i, config in ipairs(primaryMenus) do
local btn = GUI:Button_Create(mainWindow, "primary_"..i, config.x, config.y, "res/public/1900000612.png")
GUI:Button_setTitleText(btn, config.text)
GUI:setContentSize(btn, config.width, config.height)
-- 存储菜单位置信息
menuPositions[i] = {
primaryY = config.y,
secondaryY = {}
}
for j, secConfig in ipairs(secondaryMenus[i]) do
menuPositions[i].secondaryY[j] = secConfig.y
end
-- 创建二级菜单容器
local secondaryContainer = GUI:Layout_Create(mainWindow, "secondary_"..i, 0, 0, 0, 0, false)
GUI:setVisible(secondaryContainer, false)
-- 创建二级菜单项
local secondaryItems = {}
for j, secConfig in ipairs(secondaryMenus[i]) do
local item = GUI:Button_Create(secondaryContainer, "item_"..i.."_"..j, secConfig.x, secConfig.y, "res/public/1900000612.png")
GUI:Button_setTitleText(item, secConfig.text)
GUI:setContentSize(item, secConfig.width, secConfig.height)
GUI:setVisible(item, false)
GUI:setOpacity(item, 0) -- 初始透明
secondaryItems[j] = item
end
secondaryPanels[i] = {
container = secondaryContainer,
items = secondaryItems,
isExpanded = false,
itemCount = #secondaryMenus[i]
}
-- 一级菜单点击事件
GUI:addOnClickEvent(btn, function()
toggleSecondaryMenu(i)
end)
primaryButtons[i] = btn
end
-- 当前展开的菜单索引
local currentExpandedMenu = nil
-- 计算菜单移动距离
function getMenuMoveDistance(menuIndex)
local panel = secondaryPanels[menuIndex]
return panel.itemCount * 35 -- 每个二级菜单项占35像素高度
end
-- 移动其他菜单(展开时)
function moveOtherMenusDown(startIndex, distance)
for i = startIndex + 1, #primaryButtons do
local btn = primaryButtons[i]
local currentPos = GUI:getPosition(btn)
local targetY = currentPos.y - distance
-- 移动一级菜单
GUI:runAction(btn, GUI:ActionMoveTo(0.3, currentPos.x, targetY))
-- 如果有二级菜单,也移动
local panel = secondaryPanels[i]
if panel and panel.isExpanded then
for _, item in ipairs(panel.items) do
local itemPos = GUI:getPosition(item)
GUI:runAction(item, GUI:ActionMoveTo(0.3, itemPos.x, itemPos.y - distance))
end
end
end
end
-- 移动其他菜单(收回时)
function moveOtherMenusUp(startIndex, distance)
for i = startIndex + 1, #primaryButtons do
local btn = primaryButtons[i]
local currentPos = GUI:getPosition(btn)
local targetY = currentPos.y + distance
-- 移动一级菜单
GUI:runAction(btn, GUI:ActionMoveTo(0.3, currentPos.x, targetY))
-- 如果有二级菜单,也移动
local panel = secondaryPanels[i]
if panel and panel.isExpanded then
for _, item in ipairs(panel.items) do
local itemPos = GUI:getPosition(item)
GUI:runAction(item, GUI:ActionMoveTo(0.3, itemPos.x, itemPos.y + distance))
end
end
end
end
-- 切换二级菜单显示/隐藏
function toggleSecondaryMenu(menuIndex)
local panel = secondaryPanels[menuIndex]
if panel.isExpanded then
-- 收回动画
collapseMenu(menuIndex)
else
-- 如果其他菜单展开,先收回
if currentExpandedMenu and currentExpandedMenu ~= menuIndex then
collapseMenu(currentExpandedMenu)
end
-- 展开动画
expandMenu(menuIndex)
currentExpandedMenu = menuIndex
end
end
-- 展开菜单动画
function expandMenu(menuIndex)
local panel = secondaryPanels[menuIndex]
local moveDistance = getMenuMoveDistance(menuIndex)
-- 先移动下面的其他菜单
moveOtherMenusDown(menuIndex, moveDistance)
-- 显示容器
GUI:setVisible(panel.container, true)
-- 展开二级菜单项(从下往上依次显示)
for i = #panel.items, 1, -1 do
local item = panel.items[i]
GUI:setVisible(item, true)
-- 设置初始位置(在下方)
local targetY = menuPositions[menuIndex].secondaryY[i]
local initialY = targetY + 20 -- 从下方20像素开始
GUI:setPosition(item, menuPositions[menuIndex].primaryY, initialY)
GUI:setOpacity(item, 0)
-- 延迟显示,创建阶梯效果
local delay = (i - 1) * 0.1
-- 丝滑动画:向上移动 + 淡入
local moveAction = GUI:ActionMoveTo(0.3, menuPositions[menuIndex].primaryY, targetY)
local fadeAction = GUI:ActionFadeTo(0.3, 255)
local sequence = GUI:ActionSequence(
GUI:DelayTime(delay),
GUI:ActionSpawn(moveAction, fadeAction)
)
GUI:runAction(item, sequence)
end
panel.isExpanded = true
end
-- 收回菜单动画
function collapseMenu(menuIndex)
local panel = secondaryPanels[menuIndex]
local moveDistance = getMenuMoveDistance(menuIndex)
-- 先移动下面的其他菜单
moveOtherMenusUp(menuIndex, moveDistance)
-- 收回二级菜单项(从上往下依次收回)
for i = 1, #panel.items do
local item = panel.items[i]
-- 延迟收回,创建阶梯效果
local delay = (i - 1) * 0.1
local currentPos = GUI:getPosition(item)
-- 丝滑动画:向下移动 + 淡出
local moveAction = GUI:ActionMoveTo(0.3, currentPos.x, currentPos.y + 20)
local fadeAction = GUI:ActionFadeTo(0.3, 0)
local sequence = GUI:ActionSequence(
GUI:DelayTime(delay),
GUI:ActionSpawn(moveAction, fadeAction),
GUI:CallFunc(function()
GUI:setVisible(item, false)
GUI:setOpacity(item, 255) -- 重置透明度
end)
)
GUI:runAction(item, sequence)
end
-- 延迟隐藏容器
SL:ScheduleOnce(function()
if panel.isExpanded then
GUI:setVisible(panel.container, false)
panel.isExpanded = false
if currentExpandedMenu == menuIndex then
currentExpandedMenu = nil
end
end
end, 0.35)
end
-- 添加背景
local bg = GUI:Image_Create(mainWindow, "bg", 0, 0, "res/public_win32/1900000610.png")
GUI:setLocalZOrder(bg, -1)
SL:print("垂直二级菜单系统创建完成!点击一级菜单可以展开/收回二级菜单,其他菜单会跟着移动")
```
**修改说明:**
1. **垂直布局**:二级菜单现在和一级菜单在同一列(x坐标相同),形成垂直排列
2. **联动动画**:
- 展开时:下面的所有菜单会向下移动,为二级菜单腾出空间
- 收回时:下面的菜单会向上移动,恢复原位
3. **阶梯效果**:
- 二级菜单项从下往上依次展开
- 收回时从上往下依次收回
- 每个项有0.1秒的延迟,形成流畅的动画序列
4. **视觉效果**:
- 淡入淡出 + 垂直移动动画
- 保持所有菜单在同一垂直线上
- 背景使用指定的图片
现在点击任意一级菜单,它的二级菜单会在下方展开,同时下面的其他菜单会自动下移,收回时又会自动上移,形成很流畅的垂直菜单系统!
← 返回问答库