0

そのため、löve2d を使用して lua でゲームのようなスペース インベーダーをプログラムしようとしています。敵の最初の波はスムーズに実行されますが、levelctrl テーブルに別の波を追加しようとすると、次のエラーが発生します: 「ペア」への引数 #1 が正しくありません (テーブル235 行目 (2 番目のテーブルにデータを入力した場合でも)

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 つのテーブルがあるため、最初のテーブルを削除して 2 番目のテーブルを押し下げると、不正な引数エラーが表示されます

4

2 に答える 2

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.

1つの解決策は、描画関数のその部分を

if not empty(levelctrl)

また、fleet1 を levelctrl に複数回追加しようとした場合、

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

次に、levelctrl には同じテーブルの 3 つのインスタンスがあり、levelctrl[1] から何かを削除すると、それがフリート 1 から削除されます => すべてのレベルが同時に空になります。

于 2015-03-10T06:26:32.673 に答える
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 に答える