LibGDX - 来自自定义 class 的 Sprite 未显示

LibGDX - Sprite from custom class is not showing up

我已经花了大约 6 个小时试图解决这个问题... 我有 2 个 类(PlayerUiButton),它们都是 extends Sprite。 问题是来自 PlayerSprite 正在渲染 而来自 UiButton 不是.

这里,看一下代码:

Player.java(简化)

public class Player extends Sprite
{
    public Player( float posX, float posY )
    {
        super( new Texture( Gdx.files.internal( "character/char_idle.png" ) ) );
        super.setPosition( posX, posY );
    }
}

UiButton.java

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.graphics.Texture;
import com.badlogic.gdx.graphics.g2d.Sprite;

public class UiButton extends Sprite
{
    public UiButton( Texture texture, float posX, float posY, float rotation )
    {
        super( new Texture( Gdx.files.internal( "ui/arrow.png" ) ) );

        setPosition( posX, posY );
        setRotation( rotation );
    }

    public UiButton( UiButton button )
    {
        super( );
    }

    public void setSize( float toWidth, float toHeight )
    {
        float scaleX = toWidth / super.getWidth( );
        float scaleY = toHeight / super.getHeight( );

        setScale( scaleX, scaleY );
    }

    public boolean isTouched( int touchX, int touchY )
    {
        if( touchX >= getX( ) && touchX <= getX( ) + getWidth( ) )
            if( touchY >= getY( ) && touchY <= getY( ) + getHeight( ) )
                return true;

        return false;
    }

}

GameEngine.java(不是整个文件,而是所需的函数和变量)

public class GameEngine extends ApplicationAdapter implements ApplicationListener
{
    private SpriteBatch spriteBatch;
    private Player      player;
    private Sprite      grid;

    private UiButton arrow_right;
    private UiButton arrow_left;
    private UiButton arrow_down;
    private UiButton arrow_up;

    @Override public void create( )
    {
        /** Setting InputProcessor **/
        InitializeInputProcessor( );

        /** Initializing SpriteBatch **/
        spriteBatch = new SpriteBatch( );
        spriteBatch.maxSpritesInBatch = 10;

        /** Creating UI **/
        GenerateUiArrows( 10, Gdx.graphics.getHeight( ) / 4 );

        /** Creating Player **/
        player = new Player( 100, 100 );

        /** Creating background grid **/
        grid = new Sprite( new Texture( generateGrid( 50 ) ) );
    }

    @Override public void dispose( )
    {
        spriteBatch.dispose( );
    }

    public void doUpdating( )
    {
        player.update( );
    }

    public void doRendering( )
    {
        /** Clearing the screen **/
        Gdx.gl.glClearColor( 1, 1, 1, 1 );
        Gdx.gl.glClear( GL20.GL_COLOR_BUFFER_BIT );

        /** Beginning SpriteBatch rendering **/
        spriteBatch.begin( );

        /** Drawing background grid **/
        grid.draw( spriteBatch );

        /** Drawing Player **/
        player.draw( spriteBatch );

        /** Drawing UI **/
        arrow_right.draw( spriteBatch );
        arrow_left.draw( spriteBatch );
        arrow_down.draw( spriteBatch );
        arrow_up.draw( spriteBatch );

        /** Ending SpriteBatch rendering **/
        spriteBatch.end( );
    }

    @Override public void render( )
    {
        doUpdating( );
        doRendering( );

        /******************************************/
        /** Here was a loop to control framerate **/
        /******************************************/
    }

    private Pixmap generateGrid( int interval )
    {
        /** Creating temporary Pixmap **/
        Pixmap tempMap = new Pixmap( Gdx.graphics.getWidth( ), Gdx.graphics.getHeight( ), Pixmap.Format.RGBA8888 );

        /** Setting lines color to BLACK **/
        tempMap.setColor( Color.BLACK );

        /** Creating horizontal lines **/
        for( int i = interval; i < Gdx.graphics.getWidth( ); i += interval )
            tempMap.drawLine( i, 0, i, Gdx.graphics.getHeight( ) );

        /** Creating vertical lines **/
        for( int i = interval; i < Gdx.graphics.getHeight( ); i += interval )
            tempMap.drawLine( 0, i, Gdx.graphics.getWidth( ), i );

        /** Returning the result **/
        return tempMap;
    }

    private void GenerateUiArrows( float padding, float button_size )
    {
        arrow_right = new UiButton( new Texture( Gdx.files.internal( "ui/arrow.png" ) ), button_size * 2 + padding * 3, padding, 90 );
        arrow_right.setSize( button_size, button_size );

        arrow_left = new UiButton( new Texture( Gdx.files.internal( "ui/arrow.png" ) ), padding, padding, 270 );
        arrow_left.setSize( button_size, button_size );

        arrow_down = new UiButton( new Texture( Gdx.files.internal( "ui/arrow.png" ) ), button_size + padding * 2, padding, 180 );
        arrow_down.setSize( button_size, button_size );

        arrow_up = new UiButton( new Texture( Gdx.files.internal( "ui/arrow.png" ) ), button_size + padding * 2, button_size + padding * 2, 0 );
        arrow_up.setSize( button_size, button_size );
    }

}

未显示任何错误或警告。只有 UiButtons 没有被渲染。我还没有设置 OrthographicCamera。所以也不应该是这样...

你的问题出在 UiButton 的 setSize() 方法中 class:

    public void setSize( float toWidth, float toHeight )
    {
        //System.out.println("super.width = " + super.getWidth() + ", super.height = " + super.getHeight() ); - you can uncomment it to see the super width/height value in the console

        float scaleX = toWidth / super.getWidth( );
        float scaleY = toHeight / super.getHeight( );

        setScale( scaleX, scaleY );
    }

super.getWidth()super.getHeight() returns 都归零(因为你还没有为超级 class 对象设置任何 width/height)。然后在 scaleX/scaleY 变量中你有 infinity 值——你可以通过在我的代码中取消注释标记行来看到它。

有趣的是 Java 允许您除以浮点零 - 返回提到的 infinity 值 (read more here) 这就是为什么您不那里没有例外。

解决方案 是通过调用 super.setSize(width,height) 来修复这个方法,或者干脆删除它并依靠默认的 Sprite class setSize() 方法实现。


还有一件事 - 解决问题后你会发现旋转问题 - 它与原点有关。您可以将 setSize 方法更改为

    @Override
    public void setSize(float w, float h)
    {
        super.setSize(w,h);

        setOrigin(w/2f, h/2f);
    }

它会做这件事