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.
精彩评论