【问题标题】:How to draw several copies of the same actor on one stage at different positions?如何在一个舞台上不同位置绘制同一个演员的多个副本?
【发布时间】:2015-09-03 10:11:57
【问题描述】:

我想在同一个舞台上画几个演员的副本。

这是我所做的:

// 类测试

公共类测试扩展图像{

private Sprite sprite;
private Rectangle bounds;
private final float HEIGHT = Gdx.graphics.getHeight();

public Test() {

    // Sprite
    Texture texture = new Texture("img.png");
    texture.setFilter(TextureFilter.Linear, TextureFilter.Linear);
    sprite = new Sprite(texture);

    // adjusting sprite size to different resolutions
    float imgHeightRatio = 120.0f / 480.0f;
    float imgWidthHeightRatio = sprite.getWidth() / sprite.getHeight();


    float newHeight = imgHeightRatio * HEIGHT;
    float newWidth = imgWidthHeightRatio * newHeight;

    clockSprite.setSize(newWidth, newHeight);

    // setting the size of the actor
    setSize(sprite.getWidth(), sprite.getHeight());


    // sprite bounds
    bounds = new Rectangle();
}

public void setBounds(Rectangle bounds) {
    this.bounds = bounds;
}

@Override
public void draw(Batch batch, float parentAlpha) {
// drawing sprite
    batch.draw(sprite, bounds.x, bounds.y, bounds.getWidth(), bounds.getHeight());
}

} // 测试类结束

// MyStage 类

公共类 MyStage 扩展舞台 {

private Array<Test> actors;
private Rectangle rect1, rect2, rect3;

public MyStage(Test t) {
    // Rectangles
    rect1 = new Rectangle(0, 0, t.getWidth(), t.getHeight());
    rect2 = new Rectangle(30, 30, t.getWidth(), t.getHeight());
    rect3 = new Rectangle(60, 60, t.getWidth(), t.getHeight());

    actors = new Array<Test>();
    for(int i = 0; i < 3; i++) {
        actors.add(t);
    }

    for(Test test : actors) {
        addActor(test);
        test.setBounds(rect1);
        test.setBounds(rect2);
        test.setBounds(rect3);
    }

}


public void act(float dt) {
    super.act(dt);
}

@Override
public void draw() {
    super.draw();
}

public void dispose() {
    super.dispose();
}

} // MyStage 类结束

【问题讨论】:

    标签: libgdx


    【解决方案1】:

    您不能只是简单地复制 Actor 实例或将其多次添加到 Stage,尽管您可以分配例如相同的 Texture对他们所有人(但我不确定这是否合理 - 可能是因为有几十个相同的演员时的记忆)。

    您可以通过非常简单的方式对其进行测试:

    Stage stage;
    Actor a = new Actor();
    
    stage.addActor(a);
    
    System.out.println(stage.getActors().size);
    
    stage.addActor(a);
    
    System.out.println(stage.getActors().size); //same as above
    

    在我看来,最好的办法是创建 ActorFactory,对于不太复杂的示例,例如您的 返回 Actor 新实例的方法

    public Test getTestActor(float x, float y, float width, float height)
    {
        //here you are creating Test instance, giving it bounds etc
    }
    

    那么你就可以这样处理了

    stage.addActor ( getTestActor(0, 0, t.getWidth, t.getHeight)
    

    还有一件事 - 如果将演员副本添加到舞台是您扩展它的唯一原因,请不要这样做。这将使您的应用程序在未来变得不那么灵活。

    【讨论】:

      【解决方案2】:

      首先,您的 setBounds 方法可能应该复制值而不是引用,因此您不会冒险将同一个 Rectangle 对象传递给多个不同的参与者。

      public void setBounds(Rectangle bounds) {
          this.bounds.set(bounds);
      }
      

      向您的测试类添加一个允许您从原型制作副本的方法:

      public Test (Test test){
          this();
          setBounds(test.bounds);
      }
      

      尽管在您的情况下,无论如何您都在为它们分配不同的界限,因此目前没有必要这样做。从类构造函数中加载纹理是错误的,因为这将导致类的每个实例都加载纹理的副本,而它们都可以共享一个副本。所以真的你的构造函数应该是这样的:

      public Test(Texture texture) {
      
          sprite = new Sprite(texture);
      
          // adjusting sprite size to different resolutions
          float imgHeightRatio = 120.0f / 480.0f;
          float imgWidthHeightRatio = sprite.getWidth() / sprite.getHeight();
      
          float newHeight = imgHeightRatio * HEIGHT;
          float newWidth = imgWidthHeightRatio * newHeight;
      
          clockSprite.setSize(newWidth, newHeight);
      
          setSize(sprite.getWidth(), sprite.getHeight());
      
          // sprite bounds
          bounds = new Rectangle();
      }
      
      public Test (Test test){
          this();
          sprite.set(test.sprite);
          bounds.set(test.bounds);
      }
      

      现在复制它是有意义的。所以要设置你的测试用例:

      public MyStage(Test prototypeTest) {
          int width = prototypeTest.getWidth();
          int height = prototypeTest.getHeight();
          rect1 = new Rectangle(0, 0, width, height);
          rect2 = new Rectangle(30, 30, width, height);
          rect3 = new Rectangle(60, 60, width, height);
      
          actors = new Array<Test>();
          for(int i = 0; i < 3; i++) {
              actors.add(new Test(prototypeTest));
          }
      
          for(Test test : actors) {
              addActor(test);
              test.setBounds(rect1);
              test.setBounds(rect2);
              test.setBounds(rect3);
          }
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2013-04-04
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-12-08
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多