开发者

How to effectively handle object removal of objects with Corona SDK

just starting to play around with the awesome corona sdk.

I started building a simple shooter game.

I have the following code :

-- 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(bull开发者_如何学Cets, bullet)
    end 
audio.play(shot)

end

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

Main()

For now it 'works'; but when the bullet comes of the screen the whole 'game' slows down and I can clearly see that each bullet is removed which slows down the game.

Maybe i'm not doing it right; also tried the :removeSelf() function; same results.


I was facing the same problem...And got the soln for this:

you are removing objects using for loop: if you remove objects in for loop say: you deleted object at index 1, then object 2 moves to object 1...so when it loops to object to it wont check object 2(bcoz its moved to object 1's place and you are checking object 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

I hope its useful


I fought for a long long time with object removal for my game which uses a lot of tabbed views. The solution I found was to use "= nil", ":removeSelf()" and ".alpha = 0" on all objects which need removing. If they are all added to the same group, and nothing else is in it, that could be used too, but doesn't always work for various reasons as to how groups are set up behind the scenes.

It would seem what you've done there is remove the contents of "bullets" but that's just a reference, so where you say each bullet is being removed, it's actually only being dropped from the array - the object itself still exists and needs to be nil'd in order to prevent a memory leak and a slowing of the app (you will probably have found that each bullet slows the app more, right?)

Add this condition after your removes and you should be set:

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


its easier to simply create a table like this

local bulletCache = {}

Then in your bullet creation code add

table.insert(bulletCache, myBulletObject)

then in your exit code and/or your destroy code say

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


First of all, never try to execute any kind of loop in GameLoop. It does drop fps of game, because it takes usually more memory.

Now, it seems that you just want to destroy bullets after disappearing from the screen and you are using physics too, so why you are not taking advantage of that?

Here are the steps you should follow. (If you find any query or difficulty about it then ask me)

1.Draw a Static Physical Line little bit above the screen. Let say y is -20.

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

2.Add all bullets as a physical object.

3.Apply force at the Bottom Center of bullet, rather then transforming it. [Assuming that bullet have rectangular physical shape, otherwise decide the equilibrium point of the shape].

4.Check for collisions with "collision" event listener.

5.Destroy bullets on collision

Thats so simple :)

Let me know if you still have problems regarding this.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜