本帖最后由 蓝烟清 于 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); --竖向菜单
参数说明:- -- menuItem 表,每项保存一个子表,内容为一个菜单项的定义
- -- 菜单项定义为 { ItemName, 菜单项名称字符串
- -- ItemFunction, 菜单调用函数,如果没有则为nil
- -- Visible 是否可见 0 不可见 1 可见, 2 可见,作为当前选择项。只能有一个为2,
- -- 多了则只取第一个为2的,没有则第一个菜单项为当前选择项。
- -- 在只显示部分菜单的情况下此值无效。
- -- 此值目前只用于是否菜单缺省显示否的情况
- -- }
- -- 菜单调用函数说明: itemfunction(newmenu,id)
- --
- -- 返回值
- -- 0 正常返回,继续菜单循环 1 调用函数要求退出菜单,不进行菜单循环
- --
- -- numItem 总菜单项个数
- -- numShow 显示菜单项目,如果总菜单项很多,一屏显示不下,则可以定义此值
- -- =0表示显示全部菜单项
-
- -- (x1,y1),(x2,y2) 菜单区域的左上角和右下角坐标,如果x2,y2=0,则根据字符串长度和显示菜单项自动计算x2,y2
- -- isBox 是否绘制边框,0 不绘制,1 绘制。若绘制,则按照(x1,y1,x2,y2)的矩形绘制白色方框,并使方框内背景变暗
- -- isEsc Esc键是否起作用 0 不起作用,1起作用
- -- Size 菜单项字体大小
- -- color 正常菜单项颜色,均为RGB
- -- selectColor 选中菜单项颜色,
- --;
- -- 返回值 0 Esc返回
- -- >0 选中的菜单项(1表示第一项)
- -- <0 选中的菜单项,调用函数要求退出父菜单,这个用于退出多层菜单
复制代码 9.3.2 ShowMenu2
横向菜单与上面的参数定义是完全一样的,就不多说了。
9.4 实例
参数的说明眼花缭乱,呵呵,其实我第一次看到的时候确实是这种感觉。下面配合实例进行讲解。
9.4.1 最简单的例子
显示一个“确定”或“取消”的菜单选项,展示的是竖向,如果要变成横向只要把ShowMenu改成ShowMenu2就可以了。打开DIY.lua文件
第一步:- --定义一个菜单列表
- local menu={{"确定",nil,2},
- {"取消",nil,1}};
复制代码 第二步:- --定义显示的位置,并显示菜单
- local x = 50; --菜单开始的x坐标
- local y = 50; --菜单开始的y坐标
- local r = ShowMenu(menu,2,0,x,y,0,0,1,1,CC.DefaultFont,C_ORANGE, C_WHITE);
- --这样一个简单完整的菜单就有了
复制代码 第三步:- --判断选项
- if r == 0 then
- Talk("你按了ESC键",0);
- elseif r == 1 then
- Talk("你选择了 "..menu[r][1], 0);
- Talk("要不要做点什么事情",1);
- elseif r == 2 then
- Talk("你选择了 "..menu[r][1], 0);
- else
- Talk("菜单强制退出了!",0);
- end
复制代码 9.4.2 带函数的菜单项
以离开子场景和主角升级的功能为实例
打开DIY.lua文件
第一步:- --定义三个函数
- local function Leave_SubScene() --离开子场景
- if JY.SubScene > 0 then --如果当前是在子场景下
- JY.Base["人X1"] = JY.Scene[JY.SubScene]["出口X1"];
- JY.Base["人Y1"] = JY.Scene[JY.SubScene]["出口Y1"];
- end
- return 1; --一定要返回1,不然菜单不会自动消失
- end
- local function My_Menu_ChuangSong() --传送菜单
- local menu={{"移到出口",Leave_SubScene,2}};
- local x = 20 + 4*CC.DefaultFont + 3*CC.MenuBorderPixel;
- local y = 20;
- local r = ShowMenu(menu,1,0,x,y,0,0,1,1,CC.DefaultFont,C_ORANGE, C_WHITE);
- if r == 0 then --如果是按ESC,只退出这个菜单
- return 0;
- end
- return 1;
- end
- local function My_Menu_LevelUp() --主角升级菜单
- if JY.Person[0]["等级"] < 30 then
- JY.Person[0]["经验"] = CC.Exp[JY.Person[0]["等级"]];
- War_AddPersonLVUP(0);
- QZXS("主角等级升到了"..JY.Person[0]["等级"]);
- end
- end
复制代码 第二步:- --定义菜单项
- local menu={{"传送",My_Menu_ChuangSong,2},
- {"主角升级",My_Menu_LevelUp,1},
- {"关闭",nil,1},
- };
复制代码 第三步:- --显示菜单
- local num = table.getn(menu);
- local x = 20;
- local y = 20;
- 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个像素左右,数字越多就会越明显
定义函数
- --菜单相对居中
- local function My_ShowMenu(menuItem,numItem,numShow,x1,y1,x2,y2,isBox,isEsc,size,color,selectColor)
- if size == nil then --如果size不传值,使用默认大小
- size = CC.DefaultFont;
- end
-
- if color == nil then --如果不传color,默认橙色
- color = C_ORANGE;
- end
-
- if selectColor == nil then --如果不传selectColor,默认选中为白色
- selectColor = C_WHITE;
- end
- if x1 == -1 then --如果x1传的是-1,水平居中显示
- local len = 0;
- for i,v in pairs(menuItem) do
- if #v[1] > len then
- len = #v[1];
- end
- end
-
- if x2 == 0 then --如果是默认计算长度
- x1 = CC.ScreenW/2 - 2*CC.MenuBorderPixel - len*size/4;
- elseif x2 > x1 then --如果要传x2进来
- x1 = CC.ScreenW - x2;
-
- --x2传屏幕一半时,总要留个缝给文字显示吧,两边都挪一挪
- local diffx = x2 - x1;
- if diffx < len*size/2 + 2*CC.MenuBorderPixel then
- x1 = x1 - (len*size/2 + 2*CC.MenuBorderPixel)/2 + diffx/2;
- x2 = x2 + (len*size/2 + 2*CC.MenuBorderPixel)/2 - diffx/2;
- end
- end
-
- end
-
- if y1 == -1 then --如果y1传的是-1,垂直居中显示
- if y2 == 0 then
- y1 = CC.ScreenH/2 - 2*CC.MenuBorderPixel - numItem*(size+CC.RowPixel)/2 + CC.RowPixel/2;
- elseif y2 > y1 then
- y1 = CC.ScreenH - y2;
-
- --y1也是同样,文字要留点空隙
- local diffy = y2 - y1;
- if diffy < 2*CC.MenuBorderPixel + numItem*(size+CC.RowPixel)/2 - CC.RowPixel/2 then
- y1 = y1 - (2*CC.MenuBorderPixel + numItem*(size+CC.RowPixel) - CC.RowPixel/2)/2 + diffy/2;
- y2 = y2 + (2*CC.MenuBorderPixel + numItem*(size+CC.RowPixel) - CC.RowPixel/2)/2 - diffy/2;
- end
- end
- end
-
- ShowMenu(menuItem,numItem,numShow,x1,y1,x2,y2,isBox,isEsc,size,color,selectColor);
- end
- --使用自定义函数
- local menu={{"确定定定定定定定定定",nil,2},
- {"取消12345678121212",nil,1},
- {"取消2",nil,1},
- {"取消3",nil,1},
- {"取消4",nil,1},
- {"取消5",nil,1},
- {"取消6",nil,1},
- {"取消7",nil,1},
- {"取消8",nil,1},
- {"取消9",nil,1},
- {"取消10",nil,1},
- {"取消11",nil,1},
- {"取消12",nil,1},
- {"取消13",nil,1}
- };
- My_ShowMenu(menu,14,0,-1,-1,440,350,1,1);
复制代码 这样用起来更简单一点,不用记字体,颜色什么的。
自定义菜单函数实例图
本讲至此结束了,下一讲将会是场景数据操作。
JPG后缀传不了图片,要jpg小写才行,蛋疼啊
|