3

I've been trying to figure this our for like 6 hours now... I have 2 classes ( Player and UiButton ), both of them extends Sprite. The problem is that the Sprite from Player is rendering and the one from UiButton is not.

Here, take a look at the code:

Player.java ( simplified )

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 ( not the whole file but the required functions and variables )

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

}

No errors or warnings are shown. Just UiButtons are not rendered. I haven't setted up OrthographicCamera yet. So it shouldn't be the case either...

Sw3das
  • 157
  • 1
  • 12
  • can you post your `arrow.png` image?, I would start with locating your buttons in the same position of your player – Alex S. Diaz Sep 18 '15 at 15:28
  • http://i.imgur.com/VBW99je.png - the `arrow.png`. And I have tried to set the same position as the player's... – Sw3das Sep 18 '15 at 15:30
  • try remove the rotation or to `setOriginCenter()` before rotating – Alex S. Diaz Sep 18 '15 at 15:56
  • tried that as well - still not working :/ – Sw3das Sep 18 '15 at 18:27
  • 1
    It is working using exactly the same code you added (without player - I've commented that parts). There's some problem with positions but generally rendering arrow. Please show full uiButton class. – m.antkowicz Sep 18 '15 at 18:59
  • Check my question, I've edited it ( replaced the simplified version of UiButton to full code ) – Sw3das Sep 18 '15 at 19:17

1 Answers1

3

your problem is in setSize() method in UiButton 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 );
    }

Both super.getWidth() and super.getHeight() returns ZERO (because you haven't set any width/height to the super class object). Then in scaleX/scaleY variables you have infinity value - you can see it by uncommenting marked line in my code.

The funny thing is that Java allows you to divide by floating zero - returning mentioned infinity value (read more here) and that is why you don't have an Exception there.

The solution is to fix this method by calling super.setSize(width,height) or just to delete it at all and lean on default Sprite class setSize() method implementation.


One thing more - after fixing the issue you will observe problems with rotation - it is about origin. You can just change you setSize method to

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

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

and it will do the thing

enter image description here

Community
  • 1
  • 1
m.antkowicz
  • 13,268
  • 18
  • 37
  • Thank you, you saved my day :D It appears I have accidentally overriden setSize( ) method... Once again, thank you for taking care of this! – Sw3das Sep 19 '15 at 08:32
  • Oh and... Is the 90 and 270 degrees oposite in libGDX ? Because 90 degrees should rotate arrow so that it points to right :/ – Sw3das Sep 19 '15 at 08:46