I'm using Android Studio with Java and LibGDX.
Android studio warns the draw
line with "Possible flush inside a loop", with this detailed description:
Inspection info: Looks for the possibility of a flush of a batch or renderer occuring inside a loop, either directly or indirectly. For performance reasons care should be taken to not cause unnecessary flushes, and to limit the number of flushes per frame as much as possible.
DelayedRemovalArray<MyEntity> myEntities = ...;
bricks.begin();
for(MyEntity myEntity : myEntities) {
myEntity.draw(game.getBatch()); // warning: Possible flush inside a loop
}
bricks.end();
the MyEntity.draw method:
Matrix4 tempMatrix = new Matrix4();
Matrix4 originalMatrix = new Matrix4();
NinePatchDrawable ninePatchDrawable = ...;
public void draw(SpriteBatch batch) {
originalMatrix.set(batch.getTransformMatrix());
tempMatrix.set(originalMatrix);
tempMatrix
.translate(myEntity.width/2, myEntity.height/2, 0)
.rotate(0, 0, myEntity.angle, 10)
.translate(-myEntity.width/2, -myEntity.height/2, 0);
batch.setTransformMatrix(tempMatrix);
ninePatchDrawable.draw(batch, ...);
batch.setTransformMatrix(originalMatrix);
}
If I remove the two batch.setTransformMatrix
calls, the warning goes away but I need to do that otherwise the ninepatch will not be draw at the right position, due to the fact that the ninepatch.draw method does not consider the body center when applying the rotation... About this issue with ninepatches I opened a dedicated SO question here
So, how to do it without receiving that warning? Is there a better way to do this?
Thanks
Do not position individual entities by setting the transform of the SpriteBatch
per entity, position individual entities with coordinates that make sense in the projection the batch is setup in.
Setting the transform matrix on a batch needs to flush whatever is already submitted to that batch as everything after will be drawn with another transform.
You can see that in the source code for SpriteBatch
.
You should normally not be changing the transform of the batch for each entity drawn using it, position and rotation of each entity is passed in the draw
call (otherwise the Batch
cannot batch anything).
Often what you want to do is to set the camera view on the SpriteBatch
before the begin
and then draw all entities that use that projection before calling end
.
In the case of a NinePatchDrawable
, just use the draw
method that allows you to specify the rotation, and if you want the rotation to happen around the center of the `NinePatchDrawable' adjust the origin by half the width and height:
ninePatchDrawable.draw(batch,
0, // x
0, // y
0.5f * entityWidth, // origin-x (rotation happens around this offset)
0.5f * entityHeight, // origin-y (rotation happens around this offset)
entityWidth,
entityHeight,
1.0f, // scale-x
1.0f, // scale-y
angle);