问题描述
我正试着用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