J'utilise scene2d. Voici mon code:
group.addActor(new Actor() {
@Override
public Actor hit(float arg0, float arg1) {return null;}
@Override
public void draw(SpriteBatch batch, float arg1) {
batch.end();
shapeRenderer.begin(ShapeType.FilledRectangle);
shapeRenderer.setColor(Color.RED);
shapeRenderer.filledRect(0, 0, 300, 20);
shapeRenderer.end();
batch.begin();
}
});
Le problème est qu'il dessine ce rectangle par rapport à écran (x = 0, y = 0), mais j'ai besoin qu'il soit dessiné par rapport à mon groupe. Mais si je dessine d'autres entités avec:
batch.draw(texture, 0, 0, width, height);
il dessine correctement à (x = 0, y = 0) par rapport à mon groupe (0,0 pixels à partir du coin inférieur gauche du groupe).
Des suggestions comment puis-je implémenter le dessin de forme dans scene2d? Et quelqu'un peut-il expliquer pourquoi ces deux appels fonctionnent différemment?
ShapeRenderer a sa propre matrice de transformation et sa propre matrice de projection. Ceux-ci sont distincts de ceux du SpriteBatch que la scene2d Stage utilise. Si vous mettez à jour les matrices de ShapeRenderer pour qu'elles correspondent à celles que scene2d utilise lorsque Actor.draw () est appelé, vous devriez obtenir les résultats souhaités.
Comme Rod Hyde le mentionne, ShapeRenderer a sa propre matrice de transformation et sa propre matrice de projection. Vous devez donc d'abord obtenir la matrice de projection du SpriteBatch. Je ne sais pas s'il existe une manière élégante de le faire, je l'ai fait comme ceci:
public class myActor extends Actor{
private ShapeRenderer shapeRenderer;
static private boolean projectionMatrixSet;
public myActor(){
shapeRenderer = new ShapeRenderer();
projectionMatrixSet = false;
}
@Override
public void draw(SpriteBatch batch, float alpha){
batch.end();
if(!projectionMatrixSet){
shapeRenderer.setProjectionMatrix(batch.getProjectionMatrix());
}
shapeRenderer.begin(ShapeType.Filled);
shapeRenderer.setColor(Color.RED);
shapeRenderer.rect(0, 0, 50, 50);
shapeRenderer.end();
batch.begin();
}
}
La meilleure solution pour moi. Parce que lorsque vous utilisez ShapeRenderer, il ne réagit pas au déplacement/zoom de la caméra.
public class Rectangle extends Actor {
private Texture texture;
public Rectangle(float x, float y, float width, float height, Color color) {
createTexture((int)width, (int)height, color);
setX(x);
setY(y);
setWidth(width);
setHeight(height);
}
private void createTexture(int width, int height, Color color) {
Pixmap pixmap = new Pixmap(width, height, Pixmap.Format.RGBA8888);
pixmap.setColor(color);
pixmap.fillRectangle(0, 0, width, height);
texture = new Texture(pixmap);
pixmap.dispose();
}
@Override
public void draw(Batch batch, float parentAlpha) {
Color color = getColor();
batch.setColor(color.r, color.g, color.b, color.a * parentAlpha);
batch.draw(texture, getX(), getY(), getWidth(), getHeight());
}
}
Vous devez convertir les coordonnées locales de l'acteur en coordonnées d'écran. En supposant que votre scène est en plein écran, vous pouvez simplement utiliser Actor.localToStageCoordinates :
vec.set(getX(), getY());
this.localToStageCoordinates(/* in/out */ vec);
shapeRenderer.filledRect(vec.x, vec.y, getWidth(), getHeight());
Où vec
est un Vector2d
Privé (vous ne voulez pas en allouer un nouveau à chaque appel de rendu).
Cela suppose également que votre ShapeRenderer
est défini pour être mappé en plein écran (qui est la valeur par défaut).
De plus, si vous passez du ShapeRenderer
et revenez au SpriteBatch
, notez que le batch
est déjà ajusté aux coordonnées de l'acteur (et donc vous pouvez utiliser getX()
et getY()
directement avec batch.draw(...)
.