12

我正在使用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();
    }
});

问题是它相对于屏幕(x = 0,y = 0)绘制这个矩形,但我需要相对于我的group绘制它。但是,如果我用以下方法绘制其他实体:

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

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

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

4

5 回答 5

19

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

于 2013-03-13T22:16:39.850 回答
14

正如 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();
    }
}
于 2014-08-16T09:27:24.317 回答
7

对我来说最好的解决方案。因为当您使用 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());
    }
}
于 2016-01-08T02:37:23.183 回答
3

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

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

vec私有的在哪里Vector2d(您不想在每个渲染调用上分配一个新的)。

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

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

于 2013-03-13T22:20:19.443 回答
1

如果您正在使用ShapeRenderer不要忘记使用setProjectionMatrix()setTransformMatrix()方法...

Actorondraw方法内的绘制圆示例:

@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();
}
于 2020-10-10T20:09:14.960 回答