2013-03-13 71 views
10

Tôi đang sử dụng scene2d. Đây là mã của tôi:Libgdx - Làm thế nào để vẽ hình chữ nhật đầy ở đúng nơi trong 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(); 
     } 
    }); 

Vấn đề là nó thu hút tương đối hình chữ nhật này để màn hình (x = 0, y = 0), nhưng tôi cần nó được rút ra so với nhóm tôi. Nhưng nếu tôi vẽ các thực thể khác với:

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

nó vẽ chính xác tại (x = 0, y = 0) tương đối nhóm của tôi (0,0 pixel từ góc dưới cùng bên trái của nhóm).

Bất kỳ đề xuất nào tôi có thể triển khai vẽ hình dạng trong scene2d? Và ai đó có thể giải thích tại sao hai cuộc gọi này hoạt động khác nhau?

Trả lời

16

ShapeRenderer có ma trận biến đổi và ma trận chiếu riêng. Đây là những riêng biệt với những người trong SpriteBatch rằng scene2d Stage sử dụng. Nếu bạn cập nhật các ma trận của ShapeRenderer để khớp với các ma trận mà scene2d đang sử dụng khi Actor.draw() được gọi thì bạn sẽ nhận được kết quả mà bạn muốn.

+1

Tôi đã tự làm điều này gần đây - tôi đặt biến đổi và ma trận chiếu của ShapeRenderer từ SpriteBatch được chuyển vào phương thức draw(). Nó không có vẻ rất hiệu quả nhưng nó hoạt động. – locka

2

Bạn cần chuyển đổi toạ độ cục bộ của diễn viên thành tọa độ màn hình. Giả sử giai đoạn của bạn là toàn màn hình, bạn chỉ có thể sử dụng Actor.localToStageCoordinates:

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

đâu vec là một tin Vector2d (bạn không muốn phân bổ một cái mới trên mỗi cuộc gọi render).

Điều này cũng giả định rằng ShapeRenderer của bạn được xác định là ánh xạ tới toàn màn hình (mặc định).

Ngoài ra, nếu bạn chuyển ra khỏi ShapeRenderer và trở lại SpriteBatch, lưu ý rằng batch đã được điều chỉnh để tọa Diễn viên (và do đó bạn có thể sử dụng getX()getY() trực tiếp với batch.draw(...).

+0

1) Diễn viên không có .lovaltoStageCoordingates, chỉ .toLocalCoordinates. 2) và tôi không hiểu làm thế nào để sử dụng nó .. (ProgressBar là nhóm): '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(); '. Tôi không hiểu những gì tôi cần phải đặt vào 'vec.set()'. – Aleksandrs

+0

Cách tôi hiểu từ javadoc: "Chuyển đổi điểm đã chỉ định trong tọa độ của giai đoạn thành hệ tọa độ cục bộ của diễn viên." ví dụ tôi đặt x = 0; y = 0 cho hình chữ nhật này trong giai đoạn điều phối (nó là góc dưới cùng bên trái) Và sau khi tôi gọi .toLocalCoordinates() nó nên tính toán lại chúng và đặt ở góc trái phía dưới Actor .. – Aleksandrs

+0

Tôi đặt ngẫu nhiên cho ví dụ. vec.set (0, 800); và tôi nhận được thanh tiến trình của tôi bị lật ngang và khi tôi cuộn trang của tôi, những thanh tiến trình đó bay sang một bên khác. FYI: Tôi có cấu trúc scene2d Giai đoạn -> Nhóm -> Bảng -> Nhóm -> Diễn viên – Aleksandrs

6

Như Rod Hyde đề cập đến .., ShapeRenderer có của nó chuyển đổi riêng ma trận và ma trận chiếu Vì vậy, bạn sẽ có để có được ma trận chiếu của SpriteBatch đầu tiên tôi không chắc chắn nếu có một cách thanh lịch để làm điều đó, tôi đã làm điều đó như thế này:

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

Giải pháp tốt nhất cho tôi. Nguyên nhân khi bạn sử dụng ShapeRenderer nó không phản ứng khi di chuyển/phóng to camera.

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()); 
    } 
} 
Các vấn đề liên quan