0
votes

I keep getting this error saying that I attempted tonindex local 'e' (a number value), and I have no clue what I'm doing wrong. I was trying to work on a game where you have to shoot aliens coming toward the ground, and not let them touch the ground. I'm quite new to Lua and Love2d, so if this is an easy fix, I'm sorry.

Code:

function love.load()
  ship = love.graphics.newImage("ship.png")
  heart = love.graphics.newImage("heart.png")
  font = love.graphics.newFont("font.ttf", 20)
  player = {}
  storage = {}
  storage.enemys = {}
  level = 1
  storage.enemys.cooldown = 400 / level
  player.x = 0
  player.y = 600
  player.bullets = {}
  player.cooldown = 20
  player.speed = 10
  ammo = 3
  life = 2

  player.fire = function()
    if player.cooldown <= 0 then
      if ammo > 0 then
        ammo = ammo - 1
        player.cooldown = 20
        bullet = {}
        bullet.x = player.x + 35
        bullet.y = player.y
        table.insert(player.bullets, bullet)
      end
    end
  end

  storage.spawn = function()
    if enemys.cooldown <= 0 then
      storage.enemy.cooldown = 400 / level
      enemy = {}
      enemy.x = love.math.random(0, 780)
      enemy.y = 0
      table.insert(storage.enemys, enemy)
    end
  end


  reload = function()
    ammo = 3
  end

end

function love.update(dt)
  player.cooldown = player.cooldown - 1
  storage.enemys.cooldown = storage.enemys.cooldown - 1

  if player.x >= 720 then
    player.x = 720
  elseif player.x <= 0 then
    player.x = 0
  end

  if love.keyboard.isDown("f") then
    player.x = player.x + player.speed
  elseif love.keyboard.isDown("a") then
    player.x = player.x - player.speed
  end

  if love.keyboard.isDown("r") then
    reload()
  end

  if love.keyboard.isDown("space") then
    player.fire()
  end

  for i,b in ipairs(player.bullets) do
    if b.y < -10 then
      table.remove(player.bullets, i)
    end
    b.y = b.y - 10
  end

  for i,e in ipairs(storage.enemys) do
    if e.y < 700 then
      table.remove(storage.enemys, i)
      life = life - 1
    end
    e.y = e.y - 6
  end

  if storage.enemys.cooldown <= 0 then
    enemys.spawn()
  end

end

function love.draw()
  love.graphics.draw(ship, player.x, player.y)

  for _,e in pairs(storage.enemys) do
    love.graphics.setColor(0,255,0)
    love.graphics.rectangle("fill", e.x, e.y, 20, 20)
    love.graphics.setColor(255, 255, 255)
  end

  for _,b in pairs(player.bullets) do
    love.graphics.setColor(255,0,0)
    love.graphics.rectangle("fill", b.x, b.y, 2, 6)
    love.graphics.setColor(255, 255, 255)
  end

  if life == 2 then
    love.graphics.draw(heart, 0,0)
    love.graphics.draw(heart, 25,0)
  elseif life == 1 then
    love.graphics.draw(heart, 0,0)
  end

  love.graphics.setFont(font)
  love.graphics.print("Ammo", 715, 0)

  if ammo == 3 then
    love.graphics.rectangle("fill", 670, 20, 125, 25)
  elseif ammo == 2 then
    love.graphics.rectangle("fill", 711, 20, 84, 25)
    love.graphics.rectangle("line", 670, 20, 125, 25)
  elseif ammo == 1 then
    love.graphics.rectangle("fill", 752, 20, 43, 25)
    love.graphics.rectangle("line", 670, 20, 125, 25)
  elseif ammo == 0 then
    love.graphics.rectangle("line", 670, 20, 125, 25)
  end
end
1
You didn't tell us which line is line 98. - Dimitry

1 Answers

1
votes

First of all

The plural of enemy is enemies, not enemys ;)

storage.enemies

This table contains a list of enemies (as a sequence) as well as a cooldown value, which is a number.

pairs

This function iterates over all key-value-pairs of a table.

The problem

You might have guessed it by now. pairs(storage.enemies) not only iterates over all your enemies (at integer keys), but also over the cooldown (at the string key 'cooldown'), leading to you attempting to index a number.

Example:

for key, value in pairs({'a', 'b', 'c', foo='bar'}) do
  print(key, value)
end

will print something like

1    a
foo  bar
3    c
2    b

Note that the order is completely random and depends on how Lua decides to internally store the table.

for key, value in ipairs({'a', 'b', 'c', foo='bar'}) do
  print(key, value)
end

That, however, should print:

1    a
2    b
3    c

Because ipairs, as opposed to pairs only iterates over integer keys in order until it reaches the first nil value. For example, for {1, 2, 3, nil, 5} it would only iterate over 1, 2 and 3.