陷入我正在玩的代码中。我正在运行时间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
答案 0 :(得分:0)
首先,self
是保留字,因此您可能不希望在local
中将其声明为onGlobalCollision()
。例如,obj1
和obj2
会这样做。
在执行lanes[i]:removeEventListener("touch", moveCar)
的循环中,表lanes[i]
中定义了什么(如果有的话) ?你可以通过以下方式找到:
for k,v in pairs(lanes[i]) do
print(k,v)
end