Help with tables & spawning new enemies.

Sorry I know this is really basic/lame but it is holding me back. I'm using a function to iterate through a table and spawn a new enemy.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
local enemyTable ={}
 
 
loadShip = function()
 
        smallShip1 = {}
        smallShip1.image = "shipSmall.png"
        smallShip1.x = 1500
        smallShip1.y = 172
        smallShip1.s = 0.3 -- Speed
        smallShip1.d = "left" -- Direction
        smallShip1.h = 200 -- Health
        smallShip1.myName = "smallShip1"
        table.insert(enemyTable, smallShip1)
 
end
 
spawnEnemies = function()
 
        
        enemyProp = enemyTable[math.random(1, #enemyTable)]
        enemy = display.newImage(enemyProp.image)
        enemy.x = enemyProp.x
        enemy.y = enemyProp.y
        enemy.myName = enemyProp.myName
        enemy.s = enemyProp.s
        enemy.d = enemyProp.d
        enemy.h = enemyProp.h
        
        enemy:setReferencePoint( display.CenterReferencePoint )
        physics.addBody( enemy, "static", { isSensor = true, shape = smallShipShape } )
        enemyGroup:insert(enemy)
        
        enemyShipCount = enemyShipCount + 1;
        
        return enemy
        
        
 
end     
 
loadEnemyShips = function()
 
if enemyShipCount <= 1 then
 
        spawnEnemies()
 
end
 
end

you should create individual handles for each enemy. for that you may use tables for storing enemies.

eg:

1
2
3
4
5
6
local enemy = {}
spawnEnemies = function()
 enemy[#enemy + 1] = display.newImage(enemyProp.image)
 ...
 ...
end

@renjit,

you might want to fix line 3 as

3
 enemy[#enemy+1] = display.newImage(enemyProp.image)

Yes Jayant. it was a typo. I edited it. Thanks for pointing it out.

@renvis Thanks a lot, this looks like exactly what I need, and what i've been searching for! Although my problem now is that the properties don't apply to "enemy" anymore?

For instance my code now looks like

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
local enemy = {}                
        
spawnEnemies = function()
 
        
        enemyProp = enemyTable[math.random(1, #enemyTable)]
        enemy[#enemy + 1] = display.newImage(enemyProp.image)
        enemy.x = enemyProp.x
        enemy.y = enemyProp.y
        enemy.myName = enemyProp.myName
        enemy.s = enemyProp.s
        enemy.d = enemyProp.d
        enemy.h = enemyProp.h
        
        physics.addBody( enemy, "static", { isSensor = true, shape = smallShipShape } )
        enemyGroup:insert(enemy)
        
        enemyShipCount = enemyShipCount + 1;
        enemy.collision = enemyCollision
        
        enemy:addEventListener( "collision", enemy )
        
        return enemy
 
end     

Once you spawn the enemy what are they supposed to do ? what is ur expected behavior ?

you have to control each enemy separately using there handle like enemy[1], enemy[2] etc.
if you want to do it for all together use a loop

1
2
3
4
for i =1, #enemy,1
  --do something
  enemy[i].x = .....
end

It looks like SpawnEnemies job is to create one enemy and it gets called multiple time.

Your spawnenemies needs one small change.

change:

enemy = display.newImage(enemyProp.image)

to

local enemy = display.newImage(enemyProp.image)

This will keep "enemy" scoped to that function. Right now you are overwriting a global variable called "enemy" on each call. By making it local, you will get a new variable on each time and that variable gets returned in the return call.

Now your loadEnemies function needs to do something with the enemy object that's being returned. That would be a good place to have a table called enemies and you're keeping track of each returned enemy:

1
2
3
4
5
6
7
8
9
10
11
enemies = {}
 
loadEnemyShips = function()
 
   if enemyShipCount <= 1 then
 
        enemies[#enemies + 1] = spawnEnemies()
 
   end
 
end

You might want to read up on this article here to get a better understanding.

As for a simple oneline fix for your problem,

the thing you are doing wrong is

1. you are creating an array outside of the spawn function
2. you are populating the array inside of the function and changing the x, y for the array than for the element

yes, you have kind of identified the issue yourself where towards the end of your question, you have got a solution.

Now, this is what *I recommend*,
always use a reference, it is better to work with. so your code can look a bit like

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
local enemy = {}                
        
spawnEnemies = function()
 
   local enemyProp = enemyTable[math.random(1, #enemyTable)]
   enemy[#enemy+1] = display.newImage(enemyProp.image)
   local element = enemy[#enemy+1]
 
   element.x = enemyProp.x
   element.y = enemyProp.y
   element.myName = enemyProp.myName
   element.s = enemyProp.s
   element.d = enemyProp.d
   element.h = enemyProp.h
        
   physics.addBody( enemy, "static", { isSensor = true, shape = smallShipShape } )
   enemyGroup:insert(element)
        
   enemyShipCount = enemyShipCount + 1;
   element.collision = enemyCollision
 
   element:addEventListener( "collision", element )
   return element 
end

Thanks a bunch guys! As always Jayantv and Robmiracle, you guys are absolute legends. Renvis too, cheers mate. I've only been coding a few months so still grappling with basic stuff but hey everyday I'm getting a bit more confident and you guys are making it a lot easier.

I've ended up using Rob's method, with a splash of Renvis thrown in, so my code looks like

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
spawnEnemies = function()
 
        
        enemyProp = enemyTable[math.random(1, #enemyTable)]
        local enemy = display.newImage(enemyProp.image)
        enemy.x = enemyProp.x
        enemy.y = enemyProp.y
        enemy.myName = enemyProp.myName
        enemy.s = enemyProp.s * math.random(5)
        enemy.d = enemyProp.d
        enemy.h = enemyProp.h
        
        physics.addBody( enemy, "static", { isSensor = true, shape = smallShipShape } )
        enemyGroup:insert(enemy)
        enemyShipCount = enemyShipCount + 1;
        enemy.collision = enemyCollision
        enemy:addEventListener( "collision", enemy )
        
        return enemy
 
end     
 
enemies = {}
 
loadEnemyShips = function()
 
--if enemyShipCount == 0 then
 
        enemies[#enemies + 1] = spawnEnemies()
 
--end
 
end

Actually change that last part i updated the loop to just use

1
2
3
4
5
        for i =1, #enemies,1 do
        
        enemies[i].x = enemies[i].x - enemies[i].s
        
        end

you may use this inside your main game loop.so that you don;t have to hardcode things and can have more than 5 enemies.

1
2
3
for i=1,#enemies,1 do
  enemies[i].x = enemies[i].x - enemies[i].s
end
views:2503 update:2011/9/25 12:40:18
corona forums © 2003-2011