我正在使用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中实现形状绘制?有人可以解释为什么这两个调用的工作方式不同吗?
答案 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();
}