2014-02-07 3 views
3

Я хочу изменить фоновое изображение меню каждые x-количество секунд. Я использую libGDX scene2D.ui для создания меню. Класс TestScreen расширяет AbstractScreen, который является абстрактным классом, который реализует класс Screen библиотеки libGDX. Проблема: после загрузки изображения на сцену через объект таблицы в стеке изменение ссылки на изображение на другое изображение ничего не делает. Stage.draw() не дает никаких забот, как если бы он сделал копию моего исходного изображения. Я хотел бы сохранить фон как класс изображения и визуализировать через stage.draw().libgdx background Изменение изображения

Чтобы еще больше усложнить ситуацию, если я изменил изображение на другой в методе render(), то функция image.setVisible (false) также перестает работать.

public class TestScreen extends AbstractScreen { 

private Stage stage; 
private Image background; 
private boolean ChangeBackground = true; 
private final float refreshTime = 2.0f; // refresh to new image every 2 seconds. 
private float counter = refreshTime; 

public TestScreen(Game game) { 
    super(game); 
} 

@Override 
public void render(float deltaTime) { 
    Gdx.gl.glClearColor(0.0f, 0.0f, 0.0f, 1.0f); 
    Gdx.gl.glClear(GL10.GL_COLOR_BUFFER_BIT); 

    if(ChangeBackground){ 
     counter -= deltaTime; 
     if(counter < 0){ 
      counter = refreshTime; 
      // Assets class has the 12 images loaded as "Image" objects already. 
      // I simple want to change the reference to other (already loaded in memory images) ... 
      // and make stage render the new image. 
      background = Assets.instance.wallpapers[(int) (Math.random()*12)]; // The image should change. 
      //background.setVisible(false); 
     } 
    } 
    stage.act(deltaTime); 
    stage.draw(); 
} 

@Override 
public void resize(int width, int height) { 
    stage.setViewport(Constants.VIEWPORT_GUI_WIDTH, Constants.VIEWPORT_GUI_HEIGHT, false); 
} 
@Override 
public void show() { 
    stage = new Stage(); 
    Gdx.input.setInputProcessor(stage); 
    makeStage(); 
} 
@Override 
public void hide() { 
    stage.dispose(); 
} 
@Override 
public void pause() { 
} 

// Builds the Background later and adds it to a stage through a stack. 
// This is how it's done in my game. I made this test bench to demonstrate. 
private void makeStage() { 
    Table BackGroundLayer = new Table(); 
    background = Assets.instance.wallpapers[(int) (Math.random()*12)]; 
    BackGroundLayer.add(background); 

    Stack layers = new Stack(); 
    layers.setSize(800, 480); 
    layers.add(BackGroundLayer); 

    stage.clear(); 
    stage.addActor(layers); 
} 

}

+0

Try вызвать Table.invalidate() после изменения изображения. – Viacheslav

+0

Пробовал это, и он не работал. Я сделал BackGroundLayer объектом класса и вызвал метод .invalidate() после изменения Image в методе рендеринга. Решение ниже работало красиво, хотя :) – Artash

ответ

6

Image является подклассом Actor. Главное отличие состоит в том, что Image имеет Drawable внутри. Это Drawable получает обратный код, если вы звоните stage.draw(), который вызывает draw()Image. Вместо изменения Image вы можете изменить Drawable с помощью setDrawable(Drawable param);. Что такое Drawable? Это любой класс, который реализует интерфейс Drawable, например TextureRegionDrawable. Если вы используете TextureRegion s, вы можете использовать этот конструктор: TextureRegionDrawable(TextureRegion region);. Возможно, было бы лучше сохранить ваши фоновые изображения в массиве Drawable, поэтому вам не нужно вызывать конструктор каждый раз, когда вы устанавливаете новый Drawable. Пример кода:

TextureRegionDrawable[] images = new TextureRegionDrawable[12]; 
for (int i = 0; i<12; i++) { 
    images[i] = new TextureRegionDrawable(Assets.instance.textureRegions[i]); 
} 

Тогда в рендеринге:

if(changeBackground) { 
    counter -= delta; 
    if (counter < 0) { 
     counter = refreshtime 
     background.setDrawable(images[(int)(Math.random()*12)]); 
    } 
} 

Это должно работать

+1

Это сработало очень красиво! Спасибо :) – Artash

Смежные вопросы