2013-03-13 65 views
10

我正在使用scene2d。这是我的代码:Libgdx - 如何在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),但我需要它能够相吸引到我的。但是,如果我可以吸引其他实体:

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

它正确地绘制在(X = 0,Y = 0)相对我的组(从组的左下角0,0像素)。

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

回答

16

ShapeRenderer有它自己的变换矩阵和投影矩阵。这些场景与场景2d Stage使用的SpriteBatch中的场景分开。如果更新ShapeRenderer的矩阵以匹配那些调用Actor.draw()时scene2d正在使用的矩阵,那么您应该得到所需的结果。

+1

最近我不得不这样做 - 我从传递到draw()方法的SpriteBatch中设置ShapeRenderer的变换和投影矩阵。它看起来效率不高,但它的工作原理。 – locka 2014-04-02 10:02:08

2

您需要将Actor的本地坐标转换为屏幕坐标。假设你的阶段是全屏幕,你可以用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已经被调整到演员坐标(这样的话你可以用batch.draw(...)直接使用getX()getY()

+0

1)演员没有.lovaltoStageCoordingates,只有.toLocalCoordinates。 2),我不明白如何使用它(ProgressBar是Group):'batch.end(); \t \t \t \t vec.set(ProgressBar.this.x,ProgressBar.this.y); \t \t \t \t this.toLocalCoordinates(vec); \t \t \t \t shapeRenderer.begin(ShapeType。FilledRectangle); \t \t \t \t shapeRenderer.setColor(Color.BLACK); \t \t \t \t shapeRenderer.filledRect(vec.x + 11,vec.y + 11,barMaxWidth,20); \t \t \t \t shapeRenderer.end();'。我不明白我需要把'vec.set()'。 – Aleksandrs 2013-03-14 07:47:12

+0

我如何从javadoc了解到:“将舞台坐标中的指定点转换为演员的局部坐标系。”例如我把x = 0;对于这个矩形在舞台坐标(它是左下角)y = 0并且在我调用.toLocalCoordinates()之后,它应该重新计算它们并且放在左下角角角处。 – Aleksandrs 2013-03-14 07:51:18

+0

我随机为ex设置。 vec.set(0,800);并且我得到了我的进度条群组翻转,当我滚动页面时,这些进度条会飞到另一边。参考:我有scene2d结构阶段 - >组 - >表 - >组 - >演员 – Aleksandrs 2013-03-14 20:01:39

6

当杆海德提到。,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

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