LibGDX - 来自自定义 class 的 Sprite 未显示
LibGDX - Sprite from custom class is not showing up
我已经花了大约 6 个小时试图解决这个问题...
我有 2 个 类(Player
和 UiButton
),它们都是 extends Sprite
。
问题是来自 Player 的 Sprite 正在渲染 而来自 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);
}
它会做这件事
我已经花了大约 6 个小时试图解决这个问题...
我有 2 个 类(Player
和 UiButton
),它们都是 extends Sprite
。
问题是来自 Player 的 Sprite 正在渲染 而来自 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);
}
它会做这件事