我创建了这个简单的游戏,其中包括由于重力和用户在屏幕上绘画而使球进入移动的硬币容器的过程。如果球没有进入容器而是从屏幕的底部掉落(触摸对象“ fondale”),则应调用新的场景重播,然后添加后记,您应该可以再次尝试直到成功。
我设法使重播场景被调用,但是在删除侦听器和计时器方面肯定存在一些错误,因为当您第一次单击重试按钮后再次尝试播放时,会发生一些错误的事情。
非常感谢您!
答案 0 :(得分:0)
很抱歉,您的答案很大。我对您的代码进行了缩进,无法分辨添加的内容和未添加的内容。
在replay.lua
中,我将composer.removeScene("replay")
移到了function scene:hide()
中。在retry:removeEventListener("tap", restart)
之前调用移除场景,导致retry
为nil
。
我在game.lua
中做了类似的更改
不确定是否知道这一点,但是composer.gotoScene("scene name")
将调用scene:hide()
,因此您可以删除事件侦听器,然后删除场景!
p.s我很讨厌你的游戏-_-
Game.lua
local composer = require( "composer" )
local scene = composer.newScene()
-- -----------------------------------------------------------------------------------
-- Code outside of the scene event functions below will only be executed ONCE unless
-- the scene is removed entirely (not recycled) via "composer.removeScene()"
-- -----------------------------------------------------------------------------------
local physics = require( "physics" )
physics.start()
physics.setGravity(0, 5 )
physics.setDrawMode( "normal" )
local left_side_piece
local center_piece
local right_side_piece
local obstacle
local rotation
local bottomSide
local leftSide
local rightSide
local lineCollision
local speed
local distance
local ball
--local fg
local fg = display.newGroup()
local line
local x
local y
local function goToreplay()
local options =
{
effect = "fromLeft",
time = 1000,
}
composer.gotoScene("replay",options)
end
local function moveContainer()
speed = math.round(math.random(1700,2000))
distance = math.round(math.random(50,display.contentWidth-50))
transition.to(bottomSide,{time = speed, x = distance, onComplete = moveContainer})
transition.to(leftSide,{time = speed, x = distance-25})
transition.to(rightSide,{time = speed, x = distance+25})
transition.to(lineCollision,{time = speed, x = distance})
end
function bodyAwake()
if (ball.isAwake== false) then
local myText = display.newText( "RITENTA", 120, 30, native.systemFont, 16 )
myText:setFillColor( 1, 0, 0 )
setWorldChange = true
transition.cancel()
physics.pause()
end
end
function draw(event)
if event.phase=="began" then
x = event.x
y = event.y
elseif event.phase=="moved" then
line = display.newLine(fg, x,y,event.x,event.y)
physics.addBody( line, "static", { radius=4 })
line.strokeWidth = 3
x = event.x
y = event.y
elseif event.phase=="ended" then
physics.start()
body = timer.performWithDelay( 3000, bodyAwake,6 )
end
end
local function onLocalCollision( self, event )
if ( event.phase == "began" ) then
if ( self.myName == "sensore" and event.other.myName== "ball1" ) then
local myText = display.newText( "PALLA ENTRATA", 120, 30, native.systemFont, 16 )
myText:setFillColor( 1, 0, 0 )
setWorldChange = true
transition.cancel()
elseif ( self.myName == "fondale" and event.other.myName== "ball1" ) then
ritenta = display.newText( "RITENTA", 120, 30, native.systemFont, 16 )
ritenta:setFillColor( 1, 0, 0 )
setWorldChange = true
transition.cancel()
physics.pause()
timer.performWithDelay(1000, goToreplay)
end
end
end
local function removeLine()
if (setWorldChange == true) then
for i = fg.numChildren, 1, -1 do
fg[i]:removeSelf()
fg[1] = nil
end
setWorldChange = false
end
end
local function updateBall()
leftSide.x = bottomSide.x-25
rightSide.x = bottomSide.x+25
lineCollision.x = bottomSide.x
end
-- -----------------------------------------------------------------------------------
-- Scene event functions
-- -----------------------------------------------------------------------------------
-- create()
function scene:create( event )
local sceneGroup = self.view
-- Code here runs when the scene is first created but has not yet appeared on screen
physics.pause()
-- local fg = display.newGroup()
sceneGroup:insert( fg )
left_side_piece = display.newRect( 0-5, display.contentHeight/2, 660, 10 )
physics.addBody( left_side_piece, "static" )
left_side_piece.rotation = 90
center_piece = display.newRect( display.contentCenterX, display.contentHeight+160, 400, 120 )
physics.addBody( center_piece, "static" )
center_piece.myName="fondale" --se la pallina collide con fondo, si va a pagina di replay
right_side_piece = display.newRect( display.contentWidth+5, display.contentHeight/2, 660, 10 )
physics.addBody( right_side_piece, "static" )
right_side_piece.rotation = -90
obstacle = display.newRect( 150,300,50,50 )
obstacle:setFillColor( 222.0/255.0, 184.0/255.0, 135.0/255.0 )
physics.addBody( obstacle, "static" )
obstacle.gravityScale = 0
rotation = transition.to(obstacle, {time=3000, rotation=-360, iterations=-1} )
bottomSide = display.newRect( 160, display.contentHeight, 50, 3 )
physics.addBody( bottomSide, "static",{ density=1.0, friction=0.4, bounce=0.2} )
sceneGroup:insert(bottomSide )
leftSide = display.newRect( 134, display.contentHeight-24, 50, 3 )
physics.addBody( leftSide, "static" )
leftSide.rotation = -90
sceneGroup:insert( leftSide )
rightSide = display.newRect( 185, display.contentHeight-24, 50, 3 )
physics.addBody( rightSide, "static" )
rightSide.rotation = -90
sceneGroup:insert( rightSide )
lineCollision = display.newRect( 160, display.contentHeight-10, 35, 2 )
physics.addBody( lineCollision, "static", {isSensor=true} )
lineCollision.myName = "sensore"
ball = display.newCircle( display.contentWidth/2, 0, 8 )
ball:setFillColor( 1,0,0 )
physics.addBody( ball, "dynamic", { density=1.0, friction=0.4, bounce=0, radius=8 } )
ball.myName= "ball1"
lineCollision.collision = onLocalCollision
lineCollision:addEventListener( "collision" )
center_piece.collision = onLocalCollision
center_piece:addEventListener( "collision" )
end
-- show()
function scene:show( event )
local sceneGroup = self.view
local phase = event.phase
if ( phase == "will" ) then
-- Code here runs when the scene is still off screen (but is about to come on screen)
elseif ( phase == "did" ) then
-- Code here runs when the scene is entirely on screen
physics.pause()
moveContainer()
Runtime:addEventListener("touch", draw)
Runtime:addEventListener("enterFrame", removeLine)
Runtime:addEventListener("enterFrame", updateBall)
bodyAwake()
end
end
-- hide()
function scene:hide( event )
local sceneGroup = self.view
local phase = event.phase
if ( phase == "will" ) then
-- Code here runs when the scene is on screen (but is about to go off screen)
ritenta:removeSelf()
obstacle:removeSelf()
lineCollision:removeEventListener("collision")
lineCollision:removeSelf()
center_piece:removeEventListener("collision")
lineCollision:removeSelf()
Runtime:removeEventListener("touch", draw)
Runtime:removeEventListener("enterFrame", removeLine)
Runtime:removeEventListener("enterFrame", updateBall)
composer.removeScene("game")
elseif ( phase == "did" ) then
-- Code here runs immediately after the scene goes entirely off screen
physics.pause()
end
end
-- destroy()
function scene:destroy( event )
local sceneGroup = self.view
-- Code here runs prior to the removal of scene's view
physics.stop()
end
-- -----------------------------------------------------------------------------------
-- Scene event function listeners
-- -----------------------------------------------------------------------------------
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
-- -----------------------------------------------------------------------------------
return scene
replay.lua
-----------------------------------------------------------------------------------------
--
-- replay.lua defines the replay scene
--
-----------------------------------------------------------------------------------------
local composer = require( "composer" )
local scene = composer.newScene()
-- -----------------------------------------------------------------------------------
-- Code outside of the scene event functions below will only be executed ONCE unless
-- the scene is removed entirely (not recycled) via "composer.removeScene()"
-- -----------------------------------------------------------------------------------
-- -----------------------------------------------------------------------------------
-- Scene event functions
-- -----------------------------------------------------------------------------------
local background -- variable that stores the background image
local retry -- variable that stores the retry image button
-- create()
function scene:create( event )
local sceneGroup = self.view
background = display.newImageRect("backGrass1.png",1920,1080)
-- load the retry.png image
retry = display.newImageRect("retry.png",200,200)
sceneGroup:insert(background)
sceneGroup:insert(retry)
end
-- restart is a table listener associated with the retry button
-- which is executed when the retry button is tapped
local function restart()
-- go to the game scene
composer.gotoScene("game")
return true
end
-- show()
function scene:show( event )
local sceneGroup = self.view
local phase = event.phase
if ( phase == "will" ) then
-- place the retry object at the center of the display
background.x = display.contentCenterX
background.y = display.contentCenterY
-- place the retry object at the center of the display
retry.x = display.contentCenterX
retry.y = display.contentCenterY
elseif ( phase == "did" ) then
-- activate the tap listener
retry.tap = restart
retry:addEventListener("tap", restart)
end
end
-- hide()
function scene:hide( event )
local sceneGroup = self.view
local phase = event.phase
if ( phase == "will" ) then
-- Code here runs when the scene is on screen (but is about to go off screen)
-- Remove the tap listener associated with the retry button
retry:removeEventListener("tap", restart)
elseif ( phase == "did" ) then
-- Code here runs immediately after the scene goes entirely off screen
composer.removeScene("replay")
end
end
-- destroy()
function scene:destroy( event )
local sceneGroup = self.view
-- Code here runs prior to the removal of scene's view
end
-- -----------------------------------------------------------------------------------
-- Scene event function listeners
-- -----------------------------------------------------------------------------------
scene:addEventListener( "create", scene )
scene:addEventListener( "show", scene )
scene:addEventListener( "hide", scene )
scene:addEventListener( "destroy", scene )
-- -----------------------------------------------------------------------------------
return scene