Identifying display objects

Lets say you’ve got a display group containing different shapes. How would you loop through it and identify the type of each? As far as I can tell, there is no concrete method to differentiate a polygon, for example, from a rect.

I’ve found:

Group: numChildren ~= nil

Circle: width == height and radius ~= nil

Rect: radius == nil and path.x4 ~= nil

RoundedRect: all others

Obviously, this is not canonical as anything other than the first 3 will be considered a roundedRect. Not ideal as there are other shapes available, like polygon.

How can we differentiate a polygon or image?

I don’t know but there is different way

When you create an object you can add value for example :

object=display…

object.objectType=“RoundImage”

and then you can have a look on this value to see the type of object

ex: if object.objectType==“RoundImage” then

A simple method is to append a param to each display object

local rect = display.newRect(50,50,50,50) rect.type = "rect"

Then you can do something like

if obj.type == "rect"   --its a rect end

IMHO .type should be internal

So the approach I took is along the lines of the “extending Lua libraries” tactic (which I had a featured blog post on some time ago)…

--[[Adds a property called 'displayShapeName' to the returned display object created by every display.\* library function which creates a display object. Example: local obj = display.newCircle( 10, 10, 100 ) print( obj.displayShapeName ) -- This will print "newCircle" to the console.]]-- local function addDisplayShapeNamings() for name,v in pairs(display) do if (string.starts( name, "new" ) and type(v) == "function") then local oldFunc = display[name] display[name] = function( ... ) local displayObj = oldFunc( unpack( arg ) ) displayObj.displayShapeName = name return displayObj end end end end addDisplayShapeNamings() local function testAddDisplayShapeNamings() local group = display.newGroup() local circle = display.newCircle( 0, 0, 100 ) local rect = display.newRect( 0, 0, 200, 100 ) local roundedrect = display.newRoundedRect( 0, 0, 200, 100, 50 ) print( group.displayShapeName ) print( circle.displayShapeName ) print( rect.displayShapeName ) print( roundedrect.displayShapeName ) group:removeSelf() circle:removeSelf() rect:removeSelf() roundedrect:removeSelf() end testAddDisplayShapeNamings()

Another idea I use sometimes when I want ‘additional’ features beyond the default:

local display\_newCircle = display.newCircle function display.newCircle( ... ) local obj = display\_newCircle( unpack( arg ) ) obj.isA = "circle" -- more code as needed return obj end -- Repeat for each base type

Tip: This may seem silly at first, but it also gives me the ability to then override the functions attached to objects as I need. Which, IMHO, makes it a nice way to modify the fundamental behavior of display.new*() calls while keeping all the goodness.

Drawback: Slower than normal call…

Yep - essentially, I’m doing the same thing, but to provide the same feature to all shape constructors.

It’s nice to be able to do this but it would be nicer to do it with property variables (e.g.: .width, .height), but I get why that’s not going to happen.

I don’t know but there is different way

When you create an object you can add value for example :

object=display…

object.objectType=“RoundImage”

and then you can have a look on this value to see the type of object

ex: if object.objectType==“RoundImage” then

A simple method is to append a param to each display object

local rect = display.newRect(50,50,50,50) rect.type = "rect"

Then you can do something like

if obj.type == "rect"   --its a rect end

IMHO .type should be internal

So the approach I took is along the lines of the “extending Lua libraries” tactic (which I had a featured blog post on some time ago)…

--[[Adds a property called 'displayShapeName' to the returned display object created by every display.\* library function which creates a display object. Example: local obj = display.newCircle( 10, 10, 100 ) print( obj.displayShapeName ) -- This will print "newCircle" to the console.]]-- local function addDisplayShapeNamings() for name,v in pairs(display) do if (string.starts( name, "new" ) and type(v) == "function") then local oldFunc = display[name] display[name] = function( ... ) local displayObj = oldFunc( unpack( arg ) ) displayObj.displayShapeName = name return displayObj end end end end addDisplayShapeNamings() local function testAddDisplayShapeNamings() local group = display.newGroup() local circle = display.newCircle( 0, 0, 100 ) local rect = display.newRect( 0, 0, 200, 100 ) local roundedrect = display.newRoundedRect( 0, 0, 200, 100, 50 ) print( group.displayShapeName ) print( circle.displayShapeName ) print( rect.displayShapeName ) print( roundedrect.displayShapeName ) group:removeSelf() circle:removeSelf() rect:removeSelf() roundedrect:removeSelf() end testAddDisplayShapeNamings()

Another idea I use sometimes when I want ‘additional’ features beyond the default:

local display\_newCircle = display.newCircle function display.newCircle( ... ) local obj = display\_newCircle( unpack( arg ) ) obj.isA = "circle" -- more code as needed return obj end -- Repeat for each base type

Tip: This may seem silly at first, but it also gives me the ability to then override the functions attached to objects as I need. Which, IMHO, makes it a nice way to modify the fundamental behavior of display.new*() calls while keeping all the goodness.

Drawback: Slower than normal call…

Yep - essentially, I’m doing the same thing, but to provide the same feature to all shape constructors.

It’s nice to be able to do this but it would be nicer to do it with property variables (e.g.: .width, .height), but I get why that’s not going to happen.