Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Making a Group hide Actors outside of its bounds

I have created a very simple plot that is dynamically updated by adding new images on the right side of the screen, and then making them move towards the left side. This way, the plot within the screen's bounds looks like they are plotted as time goes by.

Unfortunately, when doing it this way, I have to let the images start outside of the screen, and move into view, and I can't remove them again before they are completely outside of the screen on the left side. This results in the images being partially visible outside of the screen's bounds.

The control is created as a Group that contains two static images (a black background and the image of the screen as foreground), plus all the moving images in between. This Group is then added to my Stage (like all other actors), and drawn as part of the Stage.

In the image below, the control's bounds are marked with red. I would like to hide the parts of the moving images that are outside of these bounds. Is this possible to do using some libGDX functionality I have missed? By somehow constraining the Group's drawing area, perhaps?

An illustration of how the screen works.

My other alternatives are to draw parts of the blue background in front of the screen, to hide the outliers, or to make the screen's edges thick enough to hide them. I think that both these solutions are unnecessarily inconvenient, and I'm pretty sure there is a better way to do this.

Any suggestions?

like image 889
Erlend D. Avatar asked Jul 10 '13 13:07

Erlend D.


1 Answers

The solution was to use the ScissorStack.

@Override
public void draw(SpriteBatch batch, float parentAlpha) {

    //Create a scissor recangle that covers my Actor.
    Rectangle scissors = new Rectangle();
    Rectangle clipBounds = new Rectangle(getX(),getY(),getWidth(),getHeight());
    ScissorStack.calculateScissors(camera, batch.getTransformMatrix(), clipBounds, scissors);
    batch.flush(); //Make sure nothing is clipped before we want it to.
    ScissorStack.pushScissors(scissors);

    //Draw the actor as usual
    super.draw(batch, parentAlpha);

    //Perform the actual clipping
    ScissorStack.popScissors();
}
like image 52
Erlend D. Avatar answered Nov 15 '22 10:11

Erlend D.