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

 

代码下载,请点击

posted @ 2013-04-20 19:17  半山th  阅读(1449)  评论(4编辑  收藏  举报