This site requires JavaScript, please enable it in your browser!
Greenfoot back
K_wow
K_wow wrote ...

2013/10/8

How to create a position-based paint order system?

K_wow K_wow

2013/10/8

#
I am currently making a game with a view angle similar to pokemon, not completely top down, but not from the side either. Unfortunately when I make a game like this, the player with be either behind or in front of objects no matter what the position of the player is. For instance, when the player is in front of an object, it will show the player over the top, which is good. However, when the player is behind the same object, it will still show the player over the top, which I don't want. Does anyone know how to change this?
you can change paint order (what objects are drawn onto the screen first) with the World method:
1
setPaintOrder(java.lang.Class... classes)
So, if you want the player on top, do this:
1
[code]setPaintOrder(Block.class, Player.class)
On the bottom, you do:
1
setPaintOrder(Player.class, Block.class)
You can add as many classes as you want to this method. Just remember the ones listed first will be painted on top!
K_wow K_wow

2013/10/8

#
The problem with that is, what if the player is between two blocks? The player is either on top of both of them, or behind both of them.
danpost danpost

2013/10/8

#
As of now, you could remove and replace the block in front to place it over the player (after removing any 'setPaintOrder' statements).
K_wow K_wow

2013/10/10

#
I am very familiar with setting the paint order, but I confess I have no idea how to remove or reset it. Is there a method for that?
danpost danpost

2013/10/10

#
I would presume that just calling 'setPaintOrder' again would override any previous setting to the new one; but, I was saying not to have a 'setPaintOrder' statement at all. For any object you want placed overtop of another, save its world coordinates, remove it from the world, and 'addObject' it back at the same location. This will put it at the end of the list of actors in the world and will be painted last (on top). This may change in the future, but for now, it seems to work. So, basically, you would sort your actors from most distant from the 'camera' to the closest and apply that order to the list of actors in the world by removing and adding the actors.
mjrb4 mjrb4

2013/10/10

#
danpost wrote...
I would presume that just calling 'setPaintOrder' again would override any previous setting to the new one; but, I was saying not to have a 'setPaintOrder' statement at all. For any object you want placed overtop of another, save its world coordinates, remove it from the world, and 'addObject' it back at the same location. This will put it at the end of the list of actors in the world and will be painted last (on top). This may change in the future, but for now, it seems to work. So, basically, you would sort your actors from most distant from the 'camera' to the closest and apply that order to the list of actors in the world by removing and adding the actors.
Yup, this is the only way of achieving it at the moment on an object level - there's no `setPaintOrder()` method that deals with individual objects. As danpost says though this is an implementation quirk more than guaranteed behaviour, so it's completely possible this would change in a future release. The only other way of doing this would be to just subclass the class and have one type for background blocks, and the other for foreground blocks - but admittedly this isn't a scalable solution if you need to arbitrarily go between any blocks.
PhoebeZ PhoebeZ

2015/9/30

#
Are There any updates on this? I really want to find a way to set the paint order of individual objects. It would make my forest look much more realistic. currently I have this:
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
if(isTouching(WalnutTree.class))
        {
            wClose = (WalnutTree)getOneIntersectingObject(WalnutTree.class);
        }
        if(isTouching(WalnutTree.class) && wClose.getY() + 30 < getY())
        {
            getWorld().setPaintOrder(Walnut.class, RedPlum.class, YellowPlum.class, RingTailedLemur.class, WalnutTree.class);
        }
        if (isTouching(WalnutTree.class) && wClose.getY() + 30 > getY())
        {
            getWorld().setPaintOrder(Walnut.class, RedPlum.class, YellowPlum.class, WalnutTree.class, RingTailedLemur.class);
        }
 
        if(isTouching(RedPlumTree.class))
        {
            rClose = (RedPlumTree)getOneIntersectingObject(RedPlumTree.class);
        }
        if(isTouching(RedPlumTree.class) && rClose.getY() + 30 < getY())
        {
            getWorld().setPaintOrder(Walnut.class, RedPlum.class, YellowPlum.class, RingTailedLemur.class, RedPlumTree.class);
        }
        if (isTouching(RedPlumTree.class) && rClose.getY() + 30 > getY())
        {
            getWorld().setPaintOrder(Walnut.class, RedPlum.class, YellowPlum.class, RedPlumTree.class, RingTailedLemur.class);
        }
etc... Which works for one of my players, but when they both try to move through the forest only one of them can do it at a time. It also looks a bit strange because every tree of that class changes when the actor is near one. The only thing I can think to do is to make each tree a different class but that would be a huge pain in the ass. Not to mention I spent a long time making the trees randomly spawn in so they wouldn't be touching which is why I am using the close variables (if anyone is interested in seeing how to do that let me know, I am just barely starting to learn so there may be an easier way to do it but it took me some time to reason it out so I may just leave it). If anyone can think of a way to set the paintOrder of individual objects please let me know! I am dying to figure it out. Thanks!
You need to login to post a reply.