love2d教程27--菜单
说明
现在已经开始复刻“金庸群侠传”了,对于通用的love2d用法我已经写的较多了,希望大家看后
可以做一些自己的游戏。之后可能不会再像以前一样更新了,若是遇到通用love2d用法,我还
是会继续写。由于复刻才开始,还没搭好框架,等以后搭好框架后我把代码托管到github/gitcafe
上,这样大家可以和我一起开发。
曾经我介绍过middleclass,可是后来在代码里基本没使用,主要原因有:
1、自定义的类可以很方便的用middleclass重构
2、以前的代码不涉及继承,不需要middleclass复杂的功能
不过现在我要转向middleclass了,因为之后百分百会涉及继承、多态等面向对象的概念。
正文
由于我的菜单是仿“金庸群侠传”的所以功能需求较简单,只是实现了二级菜单和事件回调。
1、先看菜单的结构。主菜单{name,{},func},其中表里的{}表子菜单,子菜单的结构为
{name,func},如果把子菜单的结构做的与主菜单一样,那就可以实现多级菜单了,不过
感觉没必要,所以就简单点。其中name指菜单显示的文字,func是回调函数(可以为空)。
同时还有一个保存主菜单的表menus={},记录当前主菜单和子菜单的索引。
2、再看菜单项的添加。每次添加菜单时直接向menus表里添加主菜单表,添加子菜单时直接
向主菜单的{}表里插入子菜单表。
3、绘图。先保存当前的颜色,把当前索引设为颜色A,把其它菜单设为颜色B,再恢复当前
颜色。这样就可以实现突出显示当前菜单了。
4、键盘检测。检测键盘的按下,根据是主菜单还是子菜单,采取不同的策略。
图如下:
代码为:
menu.lua
require('middleclass') menu=class('menu') menu.static.colordark={120,0,0} --暗色 menu.static.colorlight={255,0,0} --亮色 --居中坐标按四个汉字标准,四项菜单 --菜单的坐标x,y 多少项n 可以为空 function menu:initialize( x, y, n ) self.mainmenus={} --主菜单 self.isInSub=false --是否进入子菜单 self.id=1 --主菜单id self.sid=1 --子菜单id local font = love.graphics.getFont( ) local w,h = font:getWidth("一"),font:getHeight() --得到字体数据 self.fw,self.fh=w,h self.x=x or (love.graphics.getWidth()-w*4)/2 --x居中 self.y=y or (love.graphics.getHeight()-4*h-20) --y离底部20 end --背景图 -- todo 参数检测 function menu:SetImage(imgname) self.img=love.graphics.newImage(imgname) end --设置背景音乐 function menu:SetMusic(source) self.music=love.audio.newSource(source) self.music:setLooping(true) love.audio.play(self.music) end --设置移动光标的音乐 function menu:SetMoveMusic(source ) -- body end --设置选中时的音乐 function menu:SetSelectMusic( source ) -- body end --新建菜单 function menu:AddMenu(name,func) self.mainmenus[#self.mainmenus+1]={name,{},func} end --添加子菜单 function menu:SubMenu(name,parentid,func) -- body table.insert(self.mainmenus[parentid][2],{name,func}) end function menu:draw() local r,g,b,a = love.graphics.getColor() --保存原有颜色 if self.img then love.graphics.draw(self.img,0,0) end --判断绘制对象 local menus={} local id=0 if self.isInSub then menus=self.mainmenus[self.id][2] id=self.sid else menus=self.mainmenus id=self.id end for k,v in ipairs(menus) do if k==id then love.graphics.setColor(unpack(menu.colorlight)) else love.graphics.setColor(unpack(menu.colordark)) end love.graphics.print(v[1],self.x,(k-1)*self.fh+self.y) end --恢复 love.graphics.setColor(r,g,b,a) end function menu:update(dt) end function menu:keypressed(key, unicode) local id = 0 local menus = {} if self.isInSub then id=self.sid menus=self.mainmenus[self.id][2] else id=self.id menus=self.mainmenus end --键盘移动 if key=="up" then id=id-1 elseif key=="down" then id=id+1 end if id>#menus then id=1 elseif id<1 then id=#menus end --把id赋值回去,检测键盘 if self.isInSub then self.sid=id local fun=menus[id][2] --第二项为函数 if type(fun)=="function" then fun() end if key=="escape" then self.isInSub=false self.sid=1 end else self.id=id --回调 if key=="return" then local fun=menus[id][3] --第三项是函数 if type(fun)=="function" then fun() end local sub = menus[id][2] --第二项是子菜单 if #sub>=1 then self.isInSub=true end end end end
main.lua
require('font') require('menu') function love.load() love.graphics.setFont(menufont) jyMenu=menu:new() jyMenu:SetImage("assets/title.png") jyMenu:SetMusic("assets/game17.ogg") jyMenu:AddMenu("重新开始") jyMenu:AddMenu("载入进度") jyMenu:SubMenu("进度1",2) --第二项主菜单的子菜单 jyMenu:SubMenu("进度2",2) jyMenu:SubMenu("进度3",2) jyMenu:AddMenu("游戏设置") jyMenu:AddMenu("退出游戏",function () love.event.push("quit") end) --绑定回调 end function love.draw() jyMenu:draw() end function love.keypressed(key,unicode) jyMenu:keypressed(key,unicode) end
代码下载,请点击。
作者:半山
出处:http://www.cnblogs.com/xdao/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。