0

所以我正在尝试使用 löve2d 在 lua 中编写一个像游戏一样的太空入侵者,第一波敌人运行顺利,但是一旦我尝试向 levelctrl 表添加另一波我得到这个错误:bad argument #1 to 'pairs'(表预期,没有)在第 235 行(即使我填充了第二个表)

function love.load()
hero = {}
hero.x = 400 - 16
hero.y = 450
hero.speedx = 300
hero.speedy = 50
hero.shots = {}
bgx = 0 
bgs = .25
fleet1 = {}
f1x = 0
f1f = 0
lost = 0
score = 0
game = 0 
menu = 1
startup = 1
--Images
bg = love.graphics.newImage("img/space.png")
bullet = love.graphics.newImage("img/shot.png")
player = love.graphics.newImage("img/player.png")
trail = love.graphics.newImage("img/trail.png")
ship1 = love.graphics.newImage("img/enemy1.png")
looser = love.graphics.newImage("img/looser.png")
boomp1 = love.graphics.newImage("img/boomp1.png")
boomp2 = love.graphics.newImage("img/boomp2.png")
boomp3 = love.graphics.newImage("img/boomp3.png")
boomp4 = love.graphics.newImage("img/boomp4.png")
boom1 = love.graphics.newImage("img/boom1.png")
boom2 = love.graphics.newImage("img/boom2.png")
boom3 = love.graphics.newImage("img/boom3.png")
boom4 = love.graphics.newImage("img/boom4.png")
winner = love.graphics.newImage("img/winner.png")
title = love.graphics.newImage("img/title.png")
message = love.graphics.newImage("img/message.png")
restart = love.graphics.newImage("img/restart.png")
icon = love.graphics.newImage("img/icon.gif")
boomtimer=0
isdead=0
boom={}
bgs = .25
bgx = 0
menublink = 0
menuf = 0
end

function love.update(dt)
    if bgx < 600 then
        bgx = bgx + bgs
    else 
        bgx = -599
    end
    if bgs > .30 then
        bgs = bgs - 2*dt
    end
    if menublink < 48 and menuf==0 then
        menublink = menublink + 1
    else
        menuf=1
        menublink = menublink -1
        if menublink == 0 then
            menuf=0
        end
    end
    if menu == 1 then
        hero = {}
        hero.x = 400 - 16
        hero.y = 450
        hero.speedx = 300
        hero.speedy = 50
        hero.shots = {}
        f1x = 0
        f1f = 0
        lost = 0
        score = 0
        boomtimer=0
        isdead=0
        won=0
        boom={}
        fleet1 = {}
        for i=0,7 do
            enemy = {}
            enemy.width = 32
            enemy.height = 16
            enemy.img = ship1
            enemy.x = i * (enemy.width + 64) + 48
            if i<4 then
                if i % 2 == 0 then
                    enemy.y = 0 - enemy.height
                else
                    enemy.y = -16 - enemy.height
                end
            else
                if i % 2 == 0 then
                    enemy.y = -16 - enemy.height
                else
                    enemy.y = 0 - enemy.height
                end
            end
            table.insert(fleet1, enemy)
        end
        boss = {}
        level = 1
        levelctrl = {}
        table.insert(levelctrl, fleet1)
        if love.keyboard.isDown(" ") then
            menu = 0
            game = 1
        end
    elseif game == 1 then
        if isdead==0 then
            if love.keyboard.isDown("left") then
                if hero.x > 0 then
                    hero.x = hero.x - hero.speedx*dt
                end
            elseif love.keyboard.isDown("right") then
                if hero.x < 800-32 then
                    hero.x = hero.x + hero.speedx*dt
                end
            end
            if love.keyboard.isDown("up") then
                if hero.y > 300 then
                    hero.y = hero.y - hero.speedy*dt
                    up=1
                else
                    up=0
                end
                if bgs < 4 then
                    bgs = bgs + 5*dt
                end
            elseif love.keyboard.isDown("down") then
                if hero.y < 600-64 then
                    hero.y = hero.y + hero.speedy*2*dt
                end
            else
                    up=0
            end
        end
        for i,v in ipairs(hero.shots) do
                v.y = v.y - dt * 300
        end
        if won == 0 then
            local remShot = {}
            local remEnemy = {}
            for i,v in ipairs(hero.shots) do
                if v.y < 0 then
                    table.insert(remShot, i)
                end
                for ii,vv in ipairs(levelctrl[1]) do
                    if CheckCollision(v.x,v.y,32,32,vv.x,vv.y,vv.width,vv.height) then
                        x = {}
                        x.x = vv.x
                        x.y = vv.y
                        x.t = 0
                        table.insert(boom, x)
                        table.insert(remEnemy, ii)
                        table.insert(remShot, i)
                    end
                end
            end
            for i,v in ipairs(levelctrl[1]) do
                if CheckCollision(hero.x,hero.y,32,64,v.x,v.y,v.width,v.height) then
                    lost = 1
                end
            end
            for i,v in ipairs(remShot) do
                table.remove(hero.shots, v)
            end
            for i,v in ipairs(remEnemy) do
                table.remove(levelctrl[1], v)
                score = score + 1
            end
            if level == 1 then
                for i,v in ipairs(levelctrl[1]) do
                    v.y = v.y + dt * 12
                    if v.y > 512 then
                        lost = 1
                    end
                    if v.x>0 and v.x < 768 then
                        if f1f == 0 then
                            if f1x<3 then
                                f1x = f1x + 1 * dt
                                v.x = v.x + 1
                            else
                                f1f = 1
                            end
                        else
                            if f1x>-3 then
                                f1x = f1x - 1 * dt
                                v.x = v.x - 1
                            else
                                f1f = 0
                            end
                        end
                    end
                end 
            end
        end
        if empty(levelctrl[1]) == true and won == 0 then
            level = level + 1
            table.remove(levelctrl, 1)
            if remEnemy ~= nil then
                for k in pairs (remEnemy) do
                    remEnemy[k] = nil
                end
            end
        end
        if won == 1 and love.keyboard.isDown("return") then
            menu = 1 
            game = 0
        elseif lost == 1 and love.keyboard.isDown("return") then
            menu = 1 
            game = 0
        end
    end
end

function love.draw()
    love.graphics.setIcon(icon)
    love.graphics.setColor(255,255,255,255)
    love.graphics.draw(bg, 0, bgx)
    love.graphics.draw(bg, 0, bgx-1199)
    if menu == 1 then
        love.graphics.draw(title)
        if menuf == 1 then
            love.graphics.draw(message)
        end
    elseif game == 1 then
        for i,v in ipairs(hero.shots) do
            love.graphics.draw(bullet, v.x, v.y)
        end
        if up==1 then
            love.graphics.draw(trail, hero.x, hero.y)
        end
        for i,v in ipairs(levelctrl[1]) do
            love.graphics.draw(v.img, v.x, v.y)
        end
        if lost == 0 then
            love.graphics.draw(player, hero.x, hero.y)
        else
            isdead=1
            if boomtimer<8 then
                love.graphics.draw(boomp1, hero.x-16, hero.y)
                boomtimer = boomtimer + 1
            elseif boomtimer<16 then
                love.graphics.draw(boomp2, hero.x-16, hero.y)
                boomtimer = boomtimer + 1
            elseif boomtimer<24 then
                love.graphics.draw(boomp3, hero.x-16, hero.y)
                boomtimer = boomtimer + 1
            elseif boomtimer<32 then
                love.graphics.draw(boomp4, hero.x-16, hero.y)
                boomtimer = boomtimer + 1
            else
                love.graphics.draw(looser)
                if menuf == 1 then
                    love.graphics.draw(restart, 0, 20)
                end
            end
        end
        for i,v in ipairs(boom) do
            if v.t<8 then
                love.graphics.draw(boom1, v.x, v.y-8)
                v.t = v.t + 1
            elseif v.t<16 then
                love.graphics.draw(boom2, v.x, v.y-8)
                v.t = v.t + 1
            elseif v.t<24 then
                love.graphics.draw(boom3, v.x, v.y-8)
                v.t = v.t + 1
            elseif v.t<32 then
                love.graphics.draw(boom4, v.x, v.y-8)
                v.t = v.t + 1
            else
                table.remove(boom, i)
            end
        end
        if won == 0 then
            if empty(levelctrl) then
                won = 1
            end
        end
        if won == 1 then
            love.graphics.draw(winner)
            if menuf == 1 then
                love.graphics.draw(restart, 0, 20)
            end
        end
    end
end

function shoot()
    local shot = {}
    shot.x = hero.x
    shot.y = hero.y - 4
    table.insert(hero.shots, shot)
end

function CheckCollision(ax1,ay1,aw,ah, bx1,by1,bw,bh)
  local ax2 = ax1 + aw
  local ay2 = ay1 + ah
  local bx2 = bx1 + bw
  local by2 = by1 + bh
  return ax1 <  bx2 and ax2 > bx1 and ay1 < by2 and ay2 > by1
end

function love.keyreleased(key)
    if isdead==0 then
        if (key == " ") then
            shoot()
        end
    end
end

function empty(self)
    for _, _ in pairs(self) do
        return false
    end
    return true
end

这就是所有的代码,更具体地说,我遇到了一个问题:

for i,v in ipairs(levelctrl[1]) do
     love.graphics.draw(v.img, v.x, v.y)
end

levelctrl 最初有 2 个表,所以在我删除第一个表以撞倒第二个表后,我收到错误的参数错误

4

2 回答 2

0

问题似乎在第 200 行附近:

    if empty(levelctrl[1]) == true and won == 0 then
        level = level + 1
        table.remove(levelctrl, 1)

levelctrl在这里,您可以从空的表格中删除并增加级别。由于表已经是空的,你不能重复使用它而不是删除它(导致下一次渲染崩溃)?删除table.remove呼叫应该会有所帮助。

于 2013-07-08T09:45:21.750 回答
0

我懂了

    levelctrl = {}
    table.insert(levelctrl, fleet1)

所以 levelctrl = {fleet1}

一段时间后,当你赢了,

    if empty(levelctrl[1]) == true and won == 0 then
        level = level + 1
        table.remove(levelctrl, 1)

所以 levelctrl = {}

获胜仍为 0,游戏仍为 1。

然后在你的绘图功能

    for i,v in ipairs(levelctrl[1]) do
        love.graphics.draw(v.img, v.x, v.y)
    end

此时 levelctrl = {} 和 levelctrl[1] = nil。

一种解决方案是用

if not empty(levelctrl)

此外,如果您尝试多次将fleet1 添加到levelctrl,

    levelctrl = {}
    table.insert(levelctrl, fleet1)
    table.insert(levelctrl, fleet1)
    table.insert(levelctrl, fleet1)

然后 levelctrl 将具有同一个表的三个实例,从 levelctrl[1] 中删除某些内容会将其从fleet1中删除=>所有级别同时变为空。

于 2015-03-10T06:26:32.673 回答