Texture of ImageButton is not displayed on some devices when used TextureAtlas - libgdx

I am using libGDX 1.0 and not sure if it is a bug or not.
My ImageButton is displayed correctly on a LG OPtimus and HTC Desire using TextureAtlas. However, on a Galaxy Tab2 the it becomes completely back, but it is still clickable.
If I load its texture from the AssetsManger, everything works fine on any device.
Here is the relevant part of the code:
stage = new Stage(new StretchViewport(fontCamera.viewportWidth,fontCamera.viewportHeight));
ImageButtonStyle styleButtonPlay = new ImageButtonStyle();
//this works
//textureButtonPlay = new TextureRegion(game.manager.get("data/ui/play.png",Texture.class));
//styleButtonPlay.imageUp = new TextureRegionDrawable(textureButtonPlay);
//this don't on Samsung Tab2
atlas = new TextureAtlas("data/shot/atlas.pack");
styleButtonPlay.imageUp = new TextureRegionDrawable(atlas.findRegion("ui/play"));
buttonPlay = new ImageButton(styleButtonPlay);
buttonPlay.addListener(
new ClickListener() {
public boolean touchDown(InputEvent event, float x, float y, int pointer, int button)
{
startGame();
return true;
}
});
buttonPlay.setSize(80, 60);
buttonPlay.setPosition(camera.viewportWidth/2 - buttonPlay.getWidth()/2,5);
stage.addActor(buttonPlay);
I now am concerned about packing all my sprites onto single imaged.

The problem has been resolved by creating a texturepack.png with the size smaller than 4096x4096.
For some reason it was ok only on some devices and no similar problem has been noticed on the desktop.
Hope this help someone...

see your code here:
atlas = new TextureAtlas("data/shot/atlas.pack");
style.imageUp = new TextureRegionDrawable(atlas.findRegion("ui/play"));
^^^^^
buttonPlay = new ImageButton(styleButtonPlay);
^^^^^^^^^^^^^^^
it looks like you assign the wrong style to your imageButton, try putting the drawable into the correct button style ("styleButtonPlay" instead "style"):
styleButtonPlay.imageUp = new TextureRegionDrawable(atlas.findRegion("ui/play"));

Related

Libgdx Group Size Issue

To make my question clearer , I created a simple test class as below.
`public void create () {
stage = new Stage();
// GP
Texture texture1 = new Texture(Gdx.files.internal("data/badlogic.jpg"));
TextureRegion tr = new TextureRegion(texture1);
Image image = new Image(tr);
Group gp = new Group();
ImageButton ib = new ImageButton(new Image(tr).getDrawable());
ib.setSize(90, 256);
gp.addActor(ib);
gp.setPosition(0, 0);
stage.addActor(gp);
gp.debugAll();
}`
The size of badlogic logo is 256*256. I set it to 90*256 in the test.But the outcome looks like this http://imgsrc.baidu.com/forum/w%3D580/sign=fb0e4402d21373f0f53f6f97940e4b8b/0958c32397dda1448779b0cbb1b7d0a20df486e2.jpg
If i set the image size before sending it to imagebutton, then it will rendered as 256*256 ,the full original size. This function is so simple. I can not figure out where is going wrong.
First of all, last update of Libgdx project is 1.4.1: http://libgdx.badlogicgames.com/download.html
The problem is the Drawable object that you are sending to the ImageButton, if you want to change the size of the Image or Texture before adding it to the ImageButton (so you will solve the problem asked), you will just need to use the .setBounds() method
I write down a little example:
1. Initialize Image object with your image file:
`Image image = new Image( new Texture ( Gdx.Files.internal("yourPathFile.png") ) );`
2. .setBounds() javadoc: (x coordinate, y coordinate, width of the image, height of the image)
image.setBounds(0f, 0f, 50f, 60f)
then you can send the image to the ImageButton object as Drawable.
`ImageButton myButton = new ImageButton(image.getDrawable());'
That's all.
Here you have some constructors of ImageButton object from the Libgdx official javadoc.
See also:
Release versions: http://libgdx.badlogicgames.com/releases/
ImageButton javadoc: http://libgdx.badlogicgames.com/nightlies/docs/api/com/badlogic/gdx/scenes/scene2d/ui/ImageButton.html

Libgdx: Stage only renders at (0, 0)

I'm attempting to use LibGDX Stage for my GUI elements, but I'm having loads of difficulty getting it to render properly. Right now, I'm attempting to render a chat window in the lower left corner of the screen.
Here is the construction of the GUI objects:
stage = new Stage();
stage.setCamera(controller.getCamera());
uiSkin = new Skin(Gdx.files.internal("res/gui/skin/uiskin.json"));
Table table = new Table(uiSkin);
stage.addActor(table);
table.setSize(300, 260);
table.setPosition(0, 0);
table.setFillParent(false);
table.bottom();
table.left();
table.pad(10);
lblChatLabel = new Label("", uiSkin);
lblChatLabel.setWrap(true);
final ScrollPane scroll = new ScrollPane(lblChatLabel, uiSkin);
txtChatBar = new TextField("do a chat", uiSkin);
txtChatBar.setName("txtChatBar");
table.add(txtChatBar).width(300f);
table.row();
table.add(scroll).expand().fill().colspan(4);
txtChatBar.addListener(new InputListener() {
public boolean keyDown(InputEvent event, int keycode) {
if (keycode == Input.Keys.ENTER) {
sendMessage();
// Close the chat bar
showChat = false;
return true;
}
return false;
}
});
And here is my render() method:
Log.debug("void", "x: " + stage.getCamera().position.x + ", y: " + stage.getCamera().position.y);
stage.act();
for (Actor a : stage.getActors()) {
a.draw(spriteBatch, 1);
}
In another section of code elsewhere, the game's camera object is translated to center on the player:
camera.translate(targetPosition.x, targetPosition.y);
camera.update();
So that all said, the chat window renders properly, but it only does so at 0, 0. I've also changed called stage.draw() rather than iterate through the Actors individually, but that causes the same issue. Here is a screenshot illustrating the issue:
http://i.imgur.com/8uz5lV6.jpg
Finally, I've tried to translate the stage manually by setting the viewport, but that causes an even weirder issue.
float cx = controller.getCamera().getX();
float cy = controller.getCamera().getY();
float width = controller.getCamera().viewportWidth;
float height = controller.getCamera().viewportHeight;
stage.act();
stage.setViewport(width, height, true, cx, cy, width, height);
stage.draw();
Image here:
http://i.imgur.com/JpSLq1s.jpg
Certainly I am doing something wrong, but I have no idea at this point. I would have assumed that the stage follows the Camera translation, but that doesn't appear to be the case. Any suggestions are welcome! Thanks!
I believe the issue is this line of code:
stage.setCamera(controller.getCamera());
If I'm reading correctly, you want the chat window to always render from (0,0), no matter where the camera is on the screen. If that's the case, then the stage shouldn't have any relation with the camera, which moves around and just further complicates getting the stage in the right position to be rendered properly.
Without that line of code, you should be able to just call
stage.act();
stage.draw();
and it should work fine.

libGDX stage draw me mirrored text

I use Stage in libGDX for drawing GUI and adding listeners to controls in my game.
But when I draw text on ImageTextButton I get mirrored text as displayed on image below.
Can some help me and tell me how to draw normal text, not mirrored ?
stage = new Stage(Constants.VIEWPORT_GUI_WIDTH, Constants.VIEWPORT_GUI_HEIGHT);
stage.clear();
....
ImageTextButtonStyle imageTextButtonStyle = new ImageTextButtonStyle();
imageTextButtonStyle.font = Assets.instance.fonts.defaultSmall;
ImageTextButton imageTextButton = new ImageTextButton("ddsds", imageTextButtonStyle);
imageTextButton.setBackground( gameUISkin.getDrawable("fil_coins"));
imageTextButton.setPosition(50, 600);
imageTextButton.setHeight(85);
imageTextButton.setWidth(183);
stage.addActor(imageTextButton);
....
public void render (float deltaTime) {
stage.act(deltaTime);
stage.draw();
}
Thanks
Edit:
Button images are shown correct, only text has mirrored view
As #Springrbua suggest me in comment below, my bitmap font was flipped when creating.
defaultSmall = new BitmapFont(Gdx.files.internal("images/font.fnt"), true);
should be
defaultSmall = new BitmapFont(Gdx.files.internal("images/font.fnt"), false);
Even it's not case here it may be useful for someone - if font size parameter is set to negative value, text will be rendered upside-down (Y-scale).

LibGDX Android Game - displaying fixed text (ie Score) over a scrolling screen

I am beginning to write a game in LibGDX, only just beginning. I have got a basic tile map loaded, a player sprite and can move the character around and the screen (camera) scrolls around - perfect.
I have two overlayed textures in the bottom right of the screen, a left and right arrow, which are used as the joypad to control the character. I position these in relation to the players.x position, which is always fixed to the centre of the screen. Cool so far .... As below:
/////////////////////////////////////////////////////////////////
private void renderJoypad(float deltaTime)
{
batch.draw(Assets.leftJoypad, blockman.position.x-14, 1, 3, 3);
batch.draw(Assets.rightJoypad, blockman.position.x-9, 1, 3, 3);
}
I am now trying to put the player's score in the top left of the screen. The score is made of a Bitmap font, as below.
font = new BitmapFont(Gdx.files.internal("fonts/minecrafter.fnt"),Gdx.files.internal("fonts/minecrafter.png"),false);
font.setScale(0.02f);
In my render() method I cam calling some other methods to update, like the positions of the
leftJoypad etc, as in renderJoypad(). I am also calling my draw font method to update the position of the score, however, when I scroll it is all jerky, and sometimes it shows less characters than there should be.
public void drawScore(float deltaTime)
{
font.draw(batch, "00000", blockman.position.x, 10);
}
I believe that I need to place the score (and any other on screen texts, HUD etc) into a stage, but I cannot understand how to get it working with my existing code.
My show method is as follows:
public void show()
{
//load assets class to get images etc
Assets Assets = new Assets();
//start logging Framerate
Gdx.app.log( GameScreen.LOG, "Creating game" );
fpsLogger = new FPSLogger();
//set the stage - bazinga
Gdx.input.setInputProcessor(stage);
//stage.setCamera(camera);
//stage.setViewport(480, 360, false);
batch = new SpriteBatch();
//load the Joypad buttons
loadJoypad();
//background image
loadBackground();
//sounds
jumpSound = Gdx.audio.newSound(Gdx.files.internal("sounds/slime_jump.mp3"));
//LOAD block man here
// load the map, set the unit scale to 1/16 (1 unit == 16 pixels)
loadMap();
//draw the score
font = new BitmapFont(Gdx.files.internal("fonts/minecrafter.fnt"),Gdx.files.internal("fonts/minecrafter.png"),false);
font.setScale(0.02f);
// create an orthographic camera, shows us 30x20 units of the world
camera = new OrthographicCamera();
camera.setToOrtho(false, 30, 20);
camera.update();
// create the Blockman we want to move around the world
blockman = new Blockman();
blockman.position.set(25, 8);
}
and my render() method is as follows:
public void render(float delta)
{
// get the delta time
float deltaTime = Gdx.graphics.getDeltaTime();
stage.act(deltaTime);
stage.draw();
// clear the screen
Gdx.gl.glClearColor(0.3f, 0.3f, 0.3f, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
renderBackground(deltaTime);
batch = renderer.getSpriteBatch();
//updateBlockman(deltaTime);
blockman.update(deltaTime);
// let the camera follow the blockMan, x-axis only
camera.position.x = blockman.position.x;
camera.update();
// set the tile map rendere view based on what the
// camera sees and render the map
renderer.setView(camera);
renderer.render();
//start the main sprite batch
batch.begin();
// render the blockMan
renderBlockman(deltaTime);
renderJoypad(deltaTime);
drawScore(deltaTime);
batch.end();
fpsLogger.log();
}
I have tried to change the way things work with relation to the Spritebatch etc and just cannot seem to get it working as I require.
Can anyone suggest how I may approach getting a stage and actors to work, or a second camera or something to help me achieve a fixed score display in the corner.
Do I need to use Scene 2D or something - aahhh! My head is exploding....
I look forward and thank you in advance.
Regards
James
I have a couple of suggestions:
Check to see if you have setUseIntegerPositions set to true
(the default) when you draw your font. If you do, and you're scaling
it, then it can cause some odd effects similar to those that you
describe. Set it to false and see if it fixes the problem.
Reset your spritebatch's matrices before drawing the text, that way you won't need to adjust it for the scrolling.
I'd even go as far as to recommend not scaling the font if you can help it, because fonts often look a little odd after being scaled.

Supporting Multiple image resolution for libgdx

How should I follow the directory structure and what to specify so that assetManger will use that folder for different resolution.
I have studied assetManager and ResolutionFileResolver but until now I couldn't exactly figured how to specify the folder to support different resolutions.
Update: Newer versions of Libgdx use a different strategy to resolve filenames (with directories, not files), so this answer does not apply to newer Libgdx versions after (0.9.2, I think? https://github.com/libgdx/libgdx/commit/3afcfe49c40196765033a90b4610159183dde981)
The built-in ResolutionFileResolver does not use a directory hierarchy. It uses file suffixes to match screen resolutions to assets.
Here's the code from the libGDX AssetManagerTest:
Resolution[] resolutions = { new Resolution(320, 480, ".320480"),
new Resolution(480, 800, ".480800"),
new Resolution(480, 856, ".480854") };
ResolutionFileResolver resolver = new ResolutionFileResolver(new InternalFileHandleResolver(), resolutions);
AssetManager manager = new AssetManager();
manager.setLoader(Texture.class, new TextureLoader(resolver));
...
The resolver appends one of those suffixes based on the current screen resolution. So, for example, if you look up "foo.jpg" on a 480x800 device, the file "foo.jpg.480800" will be opened.
If you want to resolve files based on directories (so "foo.jpg" would be resolved to "480x800/foo.jpg" or something like that), you can write a new resolver. Just implement FileHandleResolver. The ResolutionFileResolver.java source is probably a good place to start.
Once me too suffered from this problem but at end i got the working solution, for drawing anything using SpriteBatch or Stage in libgdx. Using orthogrphic camera we can do this.
first choose one constant resolution which is best for game. Here i have taken 1280*720(landscape).
class ScreenTest implements Screen{
final float appWidth = 1280, screenWidth = Gdx.graphics.getWidth();
final float appHeight = 720, screenHeight = Gdx.graphics.getHeight();
OrthographicCamera camera;
SpriteBatch batch;
Stage stage;
Texture img1;
Image img2;
public ScreenTest(){
camera = new OrthographicCamera();
camera.setToOrtho(false, appWidth, appHeight);
batch = new SpriteBatch();
batch.setProjectionMatrix(camera.combined);
img1 = new Texture("your_image1.png");
img2 = new Image(new Texture("your_image2.png"));
img2.setPosition(0, 0); // drawing from (0,0)
stage = new Stage(new StretchViewport(appWidth, appHeight, camera));
stage.addActor(img2);
}
#Override
public void render(float delta) {
batch.begin();
batch.draw(img, 0, 0);
batch.end();
stage.act();
stage.act(delta);
stage.draw();
// Also You can get touch input according to your Screen.
if (Gdx.input.isTouched()) {
System.out.println(" X " + Gdx.input.getX() * (appWidth / screenWidth));
System.out.println(" Y " + Gdx.input.getY() * (appHeight / screenHeight));
}
}
//
:
:
//
}
run this code in Any type of resolution it will going to adjust in that resolution without any disturbance.
If you use an OrthographicCamera you won't need to deal with different image resolutions.
Say that you have a camera with the size 400x300. Then you draw a 400x300 large image at coordinate (0,0). Then, regardless of screen resolution, the image will be scaled to fill the screen. This is really neat on Android where the screen resolution can vary a lot between different devices, and doing it like this you won't have to think about it.