Как эффективно обрабатывать удаление объектов с помощью Corona SDK - PullRequest
3 голосов
/ 09 октября 2011

только начинает играть с удивительной Corona SDK.

Я начал создавать простую шутер.

У меня есть следующий код:

-- Global Variables
local shot = audio.loadSound('shot.mp3')
local bg = display.newImage('bg.png')
local shoot = {}
local Main = {}
local Init = {}

local bullets = display.newGroup()

function update()
    if(bullets.numChildren ~= 0) then
        for i = 1, bullets.numChildren do
            bullets[i].y = bullets[i].y - 8
            -- Destroy Offstage Bullets

            if(bullets[i].y < (-bullets[i].height-5)) then
                -- bullets[i]:removeSelf()
                bullets:remove(bullets[i])
                display.remove(bullets[i])
                return
            end
        end
    end
end
-- Initialisation functions
function Init ()
    display.setStatusBar(display.HiddenStatusBar)
    local movieclip = require('movieclip')
    local physics = require('physics')
    physics.start()
    physics.setGravity(0, 0)

end

function shoot:tap(e)
        for i = 1, 15 do
    local bullet = display.newImage('bullet.png')
    bullet.x = 150
    bullet.y = 470
    bullet.name = 'bullet'
    physics.addBody(bullet)
    bullets.insert(bullets, bullet)
    end 
audio.play(shot)

end

-- Main routine
function Main ()
    Init()
    bg:addEventListener('tap', shoot)
    Runtime:addEventListener('enterFrame', update)
end

Main()

Длятеперь это «работает»;но когда пуля появляется на экране, вся «игра» замедляется, и я ясно вижу, что каждая пуля удаляется, что замедляет игру.

Может быть, я делаю это неправильно;также пробовал: удалить функцию ();те же результаты.

Ответы [ 4 ]

3 голосов
/ 05 декабря 2011

Я столкнулся с той же проблемой ... И получил за это Soln:

Вы удаляете объекты, используя цикл for: если вы удаляете объекты в цикле for, скажем: вы удалили объект с индексом 1, то объект 2 перемещается к объекту 1 ... поэтому, когда он возвращается к объекту, он не проверяет объект 2 (bcoz перемещает его на место объекта 1, а вы проверяете объект 3)

for j = 1, buttonGroup.numChildren do   
    buttonGroup[1]:removeSelf();        --this removes all childrens
end


for j = 1, buttonGroup.numChildren do   
    buttonGroup[j]:removeSelf();        --this removes alternative childrens
end

Я надеюсь, что это полезно

0 голосов
/ 28 декабря 2013

Прежде всего, никогда не пытайтесь выполнить какой-либо цикл в GameLoop. Он сбрасывает fps игры, потому что обычно занимает больше памяти.

Теперь кажется, что вы просто хотите уничтожить пули после исчезновения с экрана, и вы тоже используете физику, так почему вы не пользуетесь этим?

Вот шаги, которые вы должны выполнить. (Если вы обнаружите какой-либо вопрос или затруднение по этому поводу, спросите меня)

1.Нанесите статическую физическую линию немного выше экрана. Допустим, у -20.

    local _yLimit = -20
    local _limitLine = display.newLine(0,_yLimit,display.contentWidth,_yLimit)
    _limitLine.anchorX = 0
    _limitLine.anchorY = 0

2.Добавить все пули как физический объект.

3. Примените силу в нижнем центре пули, а не трансформируйте ее. [Предполагая, что пуля имеет прямоугольную физическую форму, в противном случае определите точку равновесия формы].

4. Проверьте наличие коллизий с помощью прослушивателя событий «коллизия».

5. Уничтожить пули при столкновении

Это так просто:)

Дайте мне знать, если у вас все еще есть проблемы по этому поводу.

0 голосов
/ 26 декабря 2013

проще создать такую ​​таблицу

local bulletCache = {}

Тогда в вашем коде создания пули добавьте

table.insert(bulletCache, myBulletObject)

затем в коде выхода и / или коде уничтожения произнесите

for i = 1, #bulletCache do

--[[
--Below is not needed but just to keep your code consitant
    pcall(function()
        bullet.alpha = 0
    end)
--]]

    pcall(function()
        bullet:removeSelf()
    end)
    pcall(function()
        bullet = nil
    end)
end
0 голосов
/ 21 декабря 2013

Я долгое время боролся с удалением объектов для моей игры, в которой используется множество представлений с вкладками.Я нашел решение использовать «= nil», «: removeSelf ()» и «.alpha = 0» для всех объектов, которые необходимо удалить.Если они все добавлены в одну группу и в ней больше ничего нет, это тоже можно использовать, но не всегда работает по разным причинам, как группы создаются за кулисами.

ЭтоКазалось бы, то, что вы сделали, это удалите содержимое «маркеров», но это всего лишь ссылка, поэтому, когда вы говорите, что каждая пуля удаляется, она на самом деле только удаляется из массива - сам объект все еще существует и должен бытьnil'd, чтобы предотвратить утечку памяти и замедление работы приложения (вы, вероятно, обнаружите, что каждая пуля замедляет работу приложения, не так ли?)

Добавьте это условие после удаления и установите его.:

if(not(bullet == nil)) then
    bullet.alpha = 0;
    bullet:removeSelf();
    bullet = nil;
end
...