问题
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