您好,我在 libGdx 中遇到了闪烁纹理的问题。我到处都找过了,但没有找到解决办法。
当我使用 show(Stage stage)方法更改对话框时,纹理仅闪烁。基本上有 2 个渲染调用。第一个来自我绘制纹理的渲染,第二个是 Stage 类中的绘制方法。
当我更改对话框时,第一个不应闪烁。这很烦人,我不知道如何解决这个问题。
应用程序类:
import com.badlogic.gdx.ApplicationListener;
import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.OrthographicCamera;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g2d.TextureRegion;
import com.badlogic.gdx.scenes.scene2d.Stage;
import com.badlogic.gdx.scenes.scene2d.ui.Dialog;
import com.badlogic.gdx.scenes.scene2d.ui.Label.LabelStyle;
import com.badlogic.gdx.scenes.scene2d.ui.Skin;
import com.badlogic.gdx.scenes.scene2d.ui.Table;
import com.badlogic.gdx.scenes.scene2d.ui.TextButton.TextButtonStyle;
import com.badlogic.gdx.scenes.scene2d.ui.Window.WindowStyle;
import com.badlogic.gdx.scenes.scene2d.utils.Drawable;
import com.badlogic.gdx.scenes.scene2d.utils.TextureRegionDrawable;
import com.badlogic.gdx.utils.Scaling;
import com.badlogic.gdx.utils.viewport.ScalingViewport;
import com.badlogic.gdx.utils.viewport.StretchViewport;
public class FlickerGame implements ApplicationListener {
private SpriteBatch batch;
private StretchViewport viewport;
private HUD hud;
private Texture texture;
private BitmapFont font;
@Override
public void create() {
// use only one SpriteBatch in game
batch = new SpriteBatch();
viewport = new StretchViewport( Gdx.graphics.getWidth(), Gdx.graphics.getHeight() );
texture = new Texture( Gdx.files.local( "badlogic.jpg" ) );
font = new BitmapFont();
hud = new HUD( batch, getSkin() );
Gdx.input.setInputProcessor( hud );
}
@Override
public void dispose() {
batch.dispose();
hud.dispose();
texture.dispose();
font.dispose();
}
@Override
public void resize( int width, int height ) {
viewport.update( width, height, true );
hud.getViewport().update( width, height, true );
}
@Override
public void render() {
float delta = Gdx.graphics.getDeltaTime();
Gdx.gl.glClearColor( 0, 0, 0, 1 );
Gdx.gl.glClear( GL20.GL_COLOR_BUFFER_BIT );
// draw the texture on the whole screen
batch.setProjectionMatrix( viewport.getCamera().combined );
batch.begin();
batch.draw( texture, 0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight() );
batch.end();
hud.act( delta );
hud.draw();
}
@Override public void pause() {}
@Override public void resume() {}
private Skin getSkin(){
Skin skin = new Skin();
// just add a part of the badlogic.jpg as button looks awful its just for testing
Drawable up = new TextureRegionDrawable( new TextureRegion( texture, 0, 0, 50, 8 ) );
skin.add( DEFAULT, new WindowStyle( font, Color.WHITE, null ), WindowStyle.class );
skin.add( DEFAULT, new LabelStyle( font, Color.WHITE ), LabelStyle.class );
skin.add( DEFAULT, new TextButtonStyle( up, null, null, font ), TextButtonStyle.class );
return skin;
}
private static final String DEFAULT = "default";
}
我实现对话框的 HUD 类。
class HUD extends Stage {
private Dialog menu;
private Dialog about;
private Dialog exit;
public HUD( SpriteBatch batch, Skin skin ){
super( new ScalingViewport( Scaling.stretch, 0.3f * Gdx.graphics.getWidth(), 0.3f * Gdx.graphics.getHeight(), new OrthographicCamera() ), batch );
final Stage stage = this;
menu = new Dialog( "menu", skin ){
@Override
public void result( Object object ){
if ( object instanceof Integer ){
switch ( (Integer) object ){
case 0:
// play button doesn't do anything at the moment
Gdx.app.log( "Button", "play" );
break;
case 1: about.show( stage ); break;
case 2: exit.show( stage ); break;
}
}
}
};
Table menuButtons = menu.getButtonTable();
menu.button( "play", 0 );
menuButtons.row();
menu.button( "credits", 1 );
menuButtons.row();
menu.button( "exit", 2 );
about = new Dialog( "credits", skin ){
@Override
public void result( Object object ){
menu.show( stage );
}
};
about.text( "made by me!" );
about.button( "back" );
exit = new Dialog( "", skin ){
@Override
public void result( Object object ){
if ( object instanceof Boolean ){
if ( (Boolean) object ){
Gdx.app.exit();
} else {
menu.show( stage );
}
}
}
};
exit.text( "Are you sure you want to exit?" );
exit.button( "yes", true );
exit.button( "no", false );
menu.show( this );
}
}
对于关闭,解决方案只是在 HUD 类中创建一个新的 SpriteBatch,如下所示:
super( new ScalingViewport(
Scaling.stretch,
0.3f * Gdx.graphics.getWidth(),
0.3f * Gdx.graphics.getHeight(),
new OrthographicCamera() ),
new SpriteBatch()
);
根本没有发生闪烁。 wiki 解释说“SpriteBatch 是一个相当重的对象,所以你的程序中应该只包含一个。”所以不建议这样做。
很可能 SpriteBatch 的颜色发生了变化。绘图代码不会尝试保留以前的颜色,因为这将需要大量不必要的颜色更改。在绘制背景或其他任何内容之前将其设置为白色。