My spawn object with tables doesnt work!

If you are using composer, I am guessing, the code that I sent you and most of your code is in the ‘create’ or ‘show’ functions of the scene. I have not used composer a lot, but each of those functions has a scene display group in them.

local sceneGroup = self.view

in the spawnEnemy function, after you have created an enemy object, make sure to insert it into the sceneGroup.

Right after this line :

enemytable[enemyCnt] = display.newImage(enemypic)

do this:

sceneGroup:insert(enemytable[enemyCnt])

The key is any visual object you want to be hidden when the scene hides itself, you need to make sure to insert into the sceneGroup.

(I am not that experienced with Composer), but when composer hides the scene it will/should hide all those enemies.

I won’t be back on the forum till sometime tomorrow, so if you post a response, I will try to get back to it tomorrow.

Good luck.

by the way, if you do want to manually ‘remove’ the enemies. you would need to do a loop, in reverse to remove the display objects from the table

like:

for i = enemyCnt, 1, -1 do

 display.remove(enemyTable[i])

enemyTable[i] = nil

end

enemyTable = nil

I have been able to remove them from display by putting them into scene.view with this line:

enemytable[enemyCnt] = display.newImage(scene.view, enemypic)

Now they do not show up anymore but they DO keep moving and hitting the planet and respawning. I am trying to stop their transition to the middle with this code when i leave the scene but it doesnt work:

if enemytable.trans then transition.cancel(enemytable.trans) enemytable.trans = nil end

This is put into scene.hide.

If i use this instead

if enemytable[enemyCnt].trans then transition.cancel(enemytable[enemyCnt]..trans) enemytable[enemyCnt].trans = nil end

Then it gives me this error

Make sure you do that step before you remove all the elements from enemytable.

Also using enemyCnt will only cancel the final transition, you need to loop through enemytable and cancel each one.

Im sorry which step do you mean? The one with the reverse loop? I dont have the initial loop because that would spawn 5 enemies at the start so that one didnt work out.

Im now using this one to spawn one additional enemy at the score 5, 10, 15 etc.

local function gameLoop(e) if score == scoreStep then spawnEnemy() scoreStep = scoreStep + 5 end end Runtime:addEventListener("enterFrame", gameLoop)

I mean the step that cyberparkstudios posted to remove the elements from the table. If you aren’t using this it doesn’t matter.

The point remains that you need to loop through the table and cancel the transitions in the ‘will’ phase on scene:hide() because:

[lua]

enemytable[enemyCnt].trans

[/lua]

Will only cancel the transition for the last enemy spawned.

Please bear with me for a little while longer. I have not tried to put the transition cancel in a loop that goes like this:

for i = enemyCnt, 1, -1 do if enemytable[enemyCnt].trans then transition.cancel(enemytable[enemyCnt].trans) enemytable[enemyCnt].trans = nil end end

This is giving me a nil value while i have stated the enemyCnt inside the brackets. Do you know why this is happening?

[lua]

for i = enemyCnt, 1 , - 1 do

      if enemytable[i] .t rans then

      transition.cancel(enemytable[i] .t rans)

      enemytable[i] .t rans = nil

      end

end

[/lua]

As for them continuing to respawn, have you removed the enterFrame listener upon leaving the scene?

Danny,

In regards to the error in scene.hide, the code you show has one typo error.  you  have  2 dots ‘…’  instead of 1 dot.

And don’t use ‘enemyCnt’ there.  There are many factors to consider on what is best way to cancel those transitions, but here is just a quick simple way do it.(see sample code below)

However, If you are only trying to end transition of the ‘last enemy unit’, the loop is not needed; and you can actually, do it the way you have it now, and still use enemyCnt, BUT, you need to make 2 other small changes to make it work.

  1. at the top of your code, initiate enemyCnt = 0, instead of 1

  2. move the line  ‘enemyCnt = enemyCnt + 1’ to be the first line inside of your ‘spawnEnemy’ function, instead of being the last line in that function.

(this is assuming you have not cleared any enemy units from the enemy table) 

  for i = 1, #enemytable do if enemytable[i].trans then transition.cancel(enemytable[i]..trans) enemytable[i].trans = nil end end      

Danny, 

I think the ‘nil’ value you are getting is because of the enemyCnt is 1 more then the actual number of enemies.

The quick fix, is as I mention in the last post,  change the initial value of enemyCnt at the top of your code to 0, not 1.  Then in the ‘spawnEnemy’ function, move the last line in the function  'enemyCnt = enemyCnt + 1 to be the first line in the function.

Then that reverse loop, will start with a valid index.

I am now removing the runtime loop with this piece of code in scenehide:

Runtime:removeEventListener( "enterFrame", gameLoop )

Im not sure this has any effect though.

Also I have set enemyCnt initiatal to 0 and the line enemyCnt = enemyCnt + 1 to the top of the function.
Now i can remove 1 enemy but not more.

can you post your spawnEnemy and scene.hide functions ?

Sure thing!

At the top i have

local enemytable = {} local enemypics = {"images/beetleship.png","images/octopus.png", "images/rocketship.png"} local enemyCnt = 0 local scoreStep = 5

Then i have spawnenemy

function spawnEnemy() enemyCnt = enemyCnt + 1 enemypic = enemypics[math.random(#enemypics)] enemytable[enemyCnt] = display.newImage(scene.view,enemypic) --sceneGroup:insert(enemytable[enemyCnt]) enemytable[enemyCnt]:addEventListener ( "tap", shipSmash ) if math.random(2) == 1 then enemytable[enemyCnt].x = math.random ( -100, -10 ) else enemytable[enemyCnt].x = math.random ( display.contentWidth + 10, display.contentWidth + 100 ) enemytable[enemyCnt].xScale = -1 end enemytable[enemyCnt].y = math.random (display.contentHeight) enemytable[enemyCnt].trans = transition.to ( enemytable[enemyCnt], { x=centerX, y=centerY, time=math.random(2500-speedBump, 4500-speedBump), onComplete=hitPlanet } ) speedBump = speedBump + 50 end local function gameLoop(e) if score == scoreStep then spawnEnemy() scoreStep = scoreStep + 5 end end Runtime:addEventListener("enterFrame", gameLoop)

Scenehide

-- "scene:hide()" function scene:hide( event ) local sceneGroup = self.view local phase = event.phase if ( phase == "will" ) then -- Called when the scene is on screen (but is about to go off screen). -- Insert code here to "pause" the scene. -- Example: stop timers, stop animation, stop audio, etc. Runtime:removeEventListener( "enterFrame", gameLoop ) for i = enemyCnt, 1, -1 do if enemytable[enemyCnt].trans then transition.cancel(enemytable[enemyCnt].trans) enemytable[enemyCnt].trans = nil end end -- if enemy.trans then -- transition.cancel(enemy.trans) -- enemy.trans = nil -- end elseif ( phase == "did" ) then -- Called immediately after scene goes off screen. display.remove(planet) display.remove(enemytable[enemyCnt]) display.remove(scoreTxt) pauseBtn.alpha=0 end end

Do tell me if you need more information!

if you want to remove all the enemy units, you have to do a loop, just like you did with canceling the transitions in the ‘will’ phase.

As you are using it now, enemyCnt in the ‘did’ phase will only destroy the last enemy object.  

Can you see how enemyCnt value only changes when an enemy is spawned.  So when you use that anywhere in the code it is always going to be a value that equals the number of enemies.  So, as you have it, you are simply removing the last enemy object.

So when you make the loop in the ‘did’ phase, it needs to be a reverse loop, because you will be removing objects from the enemy table.  

When you did the cancel transitions loop in the ‘will’ phase, you could and probably should do the loop in normal order. Although either way works. It just does not need to be a reverse loop.

I know everytime i spawn a unit it becomes enemyCnt + 1 so it becomes +2, +3 etc… But… how do i make a loop for that? With enemyCnt -1? Because im not sure what that count itself do. The spawning is done with spawnEnemy right? What does the enemyCnt do?

enemyCnt just keeps track of the total enemies.  Then, in the spawnEnemy function it is used to ‘index’ which enemy unit in the enemy table you are referring to as you position the enemy object, assign it an event listener and so forth.  

once out of the spawnEnemy function, enemyCnt will be equal to whatever is the total number of enemies.

So, in this example loop, if you have created 15 enemies, enemyCnt will be equal to 15.

In this sample, the loop runs from 1 to 15, and if the enemy has an active transition, it will cancel it.

  for i = 1, enemyCnt do if enemytable[i].trans then transition.cancel(enemytable[i].trans) enemytable[i].trans = nil end   end  

in this sample below, since we are removing display objects (enemy images) and clearing the enemy table, it works best to 

loop backwards…  So the loop goes from 15, to 1.   the -1, tells the loop to subtract 1 each time, so it removes enemy table index #15 first, then 14, then 13 … etc

  for i = enemyCnt, 1, -1 do  display.remove(enemyTable[i]) enemyTable[i] = nil end enemyTable = nil  

I would suggest you can learn a lot of this by checking out some good tutorials and other code other developers have shared. Looking over those tutorials and code and getting to understand them, will really help.  But, you should go over several of them.  Many indie developers have learned this way. It takes a lot of time, but it is a good way to get a feel for this stuff.

Here are just a few you may want to check out.  I have not checked these out, so I am not sure which is the best of them. But you could check each of them out.

http://coronalabs.com/blog/2014/11/04/tutorial-basic-spawning/

http://coronalabs.com/blog/2011/09/14/how-to-spawn-objects-the-right-way/

http://www.christianpeeters.com/complete-app-tutorial/create-a-simple-space-shooter-with-corona-sdk/

http://www.tandgapps.co.uk/resources/tutorial-space-shooter-in-240-lines/

http://www.raywenderlich.com/22064/how-to-make-a-simple-game-with-corona

There are even more then these out there on the internet.  You are likely to find even better ones if you search the internet.

Alright thanks for everything! I will give it a look!

Hey there guys! I still need one little bit of advice and then my app is all done!
I have done various patching and editing and most of the bugs and problems are gone by now!
How do i get the loop back after i removed it? It seems that changing the emptytable = nil to {} Doesnt allow me to spawn my enemies anymore and it stays empty if i reload the scene!

Im using this atm:

for i = enemyCnt, 1, -1 do display.remove(enemytable[i]) enemytable[i] = nil end enemytable = {}

Danny,

Probably need to see your ‘scene.create’ and ‘scene.show’ code.

Somewhere in one of those functions you would need to re-do the enemy table. This all is assuming, that when you leave the scene and return you did not want to save anything. In other words, start everything over each time player exits and returns to the scene. Otherwise, you will have to figure out what things you want to save when a scene is paused or closed.