JavaFX Fade Transition issue - java

I followed every instruction I could find, tried various ways to implement this, always with the same symptom: Nothing happens...
Expectation:
Have an image that is fading from 100% transparent to 0% transparent.
I have this FadingImage class:
public class FadingImage{
private FadeTransition ft;
public FadingImage(String imgName,int posX, int posY, double from, double to, Group root) {
ImageView img = new ImageView(imgName);
ft = new FadeTransition(Duration.millis(1000));
ft.setNode(img);
ft.setFromValue(from); //sets the start opacity value
ft.setToValue(to); //sets the target opacity value
ft.setCycleCount(1);
ft.setAutoReverse(false);
img.setTranslateX(posX);
img.setTranslateY(posY);
root.getChildren().add(img);
}
public void play(){
ft.playFromStart();
}
}
And I call it like this:
FadingImage fi = new FadingImage("images/dock1.png",500, 500, 0.0, 1.0, root);
fi.play();
I am getting no exceptions whatsoever.
If I add a System out in the play method, it shows it.
I feel like I am missing something basic here, I just don't find it...

The code is correct. The parameters used were incorrect, as the image was displayed outside the screen.

Related

libGDX problem with getWidth() and getHeight() after resizing

Problem recorded and uploaded to Youtube
libGDX resizing problem
I am starting out with libGDX and wanted to make a game.
However... when I was just experimenting around... this happened.
I don't know why it does that or what I should do to eliminate this.
I don't know what to google either. It's almost as if libGDX's default width and height methods doesn't update correctly when the screen is being resized.
Am I doing something wrong here?
Code :
public class Metroidvania extends ApplicationAdapter {
ShapeRenderer s;
#Override
public void create () {
s = new ShapeRenderer();
}
#Override
public void render () {
ScreenUtils.clear(1, 1, 1, 1);
s.begin(ShapeRenderer.ShapeType.Filled);
s.setColor(0, 0, 0, 1);
s.rect(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
s.end();
}
#Override
public void dispose () {
s.dispose();
}
}
The video is currently stuck at 97% uploaded... Even Youtube is against me now
Basically, The code is supposed to cover the entire screen in black... even when resized. But here, when resised Gdx.graphics.getWidth() and Height() returns wrong values, causing white spaces to show.
The rect()'s shape depends on which direction you resize in.
Resize the screen smaller and the rect() become's smaller at R times the rate of resizing (R is unknown). Vice versa for reisizing it larger.
LibGDX usually uses a virtual screen and viewports i.e. you render to a different width and height than are the real ones in pixel terms.
Maybe have a look here Libgdx Window Resizing: Keeping Aspect Ratio as there is a resize method you can hook into to dynamically update your own coordinate system.

LibGDX — How to detect if 3d object was clicked on?

I'm trying to make a simple bit of code that will detect whether a model was clicked on. So far the best method I've seen is to create some sort of rectangle around the mesh and detect with Gdx.input.justTouched() to get the x,y coordinates, and then check if the rectangle contains the coordinates returned by justTouched().
I have no idea if there's a better way to do this, some kind of mesh onClick listener or something that LibGDX has in place that I'm unaware of (I've been scouring Google and the javadocs but I can't seem to find anything). I don't really need to deal with the z-axis coordinate, at least I don't think so. I only have the one PerspectiveCamera and it's not going to be moving around that much (not sure if this matters?)
Anyways, in my render() method I have:
if (Gdx.input.justTouched()) {
//this returns the correct values relative to the screen size
Vector2 pos = new Vector2(Gdx.input.getX(), Gdx.input.getY());
//I'm not sure how to get the correct rectangle to see what the
//width and height are for the model relative to the screen?
Rectangle modelBounds = new Rectangle(<<not sure what to put here>>);
if (modelBounds.contains(pos.x, pos.y) {
System.out.println("Model is being touched at: " + pos.x + ", " + pos.y);
}
}
I'm really not sure if this is the correct way to do this. I can get the position of the model with:
modelInstance.getNode("Node1").globalTransform.getTranslation(new Vector3());
but I'm not sure how to get the width and height as a rectangle relative to the screen size, if it's even possible.
I'm also unsure if this would cause massive lag, as I'm going to have about 7 nodes total that I need to detect if they're clicked on or not.
Is there a better way to do this? If not, is there a way to get the model width & height relative to the screensize (or camera, maybe)?
EDIT: Read about using Bounding Boxes, seems like what I need. Not quite sure how to implement it properly, however. I've changed my code to such:
public ModelInstance modelInstance;
public BoundingBox modelBounds;
#Override
public void create() {
...
//omitted irrelevant bits of code
modelInstance = new ModelInstance(heatExchangerModel);
modelBounds = modelInstance.calculateBoundingBox(new BoundingBox());
}
#Override
public void render() {
...
if (Gdx.input.justTouched()) {
Vector3 pos = new Vector3(Gdx.input.getX(), Gdx.input.getY(), 0);
System.out.println(pos);
if (modelBounds.contains(pos)) {
System.out.println("Touching the model");
}
}
}
I'm not really sure what the output of BoundingBox is supposed to be, or how the numbers it gives me correlates to the position in a 2d space. Hmm..
EDIT2: Think I'm getting closer.. Read about Rays and the .getPickRay method for my PerspectiveCamera. .getPickRay seems to return completely unusable numbers though, like really tiny numbers. I think I need to do something like:
if (Gdx.input.justTouched()) {
Vector3 intersection = new Vector3();
Ray pickRay = perspectiveCamera.getPickRay(Gdx.input.getX(), Gdx.input.getY());
Intersector.intersectRayBounds(pickRay, modelBounds, intersection);
}
and then intersection should give me the point where they overlap. It appears to be not working, however, giving me really small numbers like (4.8066642E-5, 2.9180354E-5, 1.0) .. hmmm..

LibGDX - Drawing to a FrameBuffer does not work

So I'm trying to make custom buttons, for which I need to combine different parts of the button background. To do this I figured using a FrameBuffer would work, however it did not give viable results. Therefore I attempted to test my FrameBuffer drawing method, by writing a simple test method, which returns a texture that is drawn to the display at every render() call. This method is here (note that it is a test method, so it may be a little poorly optimized):
private Texture test()
{
BitmapFont f = ReverseBlade.fontTitle;
f.setColor(Color.LIGHT_GRAY);
FrameBuffer fbo = new FrameBuffer(Format.RGBA8888, (int)f.getBounds("Hi").width, (int)f.getBounds("Hi").height, false);
Batch b = ReverseBlade.batch;
OrthographicCamera c = new OrthographicCamera(fbo.getWidth(), fbo.getHeight());
c.setToOrtho(false);
c.update();
b.setProjectionMatrix(c.combined);
fbo.begin();
b.begin();
f.draw(b, "Hi", 0, 0);
b.end();
fbo.end();
Texture t = fbo.getColorBufferTexture();
fbo.dispose();
b.setProjectionMatrix(ReverseBlade.camera.combined);
return t;
}
However, nothing is displayed. The screen is dark... I have tried without the camera and multiple other variations that I can no longer remember. What am I doing wrong?
Half Solution
What I ended up having to do is to make a new Matrix4 object for the FrameBuffer like this:
Matrix4 m = new Matrix4();
m.setToOrtho2D(0, 0, fbo.getWidth(), fbo.getHeight());
batch.setProjectionMatrix(m);
However, this makes everything that is drawn be upside down, like this:
I think the fbo.dispose() call is destroying more than you want.
See the source and notice where it destroys the colorTexture, which is the result of getColorBufferTexture().
I think this could be considered a bug in Libgdx. The color texture is generally something that should have a very different lifetime than the FBO, so cleaning up the texture seems a bit too aggressive. However, trying to figure out which cases to clean the texture up is probably complicated.....
So following what I added with the Half Solution, all I had to do was create a new Sprite object with the texture from the FBo and call flip(false, true)!
May be this is a workaround to dispose() the framebuffer and keeping the texture alive. I do the following:
public class TextureSaveFBO extends FrameBuffer {
static final Texture DUMMY = new Texture(1, 1, Format.RGB565) {
public void dispose() {
};
};
public TextureSaveFBO(Format format, int width, int height,
boolean hasDepth) {
super(format, width, height, hasDepth);
}
#Override
public void dispose() {
// prevents the real texture of dispose()
Texture t = colorTexture;
colorTexture = DUMMY;
super.dispose();
colorTexture = t;
}
}
Just a precisation:
OrthographicCamera c = new OrthographicCamera(fbo.getWidth(), fbo.getHeight());
c.setToOrtho(false);
This is potentially harmful unless you know what you are doing: c.setOrtho(false) does the following:
Sets this camera to an orthographic projection using a viewport fitting the screen resolution, centered at (Gdx.graphics.getWidth()/2, Gdx.graphics.getHeight()/2), with the y-axis pointing up or down.
So even if you specified in the OrthographicCamera's constructor that you want the viewport to be of the frame buffer size, you are overwriting that with the following call to a viewport covering the screen size and centered to the screen center.
You should probably do:
camera.setToOrtho(false, fbo.getWidth(), fbo.getHeight());
Issue solved since LibGDX 1.6.5.
It's now possible to override disposeColorBuffer method to not dispose rendered texture.

Setting text on Label (Actor) stops drawing

I just can't figure this, and I am pulling my hair out right now!!
I have a Stage with a Label added to it, I set everything up and the first time I call Stage.draw() everything works fine. However, as soon as I set the text of the Label nothing gets drawn. Funny thing is, when I don't change the text it draws perfectly as expected, but when I call label.setText("THE TEXT") it just doesn't draw.
I have stepped through my code and I have noted down the height, width, x and y values before and after setting text of the Label, and they are all the same (before and after).
Also, when I draw the Stage it's drawn above a Sprite, and positioning the Sprite is based on the Label's position.
The Sprite draws fine before I set text on the Label and after.
PS: I have also made sure that the Sprite is not drawn "over" the Label.
This is my setup:
I have a MainGame class that renders a Player class, when ever the back button is pressed the Sprite with the Stage gets drawn, or should get drawn.
spriteBatch.begin();
player.update(spriteBatch, delta);
spriteBatch.end();
// the pause menu is drawn with a separate sprite batch as it needs to be in middle relative to the screen and above everything else
if (player.isPaused()){
messageSpriteBatch.begin();
messageSprite.draw(messageSpriteBatch);
messageSpriteBatch.end();
messageStage.draw(); // the stage doesn't seem to be getting drawn
}
Player class - update method
if (!paused){
// removed for clarity
}else{
// on MainGame class we render a small box with one of the following messages
// READY
// PAUSE
// QUIT?
// GAME OVER
if (Gdx.input.justTouched()){
paused = false;
}
spriteBatch.setProjectionMatrix(camera.combined);
camera.update();
}
messageSpriteBatch = new SpriteBatch();
messageStage = new Stage(Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
messageFont = new BitmapFont(Gdx.files.internal("fonts/fontfile.fnt"));
messageStyle = new LabelStyle();
messageStyle.font = messageFont;
messageLabel = new Label("READY", messageStyle);
This is how I initialise my Label, Sprite and Stage:
float fontScaleX = Gdx.graphics.getWidth()/SCALE_X_DIVIDER;
float fontScaleY = Gdx.graphics.getHeight()/SCALE_Y_DIVIDER;
messageLabel.setFontScale(fontScaleX*1.4f, fontScaleY*4.2f);
messageLabel.setPosition((messageStage.getWidth()/2)-((messageLabel.getWidth()/2)*messageLabel.getFontScaleX()), (messageStage.getHeight()/2)-((messageLabel.getHeight()/2)*messageLabel.getFontScaleY())+(player.getScoreboard().getSize().y/2));
messageStage.addActor(messageLabel);
messageStage.act();
messageTexture = new Texture(Gdx.files.internal("images/message_background.png"));
messageSprite = new Sprite(messageTexture);
messageSprite.setSize((messageLabel.getWidth()*messageLabel.getFontScaleX())*1.5f, (messageLabel.getHeight()*messageLabel.getFontScaleY())*3);
messageSprite.setPosition(messageLabel.getX()-(messageSprite.getWidth()/6), messageLabel.getY()-messageSprite.getHeight()/2);
Please help me, before I get bald xD
Well the width and height of the label is usually set once when creating the Label, matching the width and height of the initial text passed to the Constructor. You of course can make it bigger by setting the width and height later on. Then you could also use alignments by the way...
Are you using any special characters when changing the text, so the font has a problem with that?
Maybe posting some code could give more insights...
Haha, well, I found out what was up, it was my font file, you see when I was editing it, I used the text READY, so when I saved it, I didn't know that the text written is what is saved, so when I looked at the font.png file, I found that it only contained the letters ADERY.
Thanks for the help anyway =]

StateListDrawable containing Drawables with different bounds

Suppose I have a StateListDrawable. I want to add 2 drawables inside it: the first if it is clicked, second for any other state.
I tried it as following (pseudo-code):
Drawable clickdDrawable = getResourses.getDrawable(R.drawable.presseddrawable);
clickDrawable.setBounds(-100, -100, 100, 100);
Drawable otherStateDrawable = getResources().getDrawable(R.drawable.somedrawable);
otherStateDrawable.setBounds(-50,-50, 50, 50);
StateListDrawable sld = new StateListDrawable();
sld.addState(new int[]{andriod.R.attr.state_pressed, android.R.attr.state_focussed}, clickDrawable);
sld.addState(StateSet.WILDCARD, otherStateDrawable);
sld.setBounds(-50, -50, 50, 50);
now if I'm in state pressed I will get the presseddrawable, but it sticks to the bounds of StateListDrawable. So my question is: How to store Drawables with different bounds inside a StateListDrawable? Is this possible?
You will have to create "custom" Drawables, but before you go that way, let me invite you (and whoever is involved, often a designer) to re-think a bit what you are doing, some years ago I did a heavy work on programmatically drawn extends Drawables (yet it was awesome) just to trash it few months later in favor of simplicity and practicality, I don't see why you can't achieve something like this with a well made 9-patch (a.k.a. n-patch) rather than hardcode dimensions, anyways before you call me grandpa here is a quick answer that could work for ya:
In example say you are using color drawables:
public class FixedBoundsColorDrawable extends ColorDrawable {
private boolean mFixedBoundsSet = false; // default
public FixedBoundsColorDrawable(int color) {
super(color);
}
#Override
public void setBounds(int left, int top, int right, int bottom) {
if (!mFixedBoundsSet) {
mFixedBoundsSet = true;
super.setBounds(left, top, right, bottom);
}
}
}
With red as pressed and blue as wildcard and your values you get on a Nexus 4:
You could also create a wrapper to wrap any drawable and call its methods but I would go that way as there are some final methods that you certainly will need.

Categories