web-dev-qa-db-ja.com

Libgdx-塗りつぶされた長方形をscene2dの適切な場所に描画する方法

私はscene2dを使用しています。これが私のコードです:

    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();
        }
    });

問題はscreen(x = 0、y = 0)に対してこの長方形を描画することですが、-groupに対して描画する必要があります。しかし、私が他のエンティティを描画すると:

batch.draw(texture, 0, 0, width, height);

グループ(x = 0、y = 0)に正しく描画します(グループの左下隅から0,0ピクセル)。

どのような方法で、scene2dにシェイプ描画を実装できますか?そして、これら2つの呼び出しが異なる動作をする理由を誰かが説明できますか?

12
Aleksandrs

ShapeRenderer には独自の変換行列と投影行列があります。これらは、scene2d Stage が使用する SpriteBatch のそれらとは別のものです。 ShapeRendererの行列を更新して、scene2dが使用しているものと一致するように Actor.draw() が呼び出された場合、必要な結果が得られるはずです。

19
Rod Hyde

Rod Hydeが述べているように、ShapeRendererには独自の変換行列と投影行列があります。したがって、最初にSpriteBatchのプロジェクションマトリックスを取得する必要があります。エレガントな方法があるかどうかはわかりませんが、次のようにしました。

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();

   }
}
13
Julien

私にとって最良の解決策。 ShapeRendererを使用すると、カメラの移動/ズームに反応しなくなります。

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());
    }
}
6
Alexandr

アクターのローカル座標をスクリーン座標に変換する必要があります。ステージがフルスクリーンであると仮定すると、 Actor.localToStageCoordinates を使用できます。

_vec.set(getX(), getY());
this.localToStageCoordinates(/* in/out */ vec);
shapeRenderer.filledRect(vec.x, vec.y, getWidth(), getHeight());
_

ここで、vecはプライベート_Vector2d_です(レンダーコールごとに新しいものを割り当てたくありません)。

これは、ShapeRendererがフルスクリーンにマップされるように定義されていることも前提としています(これがデフォルトです)。

また、ShapeRendererからSpriteBatchに切り替えた場合、batchは既にアクター座標に調整されていることに注意してください(したがって、getX()およびgetY()batch.draw(...)を直接使用します。

3
P.T.