z-ordering objects of different class types

Monkey Forums/Monkey Programming/z-ordering objects of different class types

rIKmAN(Posted 2013) [#1]
As per the title, I have lots of different objects on screen all of different class types, and need to z-order them to enable me to draw them in the correct order on screen depending on their y-position.

However being different class types, obviously I can't put them all in the same list as a list needs to have a defined type.

Is there another (better?) way to do this other than creating a base class holding x/y values and extending every other class from this?
Would having a list defined to hold this base class even allow me to include the extended classes in the same list?

I can't test it myself atm as I am away from my computer at the moment, but am hoping to get cracking on this when I get home later today so thought I would post for pointers in the meantime.

Cheers.


Shagwana(Posted 2013) [#2]
You can use a Interface and implement the methods for drawing in each. That way you can put different types of classes into the same list.

Interface zdraw_i
	Method depth:Int()
	Method draw:Void()
End Interface


Class monkey_c Implements zdraw_i

	Field iDepth:Int

	Method depth:Int()
		Return iDepth
	End Method

	Method draw:Void()
		Print "draw the monkey"
	End Method
End Class


Class cow_c Implements zdraw_i

	Field iZPos:Int

	Method depth:Int()
		Return iZPos
	End Method

	Method draw:Void()
		Print "draw the cow"
	End Method
End Class



Function Main()
	Local zlist:=New List<zdraw_i>
	zlist.AddLast( New monkey_c )
	zlist.AddLast( New cow_c )

	'sort the list using some sort of depth value (for z order)
	'this can be done using the depth() method implemented above

	'now draw the list in sorted order
	For Local o:=Eachin zlist
		o.draw()
	Next

End Function


However I think the best way to do this is have a base class and use that. This way more common shared attributes can be pooled into less lines of code resulting in less bugs.


Gerry Quinn(Posted 2013) [#3]
One way to do it without a base class or common interface is to make some kind of 'wrapper' object that would direct it to the correct list:

Class OrderedItem
	Field alien:Alien
	Field asteroid:Asteroid
End	


You could make a list of OrderedItems and order them in whatever fashion you please. When iterating through the list, you would check which field was non-null and call its draw function, and your compare function could also take the type into account, if you have to call different functions to get the coordinates.

If there were many types, you could have an integer field that directs you quickly to a particular type.

One virtue of this method is that it doesn't matter if some of the items are in different container types, or not in a container at all (other than your list of OrderedItems).

On the downside, it is a little clunky...


rIKmAN(Posted 2013) [#4]
Thanks for the replies guys, most helpful! :)

Which way would be the most accepted OOP method, the base class and extending way?

Should I assume from the replies that I can have objects of different classes in the same list as long as they all extend from a single base class, and that the list of of type <baseclass>?


Nobuyuki(Posted 2013) [#5]
probably the best method is to use an interface. You won't get "stuck" later on if the superclass didn't account for some other thing you needed to add later.

Shove all interface objects into a sort list and draw them separate from your other containers, that's what I would do. A series of containers just for draw order.


Gerry Quinn(Posted 2013) [#6]
I like the interface method too. Actually I rarely use interfaces, but when I looked at this it seemed like a great example of how to benefit from them outside of the classic case of a library of controls etc. that all have common functions.

The base class method is fine if you have planned everything in advance, e.g. if you are porting something that you already wrote.

My method is for when you already have a mess but you must make it work ;-) I just threw it out there as an option since you were looking for different ways to handle the situation.


rIKmAN(Posted 2013) [#7]
I have never used interfaces before myself either, so big thanks to shagwana for the code example which has made it much easier to get my head around.

I'm not porting existing code, and I wouldn't say I am in a mess already (yet lol!), but as I have been working on other parts of the game for so long now the z-ordering problem is something I actually actually didn't think about until the problem reared it's head the other night and I had my "doh" moment.

I'm back at home now so am going to have a play with interfaces, and I have found a couple of other ideas on the forum involving using an array of lists with the array position relating to the vertical position on screen, which also makes sense.

The actual vertical area I am managing will only be around 400px so that may also work, although I think the interfaces way looks to be the way forward in terms of extensibility and moving forward.

I also have to do some homework on sorting methods.

Thanks for all the input :)

EDIT:
I have the Interfaces way working...can't believe how easy it was, thanks a lot shagwana! :)
Now onto sorting...