【问题标题】:Libgdx - How to draw filled rectangle in the right place in scene2d?Libgdx - 如何在scene2d的正确位置绘制填充矩形?
【发布时间】:2013-03-02 01:58:05
【问题描述】:

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

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

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

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

【问题讨论】:

    标签: drawing game-engine libgdx shapes rectangles


    【解决方案1】:

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

    【讨论】:

    • 我最近不得不自己做这件事——我从传递给 draw() 方法的 SpriteBatch 中设置了 ShapeRenderer 的变换和投影矩阵。它看起来效率不高,但确实有效。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

      【讨论】:

      • 这似乎工作得很好:创建一个你想要大小的纹理,然后绘制它。不要乱用形状渲染。
      【解决方案4】:

      您需要将 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 已经调整为Actor 坐标(因此您可以将getX()getY() 直接与@ 一起使用987654331@.

      【讨论】:

      • 1) Actor 没有 .lovaltoStageCoordingates,只有 .toLocalCoordinates。 2)我不明白如何使用它..(ProgressBar 是组):batch.end(); vec.set(ProgressBar.this.x, ProgressBar.this.y); this.toLocalCoordinates(vec); shapeRenderer.begin(ShapeType.FilledRectangle); shapeRenderer.setColor(Color.BLACK); shapeRenderer.filledRect(vec.x + 11, vec.y + 11, barMaxWidth, 20); shapeRenderer.end();。我不明白我需要向vec.set() 发送什么。
      • 我从 javadoc 中的理解:“将舞台坐标中的指定点转换为演员的局部坐标系。”例如我把 x = 0; y = 0 对于舞台坐标中的这个矩形(它是左下角)并且在我调用 .toLocalCoordinates() 之后,它应该重新计算它们并放入左下角的 Actor 角..
      • 我为ex随机设置。 vec.set(0, 800);我让我的进度条水平翻转,当我滚动页面时,这些进度条飞到另一边。仅供参考:我有 scene2d 结构 Stage -> Group -> Table -> Group -> Actor
      • 您使用的是旧版本的 Stage API,抱歉并不是要让您误入歧途。较旧的.toLocalCoordinateslocalToStageCoordinates相反(用于从舞台/屏幕转换为Actor)。你不想用它来渲染你的 Actor。可能最好将 @RodHyde 的方法与旧版本的 Libgdx 一起使用(也许也可以使用新版本)。
      【解决方案5】:

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

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

      @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();
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2012-07-23
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-07-11
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多