2014-04-08 19 views
0

코로나에서 jetpack joyride 개념 게임을 만들려고합니다. 우선 다른 장면과는 달리 장면을 변경하면 이전 장면이 자동으로 제거되고 코로나에서는 각 장면과 대상을 제거해야합니다.게임 속도가 다시 시작될 때마다 게임 속도가 증가합니다. - 코로나

일주일이 지나면 마침내 장면을 변경하는 동안 개체를 제거 할 수 있었지만 지금은 새로운 문제가 발생했습니다. 매번 장면을 변경하고 gameScreen으로 돌아올 때마다 레이저 및 미사일의 속도가 매번 증가합니다 (어쩌면 두 번?). 어떻게 속도를 재설정 할 수 있습니까? 심지어 다른 "gameStatus"변수를 추가하여 이벤트 리스너를 제거하고 인쇄하려고했지만 게임 상태가 실제로 "종료 됨"으로 반환 된 적이 없으며 항상 "실행 중"이었습니다. 모든


편집 일어나는 경우 여기 gameScene 화면 : 3 개체가 이미 만 처음 3 객체가 빠르고 넷째로부터 정상으로 보이는 화면을 다시로드 한 후 다음 산란 한 경우 난 그냥 예를 들어, 뭔가를 발견했습니다.

local composer = require("composer") 
local scene = composer.newScene() 
local physics = require("physics") 
physics.start() 

local image, text1 

local function onSceneTouch(self, event) 
    if event.phase == "began" then  
     composer.gotoScene("startScreen", "fade", 400 )  
     return true 
    end 
end 

function scene:create(event) 
    local sceneGroup = self.view 

    -- Variable 
    --------------------------------------- 
    sW = display.contentWidth 
    sH = display.contentHeight 

    -- trying to reset gameStatus on restart 
    gameStatus = "ended" 
    gameStatus = "running" 


    -------------------------------------------------------- 
    backgroundTiles = {} 

    drawBackground = function() 
     cieling = display.newRect(0, 0, 2 * sW, sH * 0.05) 
     physics.addBody(cieling, "static", { density=0, friction=0, bounce=0 }) 
     cieling.x, cieling.y = cieling.contentWidth/4, cieling.contentHeight * 0.25 
     cieling.alpha = 0 
     cieling.name = "ceiling" 

     ground = display.newRect(0, sH, 2 * sW, sH * 0.05) 
     physics.addBody(ground, "static", { density=3, friction=1, bounce=0.1 }) 
     ground.x, ground.y = ground.contentWidth/4, sH - ground.contentHeight * 0.25 
     ground.alpha = 0 
     ground.name = "ground" 

    end 

    drawBackground() 
    -------------------------------------------------------- 


    -------------------------------------------------------- 
    drawBird = function() 
     bird = display.newImageRect("a/img/hero/hero.png", 80, 58) 
     bird.x, bird.y = 0 - sW * 0.1, ground.y - ground.contentHeight - 10 
     bird.isFixedRotation = true; bird.angularVelocity = 0; 
     physics.addBody(bird, { density=1, friction=0.5, bounce=0.1 }) 
     bird.name = "bird" 
     sceneGroup:insert(bird) 

     bird:addEventListener("collision", onCollision) 
    end 

    coinsCollected, tokensCollected = 0, 0 

    birdFlight = function() 
     if (gameStatus == "running") then 
      transition.to(bird, { 
       y = bird.y - 75, 
       transition = easing.outQuad, 
       onComplete = function() end 
      }) 
      function birdFlight() 
       --transition.to(bird, { rotation=-45, time=300 }) 
      end 
      birdFlight() 
      function birdFall() 
       --transition.to(bird, { rotation=90, time=300 }) 
      end 
      timer.performWithDelay(700, birdFall, 1) 
     end 
    end 
    display.currentStage:addEventListener("tap", birdFlight) 

    function onCollision(event) 
     if event.phase == "began" then 
      if event.other.name == "coin" then 
       coinsCollected = coinsCollected + 1 
      end 
      if event.other.name == "token" then 
       tokensCollected = tokensCollected + 1 
      end 
      if event.other.name == "missile" or event.other.name == "laser" or event.other.name == "rod" then 
       -- game ended 
      end 
     end 
    end 

    drawBird() 

    function atFrame(event) 
     if gameStatus == "running" then 
      bird.x,bird.y = sW/3,bird.y + 9 
      if (bird.y > sH - 70) then bird.y = sH - 70 end 
      if (gameStatus == "ended") then bird.y = bird.y + 15 end 
     end 
    end 
    Runtime:addEventListener("enterFrame", atFrame) 

    -------------------------------------------------------- 



    -------------------------------------------------------- 
    missile, missileAlert, missileMoving = {}, {}, {} 

    function removeMissile(i) 
     local onEnterFrame = function(event) 
      if missile[i] ~= nil and missile[i].x ~= nil and gameStatus == "running" then 
       if missile[i].x < -100 then 
        display.remove(missile[i]) 
        missile[i] = nil 
       end 
      end 
     end 
     Runtime:addEventListener("enterFrame", onEnterFrame) 

     print(gameStatus) 

     if gameStatus == "ended" then 
      Runtime:removeEventListener("enterFrame", onEnterFrame) 
     end 
    end 


    function flyMissile(i) 
     local onEnterFrame = function(event) 
      if missile[i] ~= nil and missile[i].x ~= nil and missile[i].y ~= nil and gameStatus == "running" then 
       if missileMoving[i] == true then 
        missile[i].y = bird.y 
       end 
       missile[i].x = missile[i].x - 5 
       if missileAlert[i] ~= nil then 
        if missileMoving[i] == true then 
         missileAlert[i].y = bird.y 
        end     
        if missile[i].x < sW then 
         display.remove(missileAlert[i]) 
         missileAlert[i] = nil 
        end     
       end 
      end 
     end 
     Runtime:addEventListener("enterFrame", onEnterFrame) 

     print(gameStatus) 

     if gameStatus == "ended" then 
      Runtime:removeEventListener("enterFrame", onEnterFrame) 
     end 
    end 


    function holdMissile(i) 
     local onEnterFrame = function(event) 
      if missile[i] ~= nil and missile[i].x ~= nil and gameStatus == "running" then 
       if missile[i].x < sW * 1.5 then 
        if missileAlert[i] ~= nil then 
         missileAlert[i]:setFillColor(1,1,0) 
        end 
        missileMoving[i] = false 
       end 
      end 
     end 
     Runtime:addEventListener("enterFrame", onEnterFrame) 

     print(gameStatus) 

     if gameStatus == "ended" then 
      Runtime:removeEventListener("enterFrame", onEnterFrame) 
     end 
    end 


    function spawnMissile(i) 

     missile[i] = display.newRect(sW*2, sH/2, 80, 80) 
     missileAlert[i] = display.newRect(sW-80, bird.y, 80, 80) 
     physics.addBody(missile[i],"kinematic",{isSensor=true}) 
     missile[i].name = "missile" 
     sceneGroup:insert(missile[i]) 
     sceneGroup:insert(missileAlert[i]) 

     missileMoving[i] = true 

     flyMissile(i) 
     removeMissile(i) 
     holdMissile(i) 

    end 

    spawnMissile(1) 
    -------------------------------------------------------- 


    -------------------------------------------------------- 
    laser = {} 

    function moveAndRemovelaser(i) 
     local onEnterFrame = function(event) 
      if laser[i] ~= nil and laser[i].x ~= nil and gameStatus == "running" then    
       laser[i].x = laser[i].x - 5 
       if laser[i].x < 0 - sW/2 then 
        display.remove(laser[i]) 
        laser[i] = nil 
       end 
      end 
     end 
     Runtime:addEventListener("enterFrame", onEnterFrame) 

     print(gameStatus) 

     if gameStatus == "ended" then 
      Runtime:removeEventListener("enterFrame", onEnterFrame) 
     end 
    end 

    function spawnlaser(i) 

     laserSize = math.random(1,2) 
     laserPosition = math.random(1,3) 
     laserRotation = math.random(1,4) 

     if laserSize == 1 then 
      laser[i] = display.newRect(100,100,50,sH/3) 
     else 
      laser[i] = display.newRect(100,100,50,sH/2) 
     end 

     sceneGroup:insert(laser[i]) 

     laser[i].x = sW * 2 
     laser[i].y = sH/2 
     laser[i].name = "laser" 

     if laserPosition == 1 and laserRotation ~= 4 then 
      laser[i].y = sH * 0.05 + 12 
      laser[i].anchorY = 0 
     elseif laserPosition == 3 and laserRotation ~= 4 then 
      laser[i].y = sH * 0.95 - 12 
      laser[i].anchorY = 1 
     end 

     if laserPosition == 1 and laserRotation == 4 then 
      laser[i].y = sH * 0.05 + laser[i].contentHeight/2 
     elseif laserPosition == 3 and laserRotation == 4 then 
      laser[i].y = sH * 0.95 - laser[i].contentHeight/2 
     end 

     if laserRotation == 1 then 
      laser[i].rotation = -45 
     elseif laserRotation == 2 then 
      laser[i].rotation = 0 
     elseif laserRotation == 3 then 
      laser[i].rotation = 45 
     elseif laserRotation == 4 then 
      local onEnterFrame = function(event) 
       if laser[i] ~= nil and laser[i].rotation ~= nil then 
        laser[i].rotation = laser[i].rotation + 5 
       end 
      end 
      Runtime:addEventListener("enterFrame", onEnterFrame) 
     end 

     laser[i]:setFillColor(1,1,0) 
     physics.addBody(laser[i],"kinematic",{isSensor=true}) 

     moveAndRemovelaser(i) 
    end 

    spawnlaser(1) 
    -------------------------------------------------------- 




    image = display.newRect (100,100,100,100) 
    image.x = display.contentCenterX 
    image.y = display.contentCenterY 

    sceneGroup:insert(image) 

    image.touch = onSceneTouch 

    text1 = display.newText("Game Screen", 0, 0, native.systemFontBold, 24) 
    text1:setFillColor(255) 
    text1.x, text1.y = display.contentWidth * 0.5, 50 
    sceneGroup:insert(text1) 
end 

function scene:show(event) 

    local phase = event.phase 

    if "will" == phase then 
     gameStatus = "ended" 
    end 

    if "did" == phase then 
     print("4") 
     composer.removeScene("startScreen") 
     image:addEventListener("touch", image) 
     gameStatus = "running" 
    end 

end 

function scene:hide(event) 
    local phase = event.phase 
    if "will" == phase then 
     print("5") 
     gameStatus = "ended" 
     image:removeEventListener("touch", image) 
     Runtime:removeEventListener("enterFrame", onEnterFrame) 
    end 
end 

function scene:destroy(event) 
    print("6") 
end 


scene:addEventListener("create", scene) 
scene:addEventListener("show", scene) 
scene:addEventListener("hide", scene) 
scene:addEventListener("destroy", scene) 


return scene 

답변

0

그래서 내가 함수를 만들고 그 함수의 모든 removeEventListeners을 가하고 결국 게임이 종료되면 그 함수를 호출. 나중에 참조 할 수 있도록 항상 화면의 아무 곳에서나 만든 모든 타이머 및 이벤트 수신기의 목록을 유지하고 게임을 종료 할 때 함께 모두 제거하십시오.

1

이벤트 수신기를 두 번 등록하므로이 문제가 발생합니다.

장면을 입력하고 종료 할 때만 추가하고 제거해야합니다.

  • :

    내 조언은 당신이이 지침을 준수하도록 코드를 다시 구성하고 시도하려고한다는 것입니다 숨기기() : (파괴) 및 현장 : 게임의 개체를 제거 할 수있는 적절한 장소는 장면 scene : create() : 장면을 처음 사용할 때 발생합니다. 여기에 게임 개체를 만들고 싶습니다. 이 이벤트는 장면이 파괴 된 다음 다시 사용되지 않는 한 한 번만 발생합니다.

  • scene : show() : 모든 이벤트 리스너를 여기 (터치 등)에 등록하고 게임을 설정하고 싶습니다. 이 함수는 장면이 표시 될 때마다 호출됩니다. 여기에 등록 된 모든 이벤트 리스너는 이중 트리거링을 방지하기 위해 등록 해제되어야합니다.

  • scene : hide () : 모든 이벤트 리스너를 여기에서 등록 해제하려고합니다. 이렇게하면 다음 장면에서 이전 장면의 청취자도 이벤트를 트리거하지 않습니다.

  • scene : destroy() : 여기서 모든 게임 개체 (이미지, 텍스트, 위젯 등)를 제거하고 싶습니다. 그 장면은 더 이상 필요 없으며 모든 것은 깨끗하게해야합니다.

더 나은 장면의 작품 나는이 문서를 읽어 보시기 바랍니다 방법을 이해하려면 http://coronalabs.com/blog/2014/01/21/introducing-the-composer-api-plus-tutorial/

+0

그게 무슨 소리 야? 자동으로 제거됩니다.어쨌든 이제는 장면을 이해합니다 : 오버레이와 장면이있을 때 숨기기가 사용됩니다. 화면을 완전히 바꿀 때 파괴가 사용되므로 장면을 이동합니다. 코드를 장면에 숨기십시오. 코드를 드롭 보관함이나 다른 것으로 공유하길 원하십니까? –

관련 문제