Spawning Objects - indexing health

In my code below, I’m spawning a new object when a button is pressed. I’d like to also create a health value for each object in the table so something like allkernel[i].health = 20 so that later on, something can reference the health value of each spawned object. I’m not sure how I associate each object with a health value though.

local function spawnkernel( event )  
 local phase = event.phase  
  
 if "ended" == phase then  
  
 allkernel[#allkernel + 1] = display.newImage( "cernal.png" )  
  
  
 local disk = allkernel[#allkernel]  
  
 disk.x = math.random (150, 270)  
 disk.y = 50  
 disk.rotation = math.random( 1, 360 )  
  
  
 physics.addBody( disk, { density=50, friction=3, bounce=0, radius=15 } )  
  
 disk.linearDamping = 0.4  
 disk.angularDamping = 0.6  
  
 end  
  
  
end  
  

Thanks,
[import]uid: 78150 topic_id: 16184 reply_id: 316184[/import]

just add a member to the object you create, for example

local disk = allkernel[#allkernel]
disk.health = 20
.
.
.
end

cheers,

?:slight_smile: [import]uid: 3826 topic_id: 16184 reply_id: 60284[/import]

Thanks for the reply!

How would I reference disk.health in another function?

 local function reducehealth( event )  
  
 for i = 1, #allkernel do  
 local onekernal = allkernel[i]  
  
 if (onekernal.y) then  
 if onekernal.y \> 50 then  
  
--here i would like to reduce disk.health  
  
  
  
 end  
 end  
 end  
end  
  

Thanks again!

p.s. did you get a chance to work on that earlier project regarding the plastic army men and fire? =) [import]uid: 78150 topic_id: 16184 reply_id: 60394[/import]

  1. Towards the start of the code, create
 local allkernel={}  

then you can have your function spawnKernel that will create a new entry into the array

so from your other function, you can have

 local function reduceHealth(thisObject, reduceBy)  
 --This is a direct way, where you know  
 -- the object you want to reduce health for.  
 thisObject.health = thisObject.health - reduceBy  
 end  
  
 local function reduce\_Health(index, reduceBy)  
 local disk = allkernel[index]  
 disk.health = disk.health - reduceBy  
 end  
  

you need to either know which object it is or the index, that way it will be easier. To have a better response, you will have to reveal a bit more on what you are trying to do, as your code is *non* optimised.

and, NO, I did not really get time to work on that, am tied up. I write/respond to relax…

cheers,

?:slight_smile: [import]uid: 3826 topic_id: 16184 reply_id: 60396[/import]

I’m slowly just working on one element of the army man example. I’m doing my best, as I have no coding background and I also have a busy day job. So this is just a hobby =)

Right now my code just spawns an object which falls on the floor. I’m trying to associate a health value to the object. I have a “ticker” which ticks every second. My goal is to have the health of the object be reduced while the object is sitting on the floor

local allkernel = {}  
-- Here is my spawn function  
  
local function spawnkernel( event )  
 local phase = event.phase  
 if "ended" == phase then  
  
 allkernel[#allkernel + 1] = display.newImage( "cernal.png" )  
  
 local disk = allkernel[#allkernel]  
  
 disk.x = math.random (150, 270)  
 disk.y = 50  
 disk.rotation = math.random( 1, 360 )  
 physics.addBody( disk, { density=50, friction=3, bounce=0,   
radius=15 } )  
  
 disk.linearDamping = 0.4  
 disk.angularDamping = 0.6  
  
 end  
end  
-- Here is my reduction of health function (where I would like the health of the spawned object to be reduced)  
   
local function listener( event )  
  
 for i = 1, #allkernel do  
 local onekernal = allkernel[i]  
  
 if (onekernal.y) then  
 if onekernal.y \> 50 then  
-- reduce health here, once every second (or tick)until nothing left. Then kill object.  
  
 end  
 end  
 end  
end  
 timer.performWithDelay(  
 1000, listener, 0 )  
  

Hope that makes it more clear =) [import]uid: 78150 topic_id: 16184 reply_id: 60405[/import]

right,

local physics = require("physics")  
physics.start()  
  
local allKernal = {} -- create the blank table  
  
local function spawnKernel()  
 local disk = display.newImage("cernal.png")  
 allKernal[#allKernal+1] = disk  
  
 disk.x = math.random(150,270)  
 disk.y = 0  
 disk.rotation = math.random( 1, 360)  
  
 physics.addBody( disk, {density=50, friction=3, bounce=0, radius=15})  
 disk.linearDamping = 0.4  
 disk.angularDamping = 0.6  
  
 disk.health = 8 --change this to play with it  
end  
  
local function reduceHealth()  
 local i  
 for i=#allKernal, 1, -1 do  
 local disk = allKernal[i]  
 if disk ~= nil then  
 if disk.y \> 50 then  
 disk.health = disk.health-1  
 if disk.health \<= 0 then  
 disk:removeSelf()  
 allKernal[i] = nil  
 end  
 end  
 end  
 end  
end  
  
Runtime:addEventListener("tap",spawnKernel)  
  
timer.performWithDelay(100,reduceHealth,0)  
--Instead of this timer, you can also use enterFrame  

cheers,

?:slight_smile:

this should work for you… [import]uid: 3826 topic_id: 16184 reply_id: 60422[/import]

Impressive! Thanks for the code - definitely starting to understand what’s going on better.

As I was playing around I noticed an odd glitch. As I’m spawning new Kernals, occasionally one or two seem to do nothing after spawning. For example if I create 3 Kernals fast, sometimes only two disappear. I print(disk.health) to see whats going on, all three Kernals are in the table (i.e, the are counting down 888, 777, 666, but when it reaches 1 it only counts 11, rather than 111 as would be expected.

Any ideas? [import]uid: 78150 topic_id: 16184 reply_id: 60507[/import]

After some thinking - I have a feeling that it has to do with me using a timer instead of an enterFrame. I’m not really sure how to use an enterFrame as a timer though [import]uid: 78150 topic_id: 16184 reply_id: 60605[/import]

enterFrame =/= a timer (IS NOT A)

Think of enterFrame as a cental heartbeat, it ticks every so often, you can use that to constraint the positions of certain objects, to remove or display them or do some things continously rather than put that in a timer loop or in a for loop.

cheers,

?:slight_smile: [import]uid: 3826 topic_id: 16184 reply_id: 60607[/import]

Thanks for the clarification. I added an enterframe listener and removed the timer as you suggested. For the most part, it’s doing what I want. However it still seems to occasionally “forget” about a kernel. What I mean is, 4 out of the 5 kernels will disappear as they should, but one just sits there and does nothing. It’s only if I create additional kernels that the one that was sitting there doing nothing is finally removed. Any ideas? [import]uid: 78150 topic_id: 16184 reply_id: 60829[/import]

I do not know the final modification that you make to the code, so it is difficult to debug your code that I cannot even see.

However from what you say, it can be one of the following issues

  1. You have the index position overwritten by another kernel

  2. the way lua works with loops and tables (which I think is the culprit)

when you use

#tableName, it is supposed to return the number of items in the table, but if you have

tableName[1] = 1
tableName[2] = 2
tableName[5] = 5

and you say print(#tableName)… guess what you will get?? you will get 2 not 3 as you would expect.

so the kernel you are talking about is left alone on the screen and then when you add more, it is taken into consideration and acted upon.

hope you did understand this anomaly…

cheers,

?:slight_smile: [import]uid: 3826 topic_id: 16184 reply_id: 60831[/import]

Ok – that’s interesting! If I understand correctly from the above example you provided, the for loop would stop at 2 because “drawer” 3 is nill, and the for loop always stops at the first instance of a nill. Only once draw 3 and 4 are filled, does the loop reach drawer 5.
 
Currently I’m using
  for i=#allKernal, 1, -1 do &nbsp;
But I will try:
  for i=1, table.maxn(allKernal), 1 – 1 do &nbsp;

I cant try it now because I’m at work! =)
 
 
Thanks many times for your help!!!

*Edit*

The following line of code solved the problem… code now checks all used “drawers”

  
 for i = 1,table.maxn(allKernal) do  
  

  [import]uid: 78150 topic_id: 16184 reply_id: 60855[/import]

@ggortva

you might want to have a look at the HowTo.oz-apps.com site for this

cheers,

?:slight_smile: [import]uid: 3826 topic_id: 16184 reply_id: 61397[/import]