Libgdx - 如何在scene2d中的正确位置绘制填充矩形?

时间:2013-03-13 21:43:55

标签: drawing game-engine libgdx shapes rectangles

我正在使用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)绘制了这个矩形,但我需要相对于我的绘制它。但是如果我用其他实体绘制:

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

它相对于我的组(从组的左下角0,0像素)正确绘制(x = 0,y = 0)。

有什么建议我如何在scene2d中实现形状绘制?有人可以解释为什么这两个调用的工作方式不同吗?

5 个答案:

答案 0 :(得分:18)

ShapeRenderer有自己的变换矩阵和投影矩阵。这些内容与scene2d SpriteBatch使用的Stage中的内容分开。如果你更新ShapeRenderer的矩阵以匹配在调用Actor.draw()时scene2d正在使用的矩阵,那么你应该得到你想要的结果。

答案 1 :(得分:13)

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

   }
}

答案 2 :(得分:5)

对我来说是最好的解决方案。因为当你使用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());
    }
}

答案 3 :(得分:3)

您需要将Actor的本地坐标转换为屏幕坐标。假设您的舞台是全屏的,您可以使用Actor.localToStageCoordinates

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

其中vec是私有Vector2d(您不希望在每次渲染调用中分配新的){/ p>

这也假设您的ShapeRenderer被定义为映射到全屏(这是默认设置)。

此外,如果您从ShapeRenderer切换回SpriteBatch,请注意batch已经调整为Actor坐标(因此您可以使用getX() }和getY()直接与batch.draw(...)

答案 4 :(得分:0)

如果您使用的是ShapeRenderer,请不要忘记使用setProjectionMatrix()setTransformMatrix()方法...

Actor方法的draw内绘制圆的示例:

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

    batch.end();

    if (shapeRenderer == null) {
        shapeRenderer = new ShapeRenderer();
    }

    Gdx.gl.glEnable(GL20.GL_BLEND);
    shapeRenderer.setProjectionMatrix(batch.getProjectionMatrix());
    shapeRenderer.setTransformMatrix(batch.getTransformMatrix());
    shapeRenderer.setColor(mColor.r, mColor.g, mColor.b, mColor.a * parentAlpha);

    shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
    shapeRenderer.circle(getX() + getWidth()/2 , getY() + getHeight()/2 , Math.min(getWidth(),getHeight())/2 );
    shapeRenderer.end();
    Gdx.gl.glDisable(GL20.GL_BLEND);

    batch.begin();
}
相关问题