碰撞时电晕运行时错误

时间:2017-04-05 12:05:56

标签: corona game-physics

陷入我正在玩的代码中。我正在运行时间scene_game.lua:290:尝试调用方法'removeEventListener'(一个零值)错误。 290指的是代码的这一部分

for i=1,#lanes do
                lanes[i]:removeEventListener("touch", moveCar)
            end

有趣的是,

中的碰撞时不会调用此错误
elseif (self=="enemy" and other=="player") then

相反,它仅在下面显示的这部分代码被执行时被调用。

elseif (self=="player" and other=="enemy") then

以下提供代码的整个部分供您参考。请帮助!

function scene:create( event )

    -- Initialize the scene here.
    -- Example: add display objects to "sceneGroup", add touch listeners, etc.
    local sceneGroup = self.view

    -- The following variables are known as forward declares. We'll create some for the player, enemy, lanes and establish default values.
    local lanes = {} -- create a table called lanes
    local playerCar -- a variable for the player car
    local playerCar1 -- a variable for the player car
    local sprite
    local laneID = 1 -- a variable for the land id
    local enemyCars = {} -- a table to hold the enemy cars
    local enemyCounter = 1 -- start the enemy counter at 1 to keep track of the enemy cars

    local sendEnemyFrequency = 2500 -- defines how often to send enemy cars
    local tmrToSendCars -- a variable to hold a reference to the timer of sending cars    

    local playerScore = 0 -- start the player score at 0
    local playerScoreText -- an object to hold the score text object

    -- This function will increment the player score by 1. This function is called when the transition for the enemy car is complete and is off screen.

    local sheetInfo = require("zo")
        local myImageSheet = graphics.newImageSheet( "zo.png", sheetInfo:getSheet() )


local sequenceData = {
    {
    name="walk",                                  -- name of the animation
    sheet=myImageSheet,                           -- the image sheet
    start=sheetInfo:getFrameIndex("1"), -- first frame
    count=4,                                      -- number of frames
    time=700,                                    -- speed
    loopCount=0                                   -- repeat
    }
}

    local sheetInfo2 = require("opo")
        local myImageSheet2 = graphics.newImageSheet( "opo.png", sheetInfo2:getSheet() )


local sequenceData2 = {
    {
    name="walk2",                                  -- name of the animation
    sheet=myImageSheet,                           -- the image sheet
    start=sheetInfo:getFrameIndex("1"), -- first frame
    count=4,                                      -- number of frames
    time=700,                                    -- speed
    loopCount=0                                   -- repeat
    }
}





    chk=0
        function messenger2(text)
        if chk==0 then
g4A = display.newGroup()
halt1= display.newRect( -30 , 150, 50+100*9, 44*2+30-65 )
halt1.alpha=.85
halt1.anchorX=0
halt1.anchorY=0
halt1:setFillColor( .2, .2, .2 ,.95)
halt1:setStrokeColor( .8, .8 ,.8 )
halt1.strokeWidth = .51
audio.play(levelup)
halt1text = display.newText( text, 235, 44*3+185-140,native.systemFont, 26 )
halt1text:setFillColor( .8, .8, .8 )

 g4A:insert( halt1 ) 
  g4A:insert( halt1text )

   transition.fadeOut( g4A, { time=2500, transition=easing.inCirc  } )
    sceneGroup:insert(g4A) 
end
end


    local function incrementScore()
        playerScore = playerScore + 1 -- add playerScore by 1
        playerScoreText.text = "Score: "..playerScore -- update the on screen text



        if playerScore>bestscore then
    bestscore=playerScore

    messenger2("New high score reached")
    chk=1
     loadsave.saveTable(bestscore, "Bestscorenow.json", system.DocumentsDirectory)
    end




    end

    -- moveCar will respond to the touch event on the lanes
    local function moveCar(event)

        if(event.phase == "ended") then 

            laneID = event.target.id -- grab the lane id which will be 1, 2, or 3
            transition.to(playerCar, {x=lanes[laneID].x,time=50}) -- move the player car to the appropriate lane
            transition.to(playerCar1, {x=lanes[laneID].x,time=50}) -- move the player car to the appropriate lane
            transition.to(sprite, {x=lanes[laneID].x,time=50}) -- move the player car to the appropriate lane

audio.play(movingck)

            return true -- to indicate a successful touch event, return true
        end
    end





    -- sendEnemyCar is where the magic happens. This function will send enemy cars from the top of the screen to the bottom of the screen.
    local function sendEnemyCar()
    if(enemyCounter%7 == 0) then
    enemyCars[enemyCounter] =   display.newImageRect(sceneGroup, "tr.png", 20, 20)
    enemyCars[enemyCounter].x = lanes[math.random(1,#lanes)].x -- place the car on a random lane
            if(math.random(1,2) == 1) then enemyCars[enemyCounter].x = lanes[laneID].x; end -- 50% of the time, place the enemy car on the player car lane. 
        enemyCars[enemyCounter].y = -125 -- place the enemy off screen at the top
        enemyCars[enemyCounter]:scale(1.8,-1.65) -- rotate the cars so they are facing down
        physics.addBody(enemyCars[enemyCounter]) -- add a physics body to enemy cars
        enemyCars[enemyCounter].bodyType = "kinematic" -- make the bodies kinematic
        enemyCars[enemyCounter].id = "trophy" -- id

        transition.to(enemyCars[enemyCounter], {y=display.contentHeight+enemyCars[enemyCounter].height+20, time=math.random(2250,3000), onComplete=function(self) display.remove(self); incrementScore(); end}) -- a transition that moves the enemy car towards the bottom of the screen. On completion, the enemy car object is removed from the game.

        enemyCounter = enemyCounter + 1 -- increase enemy counter by one for tracking
        if(enemyCounter%2 == 0) then -- every other car, increase the speed of enemy frequency
            sendEnemyFrequency = sendEnemyFrequency - 200 -- deduct the frequency by 200ms
            if(sendEnemyFrequency < 850) then sendEnemyFrequency = 850; end -- cap the send enemy frequency to 800
            timer.cancel(tmrToSendCars) -- cancel the timer of sending cars
            tmrToSendCars = timer.performWithDelay(sendEnemyFrequency, sendEnemyCar, 0) -- recreate the time to send cars with update frequency
        end
    else
        enemyCars[enemyCounter] =   display.newSprite(sceneGroup, myImageSheet2, sequenceData2 )
enemyCars[enemyCounter]:setSequence("walk2")
enemyCars[enemyCounter]:play()

        enemyCars[enemyCounter].x = lanes[math.random(1,#lanes)].x -- place the car on a random lane
            if(math.random(1,2) == 1) then enemyCars[enemyCounter].x = lanes[laneID].x; end -- 50% of the time, place the enemy car on the player car lane. 
        enemyCars[enemyCounter].y = -125 -- place the enemy off screen at the top
        enemyCars[enemyCounter]:scale(1.8,-1.65) -- rotate the cars so they are facing down
        local offsetRectParams = { halfWidth=20, halfHeight=20, x=0, y=60, angle=0 }

        physics.addBody(enemyCars[enemyCounter], { box=offsetRectParams } ) -- add a physics body to enemy cars
        enemyCars[enemyCounter].bodyType = "kinematic" -- make the bodies kinematic
        enemyCars[enemyCounter].id = "enemy" -- id

        transition.to(enemyCars[enemyCounter], {y=display.contentHeight+enemyCars[enemyCounter].height+20, time=math.random(2250,3000), onComplete=function(self) display.remove(self); incrementScore(); end}) -- a transition that moves the enemy car towards the bottom of the screen. On completion, the enemy car object is removed from the game.

        enemyCounter = enemyCounter + 1 -- increase enemy counter by one for tracking
        if(enemyCounter%2 == 0) then -- every other car, increase the speed of enemy frequency
            sendEnemyFrequency = sendEnemyFrequency - 200 -- deduct the frequency by 200ms
            if(sendEnemyFrequency < 850) then sendEnemyFrequency = 850; end -- cap the send enemy frequency to 800
            timer.cancel(tmrToSendCars) -- cancel the timer of sending cars
            tmrToSendCars = timer.performWithDelay(sendEnemyFrequency, sendEnemyCar, 0) -- recreate the time to send cars with update frequency
        end

    end
    end

    -- Allow the player to return to the menu
    local function onPlayAgainTouch()

        composer.gotoScene("scene_menu", "fade") -- move player to menu
    end


    local function playersdead()

         audio.play(deads)
    print(deads)
            -- stop the game
            transition.pause()
            timer.cancel(tmrToSendCars)
            physics.pause()
              playerCar1.isVisible = true
      playerCar.alpha = 0
      sprite.alpha = 0



            -- remove event listeners from all lanes
            for i=1,#lanes do
                lanes[i]:removeEventListener("touch", moveCar)
            end
Runtime:removeEventListener( "collision",onGlobalCollision )
            local gameOverBackground = display.newRect(sceneGroup, 0, 0, display.actualContentWidth, display.actualContentHeight) -- display an opaque background graphic for some game over polish
                gameOverBackground.x = display.contentCenterX
                gameOverBackground.y = display.contentCenterY
                gameOverBackground:setFillColor(0)
                gameOverBackground.alpha = 0.5

            -- Create a text object that will display game over text
            local gameOverText = display.newText( sceneGroup, "Game Over!", 100, 200, native.systemFontBold, 36 )
            gameOverText.x = display.contentCenterX
            gameOverText.y = 150
            gameOverText:setFillColor( 1, 1, 1 )   

 wpmaGlobalAdmob.showAdmobInterstitialAd() 
wpmaGlobalAdmob.loadAdmobInterstitialAd()           

            -- create a button that allows the player to return to the
            local playAgain = widget.newButton {
                width = 220,
                height = 100,
                defaultFile = "images/btn-blank.png",
                overFile = "images/btn-blank.png",        
                label = "Menu",
                font = system.defaultFontBold,
                fontSize = 32,
                labelColor = { default={ 0, 0, 0 }, over={ 0, 0, 0, 0.5 } },
                onEvent = onPlayAgainTouch
            }
            playAgain.x = display.contentCenterX
            playAgain.y = gameOverText.y + 100
            sceneGroup:insert(playAgain)      

    end

    local function trophyz()
      audio.play(uplevel)

    end


    -- This is the global collision scene. There are several ways to handle collisions and this is only one method. I felt this was the easiest for learning purposes.
    local function onGlobalCollision(event)
        if(event.phase == "began") then -- when the enemy car collides into the player car, this if/then statement will be true        
local self = event.object2.id
local other = event.object1.id

        print_r( self)       --the first object in the collision
  print_r( other )       --the second object in the collision
 --   print_r( event.element1 )      --the element (number) of the first object which was hit in the collision
 --   print_r( event.element2 )               

 if (self=="player" and other=="trophy") then

 event.object1:removeSelf()
trophyz()
 elseif (self=="trophy" and other=="player") then

  event.object2:removeSelf()
 trophyz()
 elseif (self=="player" and other=="enemy") then
  playersdead()
 print("Someting screwy here")
 elseif (self=="enemy" and other=="player") then
  playersdead()


    --display.remove(self)
 else
 print("U SHOULD NOT BE HERE")

        end





         --END COLLISION  
    end
        end


    local background = display.newImageRect(sceneGroup, "images/background.png", 475, 713) -- create the background image object
        background.x = display.contentCenterX -- place the graphic in the center of the x-axis
        background.y = display.contentCenterY -- place the graphic in the center of the y-axis

    for i=1,3 do -- loop 3 times to create 3 lanes for our game
        lanes[i] = display.newImageRect(sceneGroup, "images/lane.png", 79, 713)
            lanes[i].x = (display.contentCenterX - 79*2) + (i*80)
            lanes[i].y = display.contentCenterY
            lanes[i].id = i
            lanes[i]:addEventListener("touch", moveCar) -- add an event listener to the lanes that will respond to touch events.
    end

    playerScoreText = display.newText(sceneGroup, "Score: "..playerScore, 0, 0, native.systemFont, 36) -- Create a text object that will display the player score
        playerScoreText.x = display.contentCenterX
        playerScoreText.y = 25






    playerCar = display.newImageRect(sceneGroup, "images/playerCar.png", 60, 60) -- create the player car image object
        playerCar.anchorY = 1 -- set the anchor point to 1 which is the bottom of the graphic
        playerCar.x = lanes[1].x -- put the player car on the first lane
        playerCar.y = display.contentHeight-70 -- place the car at the bottom of the screen
        physics.addBody(playerCar) -- add a physics body to the car
        playerCar.bodyType = "dynamic" -- make the car a dynamic body type
            playerCar.id = "player" 

        playerCar1 = display.newImageRect(sceneGroup, "images/playerCar11.png", 50, 100) -- create the player car image object
        playerCar1.anchorY = 1 -- set the anchor point to 1 which is the bottom of the graphic
        playerCar1.x = lanes[1].x -- put the player car on the first lane
        playerCar1.y = display.contentHeight -- place the car at the bottom of the screen
     -- id

      --    physics.addBody(playerCar1) -- add a physics body to the car
      --    playerCar1.bodyType = "dynamic" -- make the car a dynamic body type



sprite = display.newSprite( myImageSheet, sequenceData )
sprite:scale( 1.6, 1.6)
sprite.anchorY = 1
sprite:setSequence("walk")
sprite:play()

sprite.x = lanes[1].x -- put the player car on the first lane
        sprite.y = display.contentHeight -- place the car at the bottom of the screen




      playerCar1.isVisible = false
      playerCar.isVisible = true

        playerCar.alpha = 0

    tmrToSendCars = timer.performWithDelay(sendEnemyFrequency, sendEnemyCar, 0) -- start a timer to send cards. A 0 means run forever
    Runtime:addEventListener( "collision", onGlobalCollision ) -- create a global event listener to listen for any collision.

end

1 个答案:

答案 0 :(得分:0)

首先,self是保留字,因此您可能不希望在local中将其声明为onGlobalCollision()。例如,obj1obj2会这样做。

在执行lanes[i]:removeEventListener("touch", moveCar)的循环中,表lanes[i]中定义了什么(如果有的话) ?你可以通过以下方式找到:

for k,v in pairs(lanes[i]) do
    print(k,v)
end