Referencing multiple objects of the same type

One of the most problem faced by many is when they create/spawn multiple objects but when they try working with them, they end up with only one of them reacting to the events, etc while the rest of them do not. So, how can we handle that?

First things first. Let us see how it all works. When we create a variable, think of a card wallet, that can hold cards, generally these will be blank, but the moment you assign a variable, one of these slots is taken.

  local image1 = display.newImage("image1.png",10,10)

Variable Memory
  +-------------------+
  | Image1 0xFEEDF00D |
  +-------------------+
  |                   |
  +-------------------+
  |                   |
  +-------------------+
  |                   |
  +-------------------+
  |                   |
  +-------------------+

0xFEEDF00D: -> Holds the Image1.png data
  +-------------------+
  |                   |
  |                   |
  |                   |
  |                   |
  |                   |
  |                   |
  +-------------------+

In the example, Image1 has a slot in the memory space for variables, this then points to a memory space. Where the data for that variable is held, it can be an int, a string, an image, a table, whatever. In this example it holds an imageData.

Now when we spawn another object as
  image1 = display.newImage("Image2.png",10,50)

What happens is that the variable memory location does not have a new entry but updates the location of the memory where image2.png is held.

Variable Memory
  +-------------------+
  | Image1 0xFEEDFEED |
  +-------------------+
  |                   |
  +-------------------+
  |                   |
  +-------------------+
  |                   |
  +-------------------+
  |                   |
  +-------------------+

0xFEEDF00D: -> Holds the Image1.png data
  +-------------------+
  |                   |
  |                   |
  |                   |
  |                   |
  |                   |
  |                   |
  +-------------------+
0xFEEDFEED: -> Holds the Image2.png data
  +-------------------+
  |                   |
  |                   |
  |                   |
  |                   |
  |                   |
  |                   |
  +-------------------+

So though the two objects are in memory, we have lost the handle to the location where the image object is held, so if we want to move the object to a particular location on screen, we cannot.

let us consider an alternative situation,
 local i, rocket
 for i=1,5 do
  rocket = display.newImage("rocket" .. i .. ".png")
 end

What this will do is allocate 5 image objects in memory but the last object will be referenced by the variable rocket. So,
 rocket.x = 50
 rocket.y = 150
this will only move the last rocket.

Memory would look something like
  +-------------------+            +---------------------+
  |Image1Data         |            |                     |
  +-------------------+            +---------------------+
  |Image2Data         |            |                     |
  +-------------------+            +---------------------+
  |Image3Data         |            |                     |
  +-------------------+            +---------------------+
  |Image4Data         |            |                     |
  +-------------------+            +---------------------+
  |Image5Data         |<-----------|rocket               |
  +-------------------+            +---------------------+
  |                   |            |                     |
  |                   |            +---------------------+
  |                   |
  |                   |
  |                   |
  +-------------------+
Hope you have understood how the memory will look like and what happens.

Now how can we manage things?

There are two ways to manage this, one would be to have a totally encapsulated class that is responsible for itself, it will have it's own functions, etc all integrated or the second way to manage things would be to have an array of objects so that all the handles are stored and can be referenced for use.

 local handles={}
 local i
 for i=1,5 do
  handles[i] = display.newImage("rocket"..i..".png")
 end

then if we wanted to deal with the 4th object, we can just manage it as handles[4], so to move the 4th object, we can use
 handles[4].x = 100
 handles[4].y = 200

The other way of having a self encapsulated object, it would look like
 local i,
 local function spawnObject(thisOne)
  local image = display.newImage("rocket"..thisOne..".png")
    
  local function onTouch(event)
   local phase == event.phase
   local target = event.target
   print(event.name, phase, target)
   target:removeSelf()
  end

  image:addEventListener("touch", onTouch)

  return image
 end
This way, even if you do not have a handle to the object, it will manage the touch and also remove it on touching.

I hope this has helped you to understand how things work and why sometime when you try to remove objects, only a particular one gets deleted and after that it spawns an error.

Comments

Popular Posts