LOVE2D游戏报错:main.lua:80 对nil值'y'执行算术操作求助
解决LOVE2D中"attempt to perform arithmetic on field 'y' (a nil value)"错误
错误原因
- 全局
camera未提前初始化:你在全局作用域只声明了空表local camera = {},但未给y赋值。第一次运行love.update时,执行到玩家地面碰撞判断代码(player.y + player.height > love.graphics.getHeight() - ground.height - camera.y),此时camera.y为nil,无法参与算术运算,直接触发报错。 - 局部变量覆盖全局变量:你在
love.update函数内部重新定义了局部camera表(local camera = {x=0,y=0}),这会覆盖全局camera变量,导致后续更新的是局部变量,全局camera始终为空,即使love.update执行完毕,love.draw中访问camera.y依然是nil,会引发新的错误。
修复方案
- 在
love.load函数里初始化全局camera的x和y值,确保第一次进入love.update时camera.y已有有效值。 - 删除
love.update内部的局部camera定义,直接使用全局camera进行位置更新。
修正后的完整代码
-- Load Love2D module local love = require('love') -- Define global variables local player = {} local ground = {} local camera = {} local enemy = {} -- Load game assets function love.load() -- Load player asset player.img = love.graphics.newImage('player.png') player.x = 50 player.y = 250 player.speed = 150 player.jump_height = -300 player.gravity = 500 player.velocity = 0 player.width = player.img:getWidth() player.height = player.img:getHeight() player.health = 5 player.dead = false -- Load ground asset ground.img = love.graphics.newImage('ground.png') ground.width = ground.img:getWidth() ground.height = ground.img:getHeight() ground.length = 50 -- Load enemy asset enemy.img = love.graphics.newImage('enemy.png') enemy.width = enemy.img:getWidth() enemy.height = enemy.img:getHeight() enemy.x = 500 enemy.y = love.graphics.getHeight() - ground.height - enemy.height enemy.speed = 100 enemy.health = 5 enemy.dead = false enemy.attacking = false enemy.direction = 'left' -- 初始化全局camera camera.x = 0 camera.y = 0 end -- Handle user input function love.keypressed(key) if key == 'space' and player.velocity == 0 then player.velocity = player.jump_height end end -- Handle mouse input function love.mousepressed(x, y, button, istouch) if button == 1 and not enemy.dead and not player.dead then local mouse_x, mouse_y = love.graphics.inverseTransformPoint(x, y) if mouse_x >= enemy.x and mouse_x <= enemy.x + enemy.width and mouse_y >= enemy.y and mouse_y <= enemy.y + enemy.height then enemy.health = enemy.health - 1 if enemy.health == 0 then enemy.dead = true end end end end -- Update game state function love.update(dt) -- Move player left and right if not player.dead then if love.keyboard.isDown('a') then player.x = player.x - player.speed * dt elseif love.keyboard.isDown('d') then player.x = player.x + player.speed * dt end -- Apply gravity to player player.velocity = player.velocity + player.gravity * dt player.y = player.y + player.velocity * dt -- Check if player is on the ground if player.y + player.height > love.graphics.getHeight() - ground.height - camera.y then player.velocity = 0 player.y = love.graphics.getHeight() - ground.height - player.height - camera.y end -- Check if player is touching enemy if not enemy.dead and player.x + player.width > enemy.x and player.x < enemy.x + enemy.width and player.y + player.height > enemy.y and player.y < enemy.y + enemy.height then player.health = player.health - 1 if player.health == 0 then player.dead = true player.health = 5 player.x = 50 player.y = 250 end end end -- Update enemy position if not enemy.attacking then if enemy.direction == 'left' then enemy.x = enemy.x - enemy.speed * dt if enemy.x < 0 then enemy.direction = 'right' end elseif enemy.direction == 'right' then enemy.x = enemy.x + enemy.speed * dt if enemy.x + enemy.width > love.graphics.getWidth() then enemy.direction = 'left' end end -- Check if enemy sees player if player.x + player.width > enemy.x and player.x < enemy.x + enemy.width and player.y + player.height > enemy.y and player.y < enemy.y + enemy.height then enemy.attacking = true end else -- Move enemy towards player if enemy.x > player.x then enemy.x = enemy.x - enemy.speed * dt enemy.direction = 'left' elseif enemy.x < player.x then enemy.x = enemy.x + enemy.speed * dt enemy.direction = 'right' end -- Attack player if within range if player.x + player.width > enemy.x and player.x < enemy.x + enemy.width and player.y + player.height > enemy.y and player.y < enemy.y + enemy.height then player.health = player.health - 1 if player.health == 0 then player.dead = true player.health = 5 player.x = 50 player.y = 250 end else -- Stop attacking if player is out of range enemy.attacking = false end end -- Update camera位置(直接使用全局camera) camera.y = player.y - love.graphics.getHeight() / 2 + player.height / 2 if camera.y < 0 then camera.y = 0 elseif camera.y > ground.height * ground.length - love.graphics.getHeight() then camera.y = ground.height * ground.length - love.graphics.getHeight() end end -- Draw game objects function love.draw() -- Draw ground for i = 0, ground.length - 1 do love.graphics.draw(ground.img, i * ground.width, love.graphics.getHeight() - ground.height - camera.y) end -- Draw player if not player.dead then love.graphics.draw(player.img, player.x, player.y - camera.y) end -- Draw enemy if not enemy.dead then love.graphics.draw(enemy.img, enemy.x, enemy.y - camera.y) end -- Draw player health if not player.dead then love.graphics.print('Health: ' .. player.health, 10, 10) end -- Draw enemy health if not enemy.dead then love.graphics.print('Enemy Health: ' .. enemy.health, love.graphics.getWidth() - 150, 10) end end
内容的提问来源于stack exchange,提问作者v3nxm
相关产品推荐
相关产品推荐

