在卢阿接受"Attempt to index global 'sprite' (a nil value)"



我试图做一个简单的游戏应用程序,并不断遇到这个问题。我停止用Lua编程好几年了,所以我不太记得如何解决这个问题。总之,我的代码如下:

编辑:这是整个文件。还在努力弄清楚堆栈溢出的格式。第76行出现错误。

  module(..., package.seeall)
-- Main function - MUST return a display.newGroup()
function new()
    local localGroup = display.newGroup()
---------
local Rad   = math.rad
local Sin   = math.sin
local Cos   = math.cos
local Pi    = math.pi
local Atan2 = math.atan2
local radD  = 180 / Pi
local DegR = Pi / 180
local touchPoint = display.newCircle(localGroup, -50, -50, 20)
touchPoint.isFocus = false
touchPoint.alpha = 0

function GetDistanceFromObjects(obj1, obj2)
    local xDist = obj1.x - obj2.x
    local yDist = obj1.y - obj2.y
    local dist = Sqrt((xDist * xDist) + (yDist * yDist))
    return dist
end
function getAngleDeg(inX1, inY1, inX2, inY2)
    local xDist = inX2 - inX1
    local yDist = inY2 - inY1   
    local angRad = Atan2(yDist, xDist)
    return angRad * radD + 90
end

require "sprite"
function VectorFromAngle(inAngle, inVelocity)
    local vx = Cos(Rad(inAngle-90))
    local vy = Sin(Rad(inAngle-90))
    if(inVelocity ~= nil)then
        vx = vx * inVelocity
        vy = vy * inVelocity
    end
    return vx,vy
end

require ( "physics" ) 
physics.start() 
physics.setGravity( 1, 1 )
                --( x, y )
--physics.setDrawMode ( "hybrid" )
math.randomseed(os.time())
local background = display.newImage("yazd.jpeg")
localGroup:insert(background)
--width of image divided by # of pics lined up from left to right (in the sprite) = the first #
--height of image divided by # of pics lined up from top to bottom (in the sprite) = the second #
local birdSheet = sprite.newSpriteSheet( "enemy.jpg", 59, 50 )

local birdSet = sprite.newSpriteSet(birdSheet, 1, 1)
-- images 1-14
sprite.add( birdSet, "bird", 1, 1, 200, 0 )
-- play 1-14, each image every 200 ms, 0 = loop count, which is infinite
local bird1 = sprite.newSprite( birdSet )
bird1.x = 40 -- starting point
bird1.y = 40 -- starting point
bird1.xScale = 0.5 --scale down x
bird1.yScale = 0.5 --scale down y
bird1:prepare("bird") --prepare sprite sequence
bird1:play() --play sprite
localGroup:insert(bird1)
--only local to this group
local killSheet = sprite.newSpriteSheet("explosion.png", 100, 100)
local killSet = sprite.newSpriteSet(killSheet, 1, 9)
sprite.add(killSet, "kill", 1, 9, 200, 1)
local birdCount = 1
local transDirection12
local function transDirection1()
    bird1.xScale = 0.5
transition.to(bird1, {time=math.random(200,500), x = math.random(200,490), y = math.random(10,310), alpha = (math.random(9,100))/100, onComplete = transDirection12})
end
transDirection12 = function()
bird1.xScale = 0.5
    transition.to(bird1, {time= math.random(200,500), x = math.random(200,490), y = math.random(10,310), alpha = (math.random(9,100))/100,  onComplete = transDirection1})
end
transDirection1()
-- local transDirection1 declares what will be used (local function)
-- transDirection1 = function
-- following it are the function qualities
-- declares it will use object/image called bird1 and scales it to .5
-- time = ____ means it will take a certain time, between ____ and ____ to complete the transition
-- x=____ means that is where it will move to on the x axis
-- y=____ means that is where it will move to on the y axis
-- alpha = ___ means the is how transparent it will be
-- onComplete = ________ means that when the action is complete, it will call another function
-- The next function has the same qualities as transDirection1, but the onComplete part calls transDirection1 and they continue to loop
-- transDirection1() declares transDirection1 so the app knows about it and can use it
-- the other trans do not need to be declared because they are part of transDirection1, which is already declared
    --(x, y, size.x, size.y)
    local player = display.newImage( "mk11.png" ) 
    player.x = 240
    player.y = 260
    player.xScale = .5
    player.yScale = .5
    localGroup:insert( player )
    -- add physics to all the objects wanted: (object wanted, "static" or "dynamic")
    physics.addBody(player, "static", {radius=30, isSensor = true}) 
    physics.addBody(bird1, "static", {radius=23})
    local function shoot(inPointX, inPointY)
        -- (start at the x of the player + 10, also start at the y of the player, the radius of the circle is 5)
    local bullet = display.newImage( "bullet2.png" )
    bullet.x = player.x 
    bullet.y = player.y 
    -- add physics to the object, which is the bullet. 
    -- Make the bullet "dynamic" or moving
       physics.addBody(bullet, "dynamic")
    bullet.isFixedRotation = true
    localGroup:insert( bullet )
    local velocity = 300
    local vx, vy = VectorFromAngle(player.rotation, velocity)
    bullet.rotation = player.rotation
    bullet:setLinearVelocity(vx, vy)
    end


    function RotateToTouchPoint(inPointX, inPointY)
        local ang = getAngleDeg(player.x, player.y, inPointX, inPointY)
        player.rotation = ang
    end
    local function ScreenTouchListener(event)
        local phase = event.phase
        if(phase == "began")then
            if(touchPoint.isFocus == false)then
                touchPoint.alpha = 1
                touchPoint.x = event.x
                touchPoint.y = event.y
                display.getCurrentStage():setFocus(touchPoint, event.id)
                touchPoint.isFocus = true
                RotateToTouchPoint(event.x, event.y)
                shoot(event.x, event.y)
            end

            elseif(touchPoint.isFocus)then
                if(phase == "moved")then
                    touchPoint.x = event.x
                    touchPoint.y = event.y
                    RotateToTouchPoint(event.x, event.y)
                elseif(phase == "ended" or phase == "cancelled")then        
                    display.getCurrentStage():setFocus(touchPoint, nil)
                    touchPoint.isFocus = false
                    touchPoint.alpha = 0
                end
            end
            return true
        end 


        local function gotShot (event)
           event.target:removeSelf()
        event.other:removeSelf()    
        local explosion = sprite.newSprite(killSet)
           explosion.x, explosion.y = event.target.x, event.target.y
           explosion:prepare("kill")
           explosion:play()
           localGroup:insert( explosion )
        birdCount = birdCount - 1
        -- when there are no more birds, remove the runtime event listener and perform the
        -- function with a delay of 500 m.s. The function changes the scene to test.lua 
           if "ended" then
               if birdCount == 0 then
            Runtime:removeEventListener("touch", ScreenTouchListener)
               timer.performWithDelay(500, function()
               director:changeScene("mainPage") end, 1)
               end
           end
        end

        bird1:addEventListener("collision", gotShot)
        Runtime:addEventListener("touch", ScreenTouchListener)
---------
-- MUST return a display.newGroup()
    return localGroup
end

任何帮助都是感激的!

错误信息非常清楚——这一行使用的变量sprite:

local bird1 = sprite.birdSheet( birdSet )

有一个nil值,这意味着它没有被初始化或被设置为nil。您需要显示您应该在哪里设置它的前面的代码。


(OP更新后)

我想这行

require "sprite"

应该是

sprite = require "sprite"

你可以在模块教程中阅读更多内容:http://lua-users.org/wiki/ModulesTutorial

最新更新