错误main.lua:23:尝试索引upvalue'菜单'(布尔值)

人气:248 发布:2022-10-16 标签: user-interface menu lua love2d

问题描述

我正试着用Lua和love2d制作一个主菜单,这是我第一次这样做,遗憾的是没有关于这个问题的教程,所以我自己试了试。我一直遇到这个错误,不知道如何修复,请帮帮忙!

完整错误消息:错误main.lua:23:尝试索引upvalue‘menu’(布尔值)traceback main.lua:23:in函数‘load’[C]:in function‘xpcall’[C]:in function‘xpcall’

菜单文件

local Menu = {}
local game_state = 'menu'
local menus = { 'Play', 'Quit' }
local selected_menu_item = 1
local window_width
local window_height
local font_height

local Map = require("map")

-- functions
local draw_menu
local menu_keypressed
local draw_game
local game_keypressed

function Menu:load()

  -- get the width and height of the game window in order to center menu items
  self.window_width, self.window_height = love.graphics.getDimensions()

  -- use a big font for the menu
  self.font = love.graphics.newFont("assets/bit.ttf", 36)

  -- get the height of the font to help calculate vertical positions of menu items
  self.font_height = font:getHeight()

end

function Menu:update(dt)

end

function Menu:draw()
  local horizontal_center = self.window_width / 2
  local vertical_center = self.window_height / 2
  local start_y = vertical_center - (self.font_height * (#menus / 2))

  -- draw guides to help check if menu items are centered, can remove later
  -- love.graphics.setColor(1, 1, 1, 0.1)
  -- love.graphics.line(horizontal_center, 0, horizontal_center, window_height)
  -- love.graphics.line(0, vertical_center, window_width, vertical_center)

  -- draw game title
  love.graphics.setColor(1, 1, 1, 1)
  love.graphics.printf("Breakout", 0, 150, window_width, 'center')

  -- draw menu items
  for i = 1, #menus do

    -- currently selected menu item is yellow
    if i == selected_menu_item then
      love.graphics.setColor(1, 1, 0, 1)

    -- other menu items are white
    else
      love.graphics.setColor(1, 1, 1, 1)
    end

    -- draw this menu item centered
    love.graphics.printf(menus[i], 0, start_y + self.font_height * (i-1), self.window_width, 'center')

  end

end

function Menu:keypressed(key)

  -- pressing Esc on the main menu quits the game
  if key == 'escape' then
    love.event.quit()

  -- pressing up selects the previous menu item, wrapping to the bottom if necessary
  elseif key == 'up' then

    selected_menu_item = selected_menu_item - 1

    if selected_menu_item < 1 then
      selected_menu_item = #menus
    end

  -- pressing down selects the next menu item, wrapping to the top if necessary
  elseif key == 'down' then

    selected_menu_item = selected_menu_item + 1

    if selected_menu_item > #menus then
      selected_menu_item = 1
    end

  -- pressing enter changes the game state (or quits the game)
  elseif key == 'return' or key == 'kpenter' then

    if menus[selected_menu_item] == 'Play' then
      Map:load()
    elseif menus[selected_menu_item] == 'Quit' then
      love.event.quit()
    end

  end

end

主文件

love.graphics.setDefaultFilter("nearest", "nearest")
local Player = require("player")
local Coin = require("coin")
local GUI = require("gui")
local Spike = require("spike")
local Camera = require("camera")
local Stone = require("stone")
local Enemy = require("enemy")
local Map = require("map")
local Enemy2 = require("enemy2")
local Sound = require("sound")
local Menu = require("menu")

function love.load()
    Sound:init("music", "sfx/music.wav", "static")
    Sound:init("breeze", "sfx/breeze.mp3", "static")
    Enemy.loadAssets()
    Enemy2.loadAssets()
    Map:load()
    background = love.graphics.newImage("assets/background2.png")
    Player:load()
    GUI:load()
    Menu:load()
end

function love.update(dt)
    Sound:update()
    World:update(dt)
    Player:update(dt)
    Coin.updateAll(dt)
    Stone.updateAll(dt)
    Enemy.updateAll(dt)
    Enemy2.updateAll(dt)
    GUI:load(dt)
    Spike:updateAll(dt)
    Camera:setPosition(Player.x, 0)
    Map:update(dt)
    Menu:load()
end

function love.draw()
    love.graphics.draw(background)
    Map.level:draw(-Camera.x, -Camera.y, Camera.scale, Camera.scale)

    Menu:draw()
    Camera:apply()
    Player:draw()
    Enemy.drawAll()
    Enemy2.drawAll()
    Coin.drawAll()
    Spike.drawAll()
    Stone.drawAll()
    Camera:clear()

    GUI:draw()
end

function love.playmusic()
    loopingMusic = Sound:play("music", "sfx", 0.05, 1)
    loopingMusic:setLooping(true)
end

function love.playBreeze()
    loopingBreeze = Sound:play("breeze", "sfx", 0.3, 1)
    loopingBreeze:setLooping(true)
end

function love.keypressed(key)
    Player:jump(key)
    Menu:keypressed(key)
    if key == "m" then
        Sound:stop("sfx")
    end
end

function beginContact(a, b, collision)
    if Coin.beginContact(a, b, collision) then 
        return
    end
    if Spike.beginContact(a, b, collision) then 
        return end
    Enemy.beginContact(a, b, collision)
    Enemy2.beginContact(a, b, collision)
    Player:beginContact(a, b, collision)
end

function endContact(a, b, collision)
    Player:endContact(a, b, collision)
end

function endGame()
    love.event.quit()
end

推荐答案

您的menu.lua没有返回您的表格菜单。

如此分配menu = require("menu")会导致menu引用Menu,但指向true

来自Lua manual:

一旦找到加载程序,Required就会使用单个 参数,modname。如果加载程序返回任何值,则REQUIRED ASSIGNSET 返回到Package.loaded[modname]的值。如果加载程序返回 没有值,也没有为Package.loaded[modname]赋值, 则REQUIRED为该项赋值为TRUE。在任何情况下,都需要 返回Package.loaded[modname]的最终值。

因此,在main.lua的第23行中,您实际上正在尝试索引true,一个布尔值。Menu:load()

return Menu添加到菜单末尾。lua

829