You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

LOVE2D游戏报错:main.lua:80 对nil值'y'执行算术操作求助

解决LOVE2D中"attempt to perform arithmetic on field 'y' (a nil value)"错误

错误原因

  1. 全局camera未提前初始化:你在全局作用域只声明了空表local camera = {},但未给y赋值。第一次运行love.update时,执行到玩家地面碰撞判断代码(player.y + player.height > love.graphics.getHeight() - ground.height - camera.y),此时camera.y为nil,无法参与算术运算,直接触发报错。
  2. 局部变量覆盖全局变量:你在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.30 22:57:22