How to draw several copies of the same actor on one stage at different positions?

二次信任 提交于 2019-12-13 21:20:57

问题


I want to draw several copies of an actor on the same stage.

Here what I've done :

// class Test

public class Test extends Image {

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

} // end of test class

// class MyStage

public class MyStage extends Stage {

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

} // end of MyStage class


回答1:


you cannot just simply duplicate Actor instance or add it more than once to the Stage, although you can assign for example the same Texture to all of them (but I'm not sure if it is reasonable - maybe because of memory when having dozens of same actor it is).

You can test it in very simple way:

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

The best idea in my opinion is to create ActorFactory and for less complicated examples like your just the method returning new instance of the Actor

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

Then you can just deal with it like

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

One thing more - if adding actor copies to the stage is the only reason you are extending it please don't. It will make your application far less flexible in future.




回答2:


First of all, your setBounds method should probably copy the values rather than the reference, so you don't risk passing the same Rectangle object to multiple different actors.

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

Add a method to your Test class that allows you to make a copy from a prototype:

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

Although in your case, you are assigning them different bounds anyway, so this is currently unnecessary. It is a mistake to be loading the texture from within the class constructor, because this will cause every instance of the class to load a duplicate copy of the texture when they could all be sharing a single copy. So really your constructors should be like this:

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

Now it makes sense to make copies of this. So to set up your test case:

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

}


来源:https://stackoverflow.com/questions/32372804/how-to-draw-several-copies-of-the-same-actor-on-one-stage-at-different-positions

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!