2015-09-09 1 views
0

Я пытаюсь создать простейшее игровое приложение и постоянно сталкиваюсь с этой проблемой. Я прекратил программирование в Lua в течение нескольких лет, поэтому не помню, как это исправить. Во всяком случае, мой код выглядит следующим образом:Получение «Попытка проиндексировать глобальный« спрайт »(значение nil)» в Lua

EDIT: Вот и весь файл. Все еще пытаюсь выяснить форматирование переполнения стека. Ошибка возникает на линии 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 

Любая помощь приветствуется!

ответ

2

Сообщение об ошибке совершенно ясно - переменная sprite используется на этой линии:

local bird1 = sprite.birdSheet(birdSet) 

имеет нулевую ценность, то есть он не был инициализирован или был установлен в ноль. Вам нужно показать более ранний код, где вы должны его настроить.


(После обновления ОП)

Я думаю, что эта линия

require "sprite" 

должно быть на самом деле

sprite = require "sprite" 

Вы можете прочитать больше модулей учебник здесь: http://lua-users.org/wiki/ModulesTutorial