尽管被重新定位,我的角色会从屏幕上滑落,但我不确定为什么

时间:2016-08-06 15:52:36

标签: lua collision-detection corona physics

我正在创建一个使用Corona练习编码的2D游戏,我遇到了问题。游戏中其中一个敌人的背部形状像一个颠簸的滑道(有点像),当我的角色击中敌人的背部时,它开始滑离屏幕。当敌人被击中时,游戏切换到另一个屏幕并切换回来。

https://www.youtube.com/watch?v=xGoZ1jEG0YA&feature=youtu.be

这是一个显示正在发生的事情的视频,在大约40或45秒后你会看到角色开始滑动。

我已尝试过多种方法来解决这个问题,敌人和玩家的弹跳因子都设置为零。我尝试将玩家x坐标的linearVelocity设置为零,但这不起作用。这是我的碰撞检测代码。

  function spawnEnemies()
        temp = math.random(1, 4)
            enemy = display.newSprite(beetle, beetleSequenceData)
            enemy.x = _R + 100
            enemy.y = _CY
            enemy.hasBeenScored = false
            physics.addBody(enemy, "dynamic", physicsData:get("beetle"))
            enemy.xScale = -1
            enemy.id = "enemy"
            enemy.isFixedRotation = true
            enemy:play()
            group:insert(enemy)

            enemy2 = display.newSprite(vulture, vultureSequenceData)
            enemy2.x = _R + 100
            enemy2.y = _CY - (enemy2.height * 0.25)
            enemy2.hasBeenScored = false
            physics.addBody(enemy2, "dynamic", physicsData:get("vulture"))
            enemy2.xScale = -1
            enemy2.gravityScale = -0.01
            enemy2.id = "enemy2"
            enemy2.isFixedRotation = true
            enemy2:play()
            specialGroup:insert(enemy2)

            enemy3 = display.newSprite(scorpion, scorpionSequenceData)
            enemy3.x = _R + 100
            enemy3.y = _CY
            enemy3.hasBeenScored = false
            physics.addBody(enemy3, "dynamic", physicsData:get("scorpion"))
            enemy3.xScale = -1
            enemy3.id = "enemy3"
            enemy3.isFixedRotation = true
            enemy3:play()
            group:insert(enemy3)

            enemy4 = display.newSprite(bee, beeSequenceData)
            enemy4.x = _R + 100
            enemy4.y = _CY - (enemy4.height * 0.25)
            enemy4.hasBeenScored = false
            physics.addBody(enemy4, "dynamic", floatingEnemies:get("bee"))
            enemy4.xScale = -1
            enemy4.gravityScale = -0.01
            enemy4.id = "enemy4"
            enemy4.isFixedRotation = true
            enemy4:play()
            specialGroup:insert(enemy4)

          if temp == 1 then
              enemy2:removeSelf()
              enemy3:removeSelf()
              enemy4:removeSelf()
          elseif temp == 2 then
              enemy:removeSelf()
              enemy3:removeSelf()
              enemy4:removeSelf()
          elseif temp == 3 then
              enemy:removeSelf()
              enemy2:removeSelf()
              enemy4:removeSelf()
          else
              enemy:removeSelf()
              enemy2:removeSelf()
              enemy3:removeSelf()
          end
    end

    function moveEnemies()
        for a = group.numChildren, 1, -1 do
            if group[a].x < 100 then
                if group[a].hasBeenScored == false then
                    updateScore()
                    group[a].hasBeenScored = true
                end
            end
            if group[a].x > _L - 100 then
               group[a].x = group[a].x - 8
            else
               group:remove(group[a])
            end
        end
        for b = specialGroup.numChildren, 1, -1 do
            if specialGroup[b].x < 100 then
                if specialGroup[b].hasBeenScored == false then
                    specialUpdateScore()
                    specialGroup[b].hasBeenScored = true
                end
            end
            if specialGroup[b].x > _L - 100 then
               specialGroup[b].x = specialGroup[b].x - 8
            else
               specialGroup:remove(specialGroup[b])
            end
        end
    end

function onCollision(event)
       local function removeOnPlayerHit(obj1, obj2)
           if(obj1 ~= nil and obj1.id == "enemy") then
              display.remove(obj1)
           end
           if(obj2 ~= nil and obj2.id == "enemy") then
              display.remove(obj2)
           end
           if(obj1 ~= nil and obj1.id == "enemy2") then
              display.remove(obj1)
           end
           if(obj2 ~= nil and obj2.id == "enemy2") then
              display.remove(obj2)
           end
           if(obj1 ~= nil and obj1.id == "enemy3") then
              display.remove(obj1)
           end
           if(obj2 ~= nil and obj2.id == "enemy3") then
              display.remove(obj2)
           end
           if(obj1 ~= nil and obj1.id == "enemy4") then
              display.remove(obj1)
           end
           if(obj2 ~= nil and obj2.id == "enemy4") then
              display.remove(obj2)
           end
       end

       local function showPlayerHit()
           local tmr_onPlayerHit = timer.performWithDelay(1, playerHit, 1)
       end

       if event.phase == "began" then
           if((event.object1.id == "enemy" or event.object1.id == "enemy2" or event.object1.id == "enemy3" or event.object1.id == "enemy4") and event.object2.id == "character") then
               showPlayerHit()
               removeOnPlayerHit(event.object1, nil)
           elseif(event.object1.id == "character" and (event.object2.id == "enemy" or  event.object2.id == "enemy2" or event.object2.id == "enemy3" or event.object2.id == "enemy4")) then
               showPlayerHit()
               removeOnPlayerHit(nil, event.object2)
           end
       end
   end

1 个答案:

答案 0 :(得分:0)

我刚刚为你简化了代码

-- utility function
function isInArray(a, s, t)
    local g = {}
    for k, v in pairs(a) do
        if t then
            if v ~= s then
                table.insert(g, v)
            end
        else
            if v == s then
                return true
            end
        end
    end
    return t and (#g > 0 and g or false) or false
end

-- this will hold all the enemies names
local enemies = {}
-- this function creates all the enemies
function createEnemies(name, number)
    for i = 1, number do
        table.insert(enemies, i, name..i)
    end
end

-- now lets create the enemies, 4 enemies in total with the name enemy+n
-- e.g. enemy1, enemy2 etc.. for value of number
createEnemies('enemy', 4)


function onCollision(event)
    local function removeOnPlayerHit(obj1, obj2)
        -- see if either of the arguments are nil
        local objects = isInArray({obj1, obj2}, nil, true)  
        -- now check if objects contains any of the objects
        if next(objects) then
            -- if it does cycle through them
            for i = 1, #objects do
                -- now check against all the enemies
                if isInArray(enemies, objects[i].id) then
                    -- now remove the objects 
                    display.remove(objecta[i])
                end
            end
        end
    end

    local function showPlayerHit()
        local tmr_onPlayerHit = timer.performWithDelay(1, playerHit, 1)
    end
    if event.phase == "began" then
        if isInArray(enemies, event.object1.id) and event.object2.id == "character" then
            showPlayerHit()
            removeOnPlayerHit(event.object1, nil)
        elseif isInArray(enemies, event.object2.id) and event.object1.id == "character" then
            showPlayerHit()
            removeOnPlayerHit(nil, event.object2)
        end
    end
end