铁血丹心

 找回密码
 我要成为铁血侠客
搜索
查看: 6780|回复: 10

第九讲 菜单选项

[复制链接]
发表于 2011-10-9 12:33 | 显示全部楼层 |阅读模式
本帖最后由 蓝烟清 于 2011-10-10 00:00 编辑


第九讲 菜单选项


9.1    介绍与遗留问题
        菜单选项是为了让玩家更直观的选择将要做的操作,最常见的按ESC键,弹出的就是一个菜单选项,还有战斗时的选择等。菜单选项有两种,一种是竖向的,另一个是横向。
        学习目标:掌握菜单选项的运用
        遗留问题:还有一种菜单选项,横向的,每个菜单项都有一个框,例如开始选系或者战斗中指令的确定和取消,应该是苍炎才有的。S大看到时不知是否可以提供

9.2    函数定义
        ShowMenu(menuItem,numItem,numShow,x1,y1,x2,y2,isBox,isEsc,size,color,selectColor);  --竖向菜单
        ShowMenu2(menuItem,numItem,numShow,x1,y1,x2,y2,isBox,isEsc,size,color,selectColor);   --横向菜单

9.3    具体的说明
        两个函数的参数是一模一样的,下面只拿竖向的菜单来做详细讲解。

9.3.1     ShowMenu
        ShowMenu(menuItem,numItem,numShow,x1,y1,x2,y2,isBox,isEsc,size,color,selectColor);  --竖向菜单
        参数说明:
  1. -- menuItem 表,每项保存一个子表,内容为一个菜单项的定义
  2.         --          菜单项定义为  {   ItemName,     菜单项名称字符串
  3.         --                          ItemFunction, 菜单调用函数,如果没有则为nil
  4.         --                          Visible       是否可见  0 不可见 1 可见, 2 可见,作为当前选择项。只能有一个为2,
  5.         --                                        多了则只取第一个为2的,没有则第一个菜单项为当前选择项。
  6.         --                                        在只显示部分菜单的情况下此值无效。
  7.         --                                        此值目前只用于是否菜单缺省显示否的情况
  8.         --                       }
  9.         --          菜单调用函数说明:         itemfunction(newmenu,id)
  10.         --
  11.         --       返回值
  12.         --              0 正常返回,继续菜单循环 1 调用函数要求退出菜单,不进行菜单循环
  13.         --
  14.         -- numItem      总菜单项个数
  15.         -- numShow      显示菜单项目,如果总菜单项很多,一屏显示不下,则可以定义此值
  16.         --                =0表示显示全部菜单项
  17.         
  18.         -- (x1,y1),(x2,y2)  菜单区域的左上角和右下角坐标,如果x2,y2=0,则根据字符串长度和显示菜单项自动计算x2,y2
  19.         -- isBox        是否绘制边框,0 不绘制,1 绘制。若绘制,则按照(x1,y1,x2,y2)的矩形绘制白色方框,并使方框内背景变暗
  20.         -- isEsc        Esc键是否起作用 0 不起作用,1起作用
  21.         -- Size         菜单项字体大小
  22.         -- color        正常菜单项颜色,均为RGB
  23.         -- selectColor  选中菜单项颜色,
  24.         --;
  25.         -- 返回值  0 Esc返回
  26.         --         >0 选中的菜单项(1表示第一项)
  27.         --         <0 选中的菜单项,调用函数要求退出父菜单,这个用于退出多层菜单
复制代码
9.3.2        ShowMenu2
        横向菜单与上面的参数定义是完全一样的,就不多说了。

9.4     实例
        参数的说明眼花缭乱,呵呵,其实我第一次看到的时候确实是这种感觉。下面配合实例进行讲解。

9.4.1     最简单的例子
        显示一个“确定”或“取消”的菜单选项,展示的是竖向,如果要变成横向只要把ShowMenu改成ShowMenu2就可以了。打开DIY.lua文件
第一步:
  1. --定义一个菜单列表
  2.         local menu={{"确定",nil,2},
  3.                     {"取消",nil,1}};
复制代码
第二步:
  1. --定义显示的位置,并显示菜单
  2.         local x = 50;     --菜单开始的x坐标
  3.         local y = 50;     --菜单开始的y坐标
  4.         local r = ShowMenu(menu,2,0,x,y,0,0,1,1,CC.DefaultFont,C_ORANGE, C_WHITE);
  5.         --这样一个简单完整的菜单就有了
复制代码
第三步:
  1. --判断选项
  2.         if r == 0 then
  3.                 Talk("你按了ESC键",0);
  4.         elseif r == 1 then
  5.                 Talk("你选择了 "..menu[r][1], 0);
  6.                 Talk("要不要做点什么事情",1);
  7.         elseif r == 2 then
  8.                 Talk("你选择了 "..menu[r][1], 0);
  9.         else
  10.                 Talk("菜单强制退出了!",0);
  11.         end
复制代码
9.4.2                带函数的菜单项
        以离开子场景和主角升级的功能为实例
        打开DIY.lua文件
        第一步:
  1. --定义三个函数
  2.         local function Leave_SubScene()  --离开子场景
  3.         if JY.SubScene > 0 then                --如果当前是在子场景下
  4.                 JY.Base["人X1"] = JY.Scene[JY.SubScene]["出口X1"];
  5.                 JY.Base["人Y1"] = JY.Scene[JY.SubScene]["出口Y1"];               
  6.         end
  7.         return 1;        --一定要返回1,不然菜单不会自动消失
  8. end

  9. local function My_Menu_ChuangSong()  --传送菜单
  10.         local menu={{"移到出口",Leave_SubScene,2}};
  11.         local x = 20 + 4*CC.DefaultFont + 3*CC.MenuBorderPixel;
  12.         local y = 20;
  13.         local r = ShowMenu(menu,1,0,x,y,0,0,1,1,CC.DefaultFont,C_ORANGE, C_WHITE);
  14.         if r == 0 then        --如果是按ESC,只退出这个菜单
  15.                 return 0;
  16.         end
  17.         return 1;
  18. end

  19. local function My_Menu_LevelUp() --主角升级菜单
  20.         if JY.Person[0]["等级"] < 30 then
  21.                 JY.Person[0]["经验"] = CC.Exp[JY.Person[0]["等级"]];
  22.                 War_AddPersonLVUP(0);
  23.                 QZXS("主角等级升到了"..JY.Person[0]["等级"]);
  24.         end
  25. end
复制代码
第二步:
  1. --定义菜单项
  2.         local menu={{"传送",My_Menu_ChuangSong,2},
  3.                                                 {"主角升级",My_Menu_LevelUp,1},
  4.                     {"关闭",nil,1},
  5.                     };
复制代码
第三步:
  1. --显示菜单
  2.         local num = table.getn(menu);
  3. local x = 20;
  4. local y = 20;

  5. ShowMenu(menu,num,0,x,y,0,0,1,1,CC.DefaultFont,C_ORANGE, C_WHITE);
复制代码
附上实例图:



9.5    结束语
        菜单选项不难,没有太多需要讲解的。比较重要的一点是菜单项函数的返回值,返回1时所有的菜单都会消失,返回0就只有当前的菜单选项会消失,而父菜单选项不会。第二个实例有这个的说明
        只要把前面的知识学好了,就可以利用菜单来实现很多个性化的功能。
        菜单选项结束之后,应该都可以做出一个比较好的剧情故事,自己编个小剧本或者找金庸小说抄一小段剧情都是完全可以实现的。在设计剧情上有什么疑问的都可以询问。

        本来准备想讲一下SetD和GetD的,还是等有一点剧情编写经验之后再讲吧,如果连instruct_3函数都没会用,讲了也不会明白。先进入战斗要素讲解,回头再来说。


忘记上附件:

9.6   补充知识
        自定义一个居中显示的菜单选项函数,x2,y2传值也可以绝对的居中。但是还是有一个小问题,菜单如果数字很多的时候,就会偏离出来,经过多次测试发现2个数字显示的长度比1个中文稍微多1个像素左右,数字越多就会越明显
        定义函数
  1. --菜单相对居中
  2. local function My_ShowMenu(menuItem,numItem,numShow,x1,y1,x2,y2,isBox,isEsc,size,color,selectColor)

  3.         if size == nil then   --如果size不传值,使用默认大小
  4.                 size = CC.DefaultFont;
  5.         end
  6.         
  7.         if color == nil then   --如果不传color,默认橙色
  8.                 color = C_ORANGE;
  9.         end
  10.         
  11.         if selectColor == nil then   --如果不传selectColor,默认选中为白色
  12.                 selectColor = C_WHITE;
  13.         end

  14.         if x1 == -1 then        --如果x1传的是-1,水平居中显示
  15.                 local len = 0;
  16.                 for i,v in pairs(menuItem) do
  17.                         if #v[1] > len then
  18.                                 len = #v[1];
  19.                         end
  20.                 end
  21.                
  22.                 if x2 == 0 then    --如果是默认计算长度
  23.                         x1 = CC.ScreenW/2 - 2*CC.MenuBorderPixel - len*size/4;
  24.                 elseif x2 > x1 then   --如果要传x2进来
  25.                         x1 = CC.ScreenW - x2;
  26.                         
  27.                         --x2传屏幕一半时,总要留个缝给文字显示吧,两边都挪一挪
  28.                         local diffx = x2 - x1;
  29.                         if diffx < len*size/2 + 2*CC.MenuBorderPixel then
  30.                                 x1 = x1 - (len*size/2 + 2*CC.MenuBorderPixel)/2 + diffx/2;
  31.                                 x2 = x2 + (len*size/2 + 2*CC.MenuBorderPixel)/2 - diffx/2;
  32.                         end
  33.                 end
  34.                
  35.         end
  36.         
  37.         if y1 == -1 then   --如果y1传的是-1,垂直居中显示
  38.                 if y2 == 0 then
  39.                         y1 = CC.ScreenH/2 - 2*CC.MenuBorderPixel - numItem*(size+CC.RowPixel)/2 + CC.RowPixel/2;
  40.                 elseif y2 > y1 then
  41.                         y1 = CC.ScreenH - y2;
  42.                         
  43.                         --y1也是同样,文字要留点空隙
  44.                         local diffy = y2 - y1;
  45.                         if diffy < 2*CC.MenuBorderPixel + numItem*(size+CC.RowPixel)/2 - CC.RowPixel/2 then
  46.                                 y1 = y1 - (2*CC.MenuBorderPixel + numItem*(size+CC.RowPixel) - CC.RowPixel/2)/2 + diffy/2;
  47.                                 y2 = y2 + (2*CC.MenuBorderPixel + numItem*(size+CC.RowPixel) - CC.RowPixel/2)/2 - diffy/2;
  48.                         end
  49.                 end
  50.         end
  51.         


  52.         ShowMenu(menuItem,numItem,numShow,x1,y1,x2,y2,isBox,isEsc,size,color,selectColor);

  53. end

  54. --使用自定义函数
  55. local menu={{"确定定定定定定定定定",nil,2},
  56.                     {"取消12345678121212",nil,1},
  57.                     {"取消2",nil,1},
  58.                     {"取消3",nil,1},
  59.                     {"取消4",nil,1},
  60.                     {"取消5",nil,1},
  61.                     {"取消6",nil,1},
  62.                     {"取消7",nil,1},
  63.                     {"取消8",nil,1},
  64.                     {"取消9",nil,1},
  65.                     {"取消10",nil,1},
  66.                     {"取消11",nil,1},
  67.                     {"取消12",nil,1},
  68.                     {"取消13",nil,1}
  69.                     };

  70. My_ShowMenu(menu,14,0,-1,-1,440,350,1,1);
复制代码
这样用起来更简单一点,不用记字体,颜色什么的。

自定义菜单函数实例图



        本讲至此结束了,下一讲将会是场景数据操作。


JPG后缀传不了图片,要jpg小写才行,蛋疼啊



本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?我要成为铁血侠客

x
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2011-10-9 12:49 | 显示全部楼层
哦楼主真用心哦~顶下~

点评

呵呵,我不是搞美工的~  发表于 2011-10-9 13:17
感谢支持。 比起你的美工,差远了....  发表于 2011-10-9 13:01
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2011-10-9 13:54 | 显示全部楼层
本帖最后由 tsmdsyp 于 2011-10-9 13:55 编辑

详细的讲解!

给LZ出个小课题
现在很多人喜欢把菜单的位置设在正中
但每次用时要自已计算x1,y1的位置
那么请在菜单函数中加一段代码
当x1,y1,x2,y2的输入值分别为-1,-1,0,0时
程序就自动处理菜单的显示位置----居中显示

点评

菜单项里,如果数字多就是溢出到边框外面。 自动计算x2, y2也是这样的效果  发表于 2011-10-9 16:04
是放到了附件里,没有在上面讲。。。  发表于 2011-10-9 14:30
那就一起发了吧,相信很多人会用到的  发表于 2011-10-9 13:59
其实我已经写了,呵呵。 没放出来而已  发表于 2011-10-9 13:57
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
 楼主| 发表于 2011-10-9 14:20 | 显示全部楼层
本帖最后由 蓝烟清 于 2011-10-9 15:53 编辑
tsmdsyp 发表于 2011-10-9 13:54
详细的讲解!

给LZ出个小课题:

S大爱给人出难题,呵呵。
代码在一楼,9.6 补充知识  



点评

我就知道S大会这么问,已经修正了,放在补充知识那,附件也更新了  发表于 2011-10-9 15:49
在用-1这个参数居中显示时,还是把x2和y2也限定一下吧 写程序时尽量写得完善一些  发表于 2011-10-9 15:48

评分

参与人数 1声望 +5 收起 理由
tsmdsyp + 5 小课题奖励

查看全部评分

【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2011-10-9 16:11 | 显示全部楼层
我的意思是在处理x1为-1时,加一句x2=0就行了
这样即使有人给x2赋了其它值,在这里也就清掉了(y参数同样)
剩下的后面有相关代码处理

点评

嗯。我知道,其实就是只要x1,y1传入-1,那么就限定x2=0,y2=0,让他自动计算。不过真的不要紧,主要还是居中,也很少会用到x2,y2  发表于 2011-10-9 23:59
呵呵,看来你没明白我的意思 算了,一点小问题,不讨论了  发表于 2011-10-9 18:58
这样感觉不是很好,就和之前菜单的有些区别了。 现在好一点,不清除,传x2,y2同样有之前函数的效果,居中效果会有自适应的调整  发表于 2011-10-9 17:55
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2011-10-9 16:21 | 显示全部楼层
本帖最后由 jy02785317 于 2011-10-9 16:22 编辑
但是还是有一个小问题,菜单如果数字很多的时候,就会偏离出来,经过多次测试发现2个数字显示的长度比1个中文稍微多1个像素左右,数字越多就会越明显

程序计算时,直接使用两个半角字符宽度等于一个全角字符,对于等宽字体,这个当然OK,但是其他的就不行了。

点评

我估计是在计算字体宽度的时候,就留下的问题,半角的宽度不是绝对的占全角的一半  发表于 2011-10-9 18:01
嗯。菜单项中数字或字母超过10个的时候,才会比较明显。这个在实际中是比较少用到.....除非是做英文版的金庸MOD ,就得考虑这个问题  发表于 2011-10-9 17:59
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2011-11-10 13:18 | 显示全部楼层
本帖最后由 wklee3 于 2011-11-10 13:23 编辑

作天用了 9.6 的 function My_ShowMenu,  發現 line 56 應為

return ShowMenu(menuItem,numItem,numShow,x1,y1,x2,y2,isBox,isEsc,size,color,selectColor);



楼主的教學資源真要一讚



【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2011-12-8 13:51 | 显示全部楼层
这个 蓝大吖
9.4.2中 你的2级子菜单 的X坐标
“local x = 20 + 4*CC.DefaultFont + 3*CC.MenuBorderPixel;” 这个是什么意思吖? 怎么得出这个算法的呐? 请教请教

点评

X和Y是显示的位置, 这些位置不固定,都是自己慢慢调的。 CC. 开头的都是常量,在程序中就定义好的  发表于 2011-12-8 14:00
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2011-12-8 14:22 | 显示全部楼层
厄 不是 蓝大 我知道XY表示的是坐标
我的意思是 加上了“4*CC.DefaultFont + 3*CC.MenuBorderPixel” 后 效果是不是 2级菜单的X位置会根据1级菜单的长度而调整?“4*CC.DefaultFont + 3*CC.MenuBorderPixel”又分别代表什么呢?为什么要用这个来调整呐? 不好意思 我才学了没几天 问题问的浅 多担待吖

点评

原来如此 受教了 ~  发表于 2011-12-8 15:34
不会的,每级菜单的位置都要另外设置。CC.DefaultFont是默认字体大小,CC.MenuBorderPixel是菜单两边的缝隙大小。用这些来调整比较方便,当把字体大小进行修改时,相应的位置就可以自动调整  发表于 2011-12-8 15:17
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2012-1-4 09:28 | 显示全部楼层
有个难题,蓝大~
怎么做到随机不重复菜单
比如,allmenu一共有20个,每次显示5个,怎么做到这5个不重复呢

点评

这个得看你的menu怎么定义了,你自己在menu进行一次排序才行。ShowMenu默认都是显示前五个的  发表于 2012-1-4 09:32
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。
发表于 2018-4-25 11:43 | 显示全部楼层
蓝大威武,有些还看不明白,但看明白的都受益菲浅。
【武侠.中国】铁血丹心论坛(大武侠):致力于推广和发展武侠文化,让我们一起努力,做全球最大的武侠社区。
可能是目前为止最好的金庸群侠传MOD游戏交流论坛,各种经典武侠游戏等你来玩,各种开源制作工具等你来实现你的游戏开发之梦。

本版积分规则

小黑屋|手机版|铁血丹心

GMT+8, 2024-5-6 01:38

Powered by Discuz! X3.4 Licensed

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表