How is it possible to fade-out a TextButton after it has been pressed? - libgdx

I simply want to fade-out (opacity = completely transparent) a button after I've pressed it... the following code has the unexplainable effect of fading the background image (a totally different actor!) to black !
What am I doing wrong ?
Skin skin = new Skin();
TextureAtlas buttonAtlas = new TextureAtlas(Gdx.files.internal("gfx/menu_buttons.pack"));
skin.addRegions(buttonAtlas);
TextButtonStyle textButtonStyle = new TextButtonStyle();
textButtonStyle.font = mButtonSpacefont;
textButtonStyle.up = skin.getDrawable("menu_button_background_top");
textButtonStyle.down = skin.getDrawable("menu_button_background_bottom");
mButtonStartGame = new TextButton("Play", textButtonStyle);
mButtonStartGame.setPosition(game.getIdealWidth()/2 - mButtonStartGame.getWidth()/2,
game.getIdealHeight()/2 - mButtonStartGame.getHeight()/2);
mButtonStartGame.addListener(new ChangeListener()
{
#Override
public void changed (ChangeEvent event, Actor actor)
{
//triggers when button is pressed and let go
mButtonStartGame.addAction(Actions.fadeOut( 1.0f ));
}
});
// add actors to stage
mStage.addActor(backgroundActor);//background
mStage.addActor(titleActor);//ontop of background
mStage.addActor(mButtonStartGame);//ontop of background
UPDATE 1:
I've discovered that the TextButton is faded out - BUT - so is the actor that contains the background image backgroundActor ! Why would the backgroundActor be faded when the code doesn't even call backgroundActor.addAction(Actions.fadeOut( 1.0f )); ??
UPDATE 2:
The render() method seems to play a part... when I call Gdx.gl.glClearColor(0, 0, 0, 0); the whole screen (except for the titleActor!) turns black due to the fadeOut action. When I call Gdx.gl.glClearColor(1, 1, 1, 1); the whole screen (except for the titleActor!) turns white.
#Override
public void render(float delta)
{
Gdx.gl.glClearColor(0, 0, 0, 0);//clear the screen black
//Gdx.gl.glEnable(GL20.GL_BLEND);// no effect, so commented out
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// update the actors
mStage.act(Gdx.graphics.getDeltaTime());
// draw the actors
mStage.draw();
}

The solution was that all of my actor's need to take into consideration the parentAlpha and set the color with batch.setColor().
Since my background was an actor, and I wasn't setting the batch color, the background was screwed up.
for example:
public class ActorBackground extends Actor
{
// Member Variables
private Texture mTexture;
// Constructor
public ActorBackground(GFXLoader gfxloader)
{
mTexture = new Texture(gfxloader.loadGraphic("menu_background"));// returns Gdx.files.internal(file.path())
//setBounds(getX(), getY(), mTexture.getWidth(), mTexture.getHeight());
setWidth(mTexture.getWidth());
setHeight(mTexture.getHeight());
}
#Override
public void draw(Batch batch, float parentAlpha)
{
// needed to make actions work
super.act(Gdx.graphics.getDeltaTime());
// needed to make fade work
Color color = new Color(this.getColor().r, this.getColor().g, this.getColor().b, this.getColor().a * parentAlpha);
batch.setColor(color);
// show it
batch.draw(mTexture, getX(), getY(), getWidth(), getHeight());
}
}

Related

LIBGDX Framebuffer is drawn as a black box

We figured out the issue. I was disposing the framebuffer before using it.
I recently queried about how to use the Libgdx Framebuffer correctly.
Summed up, i am making a tile-based game and i wanted to understand how to setup and use a
framebuffer object to eventually start experimenting with shaders. I wanted to exclude the
"water tiles" from the normal draw cycle and instead have them be rendered to a framebuffer.
Then render the framebuffer to the screen.
(I am not using any "Scene2d" or "Tiled" classes)
Link to previous question: How to use LIBGDX FrameBuffer correctly.
Even though the answer i accepted did not work in my particular program, it did work
when i tried it out on a smaller more contained program (shown below).
This works:
public void render() {
float dt = Gdx.graphics.getDeltaTime();
Cam.instance.getCamera().translate(direction.x*speed*dt, direction.y*speed*dt,0);
Cam.instance.update();
// clear the screen, set batch's projection matrix
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(Cam.instance.getCamera().combined);
// draw texture as layer 0
batch.begin();
batch.draw(green,606,306);
batch.flush(); // No need to call batch.end() / batch.begin()
// Storing the original values of the batch before changing it.
originalMatrixTemp.set(batch.getProjectionMatrix());
int originalBlendSrcFunc = batch.getBlendSrcFunc();
int originalBlendDstFunc = batch.getBlendDstFunc();
// Sorcery as far as i am concerned. "Ensures alpha is preserved in case of overlapping translucent sprites"
batch.setBlendFunctionSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE);
frameBuffer.begin(); // initialize framebuffer
// clear the colors of the batch
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.draw(red,256,0); // Draw another texture, now unto the framebuffer texture
batch.flush(); // flush batch
frameBuffer.end(); // end framebuffer
// "Ensure we're drawing the frame buffer texture without modifying its color"
batch.setColor(Color.WHITE);
// I think we are setting the projection to "default" (-1,1,2,-2)
batch.setProjectionMatrix(IDENTITY);
// draw the framebuffers texture across all the screen (layer 1)
batch.draw(frameBuffer.getColorBufferTexture(),-1, 1, 2, -2);
batch.flush();
// restoring the original state
batch.setProjectionMatrix(originalMatrixTemp);
batch.setBlendFunction(originalBlendSrcFunc, originalBlendDstFunc);
// drawing arbitrary layer 2
batch.draw(green,300,300);
batch.end(); // end of cycle
}
and it shows (Red square is the framebuffer texture):
The cycle is: Begin -> Draw something -> Draw, using buffer -> Draw something -> end.
So my question is then, why does this not work:
private void renderFbo(int layer) {
batch.flush();
originalMatrixTemp.set(batch.getProjectionMatrix());
int originalBlendSrcFunc = batch.getBlendSrcFunc();
int originalBlendDstFunc = batch.getBlendDstFunc();
batch.setBlendFunctionSeparate(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA, GL20.GL_ONE, GL20.GL_ONE);
fbo.begin();
Gdx.gl.glClearColor(0, 0, 0, 0);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
// Drawing the layer unto the framebuffer:
for (DrwDat dat: layers.get(layer)) { dat.draw(batch); }
batch.flush();
fbo.end();
batch.setColor(Color.WHITE);
batch.setBlendFunction(GL20.GL_SRC_ALPHA, GL20.GL_ONE_MINUS_SRC_ALPHA);
batch.setProjectionMatrix(IDENTITY);
// Halving the output texture to see the issue clearer. whole screen: (-1, 1, 2, -2)
batch.draw(fbo.getColorBufferTexture(), -0.5f, 0.5f, 1f, -1f);
batch.flush();
batch.setProjectionMatrix(originalMatrixTemp);
batch.setBlendFunction(originalBlendSrcFunc, originalBlendDstFunc);
}
With this being the immediate context:
public void draw() {
Gdx.gl.glClearColor(1, 1, 1, 1); // clearing with WHITE to see the framebuffer texture
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.setProjectionMatrix(camera.combined);
batch.begin();
for (int i = 0; i < NUM_LAYERS; i++) {
if (RENDER[i]) {
if (SORT[i]) Collections.sort(layers.get(i));
//for (DrwDat dat: layers.get(i)) { dat.draw(batch);}
if (i==1) { renderFbo(i); } // calling the framebuffer-using method for "water layer"
else{
for (DrwDat dat: layers.get(i)) {
dat.draw(batch);
}
}
}
}
Instance variables in the "draw class" :
public class DrwHandler {
private static final String TAG = DrwHandler.class.getName();
public static DrwHandler instance = new DrwHandler();
private final Matrix4 originalMatrixTemp = new Matrix4();
private static final Matrix4 IDENTITY = new Matrix4();
private Map<Integer, ArrayList<DrwDat>> layers;
private OrthographicCamera camera;
private FrameBuffer fbo;
private SpriteBatch batch;
private static final int NUM_LAYERS = 8;
private static final boolean[] RENDER = new boolean[NUM_LAYERS];
private static final boolean[] SORT = new boolean[NUM_LAYERS];
private DrwHandler() {
fbo = new FrameBuffer(Pixmap.Format.RGBA8888, Settings.SCREEN_W,Settings.SCREEN_H,false);
batch = new SpriteBatch();
layers = new HashMap<>();
layers.put(0,new ArrayList<>());
layers.put(1,new ArrayList<>());
layers.put(2,new ArrayList<>());
layers.put(3,new ArrayList<>());
layers.put(4,new ArrayList<>());
layers.put(5,new ArrayList<>());
layers.put(6,new ArrayList<>());
layers.put(7,new ArrayList<>());
}
It shows:
The "black box" is the framebuffer texture (redused in size). The white background is the clear color.
and the green is a foreground layer.
It is black regardless of changing the Gdx.gl.glClearColor(0, 0, 0, 0) within the context of the framebuffer rendering to some other color.
without the renderFbo() method, it renders normally like this:
Now i have heard Static references can cause issues with OpenGL-related objects:
"If you will be building for Android, never use static references to any OpenGL-related objects unless you have an expert understanding of the LibGDX lifecycle. Even then, it is an error-prone practice. People come on here to ask about black textures pretty frequently and 99% of the time it has to do with some static reference being used incorrectly."
I am not building for android. And since my previous question i have removed static objects.
just to be sure.
But i do use statics in a few select classes like this (example):
public class Cam {
public static Cam instance = new Cam();
private OrthographicCamera camera;
private Cam() {
camera = new OrthographicCamera(Settings.SCREEN_W, Settings.SCREEN_H);
}
(including my Assets class and Draw class):
Trying to think about what else.. I guess we will try with this first. Se if something sticks out to you.
Really could need some help right about now. Been banging my head against the wall for a while. Thank you.
Here is a link to some source files that could be relevant:
Source

LibGDX making a rectangle move on its own

public class gameMain implements Screen {
final main game;
SpriteBatch batch;
Texture img;
private Texture alexTexture;
private Rectangle alex;
private Texture cTex;
private Texture dropper;
private Texture ender;
private Texture partsImg;
private Texture toy;
private OrthographicCamera camera;
private Array<Rectangle> part; // ******
private long lastDropTime;
private int beltSpeed = 100; // ******
//Score Keeper
private int score;
private String scoreName;
//basically a create method
public gameMain(final main gam){
this.game = gam;
// load images into memory
dropper = new Texture("android/assets/dropper.png");
ender = new Texture("android/assets/endOfBelt.png");
partsImg = new Texture("android/assets/unmadeToyParts.png");
toy = new Texture("android/assets/toymade.png");
cTex = new Texture("android/assets/conveyerBeltBackground.png");
alexTexture = new Texture(Gdx.files.internal("android/assets/alexAlpha2.png"));
// set the game window resolution
camera = new OrthographicCamera();
camera.setToOrtho(false, 1080,720);
// Alex's position / hitbox
alex = new Rectangle();
alex.x = 250;
alex.y = 150;
alex.width = 126;
alex.height = 75;
// part stuff
part = new Array<Rectangle>();
spawnPart();
// score handler
score = 0;
scoreName = "Toys Made: ";
}
private void spawnPart(){ // *******
Rectangle parts = new Rectangle();
parts.x = 0;
parts.y = 210;
parts.width = 52;
parts.height = 60;
part.add(parts);
lastDropTime = TimeUtils.nanoTime();
} //********
#Override
public void render(float delta) {
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
// load alex sprite
game.batch.setProjectionMatrix(camera.combined);
// begin drawing to screen
game.batch.begin();
batch.draw(cTex, -5, 200); // draw conveyer background
batch.draw(dropper, 0, 210); // draw the dropper
batch.draw(ender, 600, 200); // draw the ender
game.batch.draw(alexTexture, alex.x, alex.y); // draw alex
for(Rectangle parts: part){
game.batch.draw(partsImg, parts.x, parts.y); // draw part
}
game.font.draw(game.batch, scoreName, 25, 100); // draw scoreboard
game.batch.end(); // end drawing to screen
//******************************************************************************
//HERE IS WHERE I AM TRYING TO PUT IT
part.x += beltspeed;
if (part.rectangle overlaps ender.rectangle){
despawn part;
}
//******************************************************************************
}
#Override
public void show() {
}
#Override
public void hide() {
}
#Override
public void pause() {
}
#Override
public void resume() {
}
#Override
public void resize(int width, int height) {
}
#Override
public void dispose() {
}
}
Hello I am very new to LibGDX, and after doing some research I decided to make a game where you are a factory worker named Alex and you build toys. I will gladly take any feedback you have to make my code more orginized or work better. I highlighted everything I believe to be relevant to my question with some asterisks.
But my question is: How do you make a 'rectangle' such as my 'part' move on its own. I added a beltspeed and a spawn zone, and once the hitbox for it goes over the 'ender' hitbox I would like to despawn it.
Also I haven't gotten this far yet, but when the 'part' hitbox passes over 'Alex' hitbox I would like a little minigame to appear where you have to press up, down, left, right (randomly) to build the toy. If you have any suggestions on how I should handle that, I would be very appreciative.
"C:\Program Files\Java\jdk1.7.0_79\jre\bin\java" -Didea.launcher.port=7532 "-Didea.launcher.bin.path=C:\Program Files (x86)\JetBrains\IntelliJ IDEA Community Edition 2016.1.1\bin" -Dfile.encoding=UTF-8 -classpath "C:\Program Files\Java\jdk1.7.0_79\jre\lib\charsets.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\deploy.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\access-bridge-64.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\dnsns.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\jaccess.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\localedata.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\sunec.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\sunjce_provider.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\sunmscapi.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\ext\zipfs.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\javaws.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\jce.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\jfr.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\jfxrt.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\jsse.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\management-agent.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\plugin.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\resources.jar;C:\Program Files\Java\jdk1.7.0_79\jre\lib\rt.jar;C:\Users\RAFiredog\Desktop\Intellij\AlexTheTemp\out\production\desktop;C:\Users\RAFiredog\Desktop\Intellij\AlexTheTemp\out\production\core;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\com.badlogicgames.gdx\gdx\1.9.2\e641cb91bec06bc64d9ddf7a7d7062caceec73cd\gdx-1.9.2.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\com.badlogicgames.gdx\gdx-box2d\1.9.2\b78eaa90aaaf7830e6dffff587ea6e859c2787b2\gdx-box2d-1.9.2.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\com.badlogicgames.gdx\gdx-freetype\1.9.2\3609253d14edb1b3ca5aacff4e06989edde75be4\gdx-freetype-1.9.2.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\com.badlogicgames.gdx\gdx-backend-lwjgl\1.9.2\d710a8704ed584ec2ba9ca52e3a6a5885dd759cc\gdx-backend-lwjgl-1.9.2.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\com.badlogicgames.gdx\gdx-platform\1.9.2\dde4cf7e9ce61c24042f512203aed87657496639\gdx-platform-1.9.2-natives-desktop.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\com.badlogicgames.gdx\gdx-box2d-platform\1.9.2\497cbfbf81e7e8b1e8433b19291c5af4bbc2ec66\gdx-box2d-platform-1.9.2-natives-desktop.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\com.badlogicgames.gdx\gdx-tools\1.9.2\37d8e3009ae0febdf93717b21980c67c8cadac07\gdx-tools-1.9.2.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\com.badlogicgames.gdx\gdx-freetype-platform\1.9.2\1e1afb0b6c9e8aeb7d495cb8f55c353d3da58cf0\gdx-freetype-platform-1.9.2-natives-desktop.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\org.lwjgl.lwjgl\lwjgl\2.9.2\a9d80fe5935c7a9149f6584d9777cfd471f65489\lwjgl-2.9.2.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\org.lwjgl.lwjgl\lwjgl_util\2.9.2\4b9e37300a87799856e0bd15ed81663cdb6b0947\lwjgl_util-2.9.2.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\com.badlogicgames.jlayer\jlayer\1.0.1-gdx\7cca83cec5c1b2f011362f4d85aabd71a73b049d\jlayer-1.0.1-gdx.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\org.jcraft\jorbis\0.0.17\8872d22b293e8f5d7d56ff92be966e6dc28ebdc6\jorbis-0.0.17.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\com.badlogicgames.gdx\gdx-backend-headless\1.9.2\813e6020de85cd831f02cb5e9060fd7ea8cb208e\gdx-backend-headless-1.9.2.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\org.lwjgl.lwjgl\lwjgl-platform\2.9.2\510c7d317f5e9e700b9cfaac5fd38bdebf0702e0\lwjgl-platform-2.9.2-natives-windows.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\org.lwjgl.lwjgl\lwjgl-platform\2.9.2\d276cdf61fe2b516c7b7f4aa1b8dea91dbdc8d56\lwjgl-platform-2.9.2-natives-linux.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\org.lwjgl.lwjgl\lwjgl-platform\2.9.2\d55b46b40b40249d627a83a7f7f22649709d70c3\lwjgl-platform-2.9.2-natives-osx.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\net.java.jinput\jinput\2.0.5\39c7796b469a600f72380316f6b1f11db6c2c7c4\jinput-2.0.5.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\net.java.jutils\jutils\1.0.0\e12fe1fda814bd348c1579329c86943d2cd3c6a6\jutils-1.0.0.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\net.java.jinput\jinput-platform\2.0.5\7ff832a6eb9ab6a767f1ade2b548092d0fa64795\jinput-platform-2.0.5-natives-linux.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\net.java.jinput\jinput-platform\2.0.5\385ee093e01f587f30ee1c8a2ee7d408fd732e16\jinput-platform-2.0.5-natives-windows.jar;C:\Users\RAFiredog\.gradle\caches\modules-2\files-2.1\net.java.jinput\jinput-platform\2.0.5\53f9c919f34d2ca9de8c51fc4e1e8282029a9232\jinput-platform-2.0.5-natives-osx.jar;C:\Program Files (x86)\JetBrains\IntelliJ IDEA Community Edition 2016.1.1\lib\idea_rt.jar" com.intellij.rt.execution.application.AppMain com.rafiredog.game.desktop.DesktopLauncher
Exception in thread "LWJGL Application" java.lang.NullPointerException
at com.rafiredog.game.gameMain.render(gameMain.java:97)
at com.badlogic.gdx.Game.render(Game.java:46)
at com.rafiredog.game.main.render(main.java:45)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication.mainLoop(LwjglApplication.java:223)
at com.badlogic.gdx.backends.lwjgl.LwjglApplication$1.run(LwjglApplication.java:124)
Process finished with exit code 0
Lastly, I am now getting this error. I moved some code around near the 'batch.draw'. However that might not be the cause of the error? I am a little lost right now. But I will gladly screenshot what I have of the game now once the errors are resolved.
Thank you for any insight you have on fixing up this game.
You need to do game updates and then rendering on each cycle of the game loop. The game update part of your code can iterate through your objects to do stuff to them.
For example, your render method would look like this. You need to explicitly use an Iterator for your for loop because you otherwise could not remove items from the list while iterating.
#Override
public void render(float delta) {
//Update game
Iterator<Rectangle> iterator = parts.iterator();
while (iterator.hasNext()){
Rectangle part = iterator.next();
part.x += beltSpeed * delta; //distance = speed * time
if (part.rectangle.overlaps(ender.rectangle)){
iterator.remove(); //removes rectangle from the list
}
}
//This is also where you would update movement for anything else,
//such as a character jumping, or counting down a timer and spawning
//something when it reaches zero, for example.
//Draw everything
Gdx.gl.glClearColor(0, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
camera.update();
game.batch.setProjectionMatrix(camera.combined);
game.batch.begin();
//...
game.batch.end();
}
If you spawn and "despawn" a lot of objects, you will probably need to use pooling to avoid stutters from memory deallocation. You can do this by replacing new Rectangle() with Pools.obtain(Rectangle.class) and adding the line Pools.free(part) right after iterator.remove().
I also noticed you have counter-intuitive usage of the words "part" and "parts" by swapping plural and singular. Make sure that doesn't trip you up.
As for your NullPointerException, read here.
Piggy backing onto Tenfour04's answer and attempting to answer your question in the comments. I'd suggest looking at this link: https://github.com/libgdx/libgdx/wiki/The-life-cycle

Some Actions do not work

I want to make a text appear in the center of the screen, indicating
the current level. It should appear gradually and after a while disappear gradually. I'm using scene2d with stages, actors.. so i would use Actions.
This is what i have now:
public class TextActor extends Actor {
private BitmapFont font;
private CharSequence charSequence;
public TextActor(CharSequence charSequence) {
font = new BitmapFont(Gdx.files.internal("fonts/white_standard_font.fnt"));
this.charSequence = charSequence;
}
#Override
public void act(float delta) {
super.act(delta);
}
#Override
public void draw(Batch batch, float delta) {
super.draw(batch, delta);
font.draw(batch, charSequence, getX(), getY());
}
}
In the class that creates the TextActor..
textActor.addAction(Actions.sequence(Actions.fadeIn(1f), Actions.delay(1f), Actions.fadeOut(1f), new Action() {
#Override
public boolean act(float delta) {
textActor.remove();
transitionInProgress = false;
gameState = GameState.RUNNING;
Gdx.input.setInputProcessor(stage);
return true;
}
}));
gameTable.addActor(textActor);
fadeIn, fadeOut, alpha.. don't work. I tried with "moveBy" and it works, so it seems a problem concerning the appearance of the Actor. There is something that escapes me.
The fade actions modify the alpha value of the Actor's color (getColor().a). You're drawing the font directly without applying the color associated with the actor.
Take a look at how Label.draw is implemented for a better understanding. In the meantime, just try adding this above your font.draw(...) call:
font.setColor(getColor())
Or, if you don't want to modify the entire color, just the alpha, try this:
font.getColor().a = getColor().a;
UPDATE:
Also note that you should apply the parentAlpha (second parameter of draw - labelled as delta in your example) to the final alpha:
font.getColor().a = getColor().a * parentAlpha
This allows your actor to fade if you change the alpha of the stage or any parents.

LibGDX Scene2d Action affects multiple Actors

I am working on my second app and it went quite well so far. But now I got stuch on a problem I just can´t manage to find a solution for.
I´ve been using scene2d stage to display everything. Now I´ve added a black image which fades out whenever a new Screen is called(as a transition).
My problem is, that when I add the fade out action to my black Image it also fades out the background. Interestingly only the background is affected, no other Actor what so ever.
I´ve tried changing the order of the Actors, putting them into groups, clearing all actions from the background, setting his alpha to 1 but nothing worked.
Thanks for helping me !
For the background:
public class BackgroundColor extends Actor {
public BackgroundColor(int x) {
this.setBounds(x, 0, 270, 960);
}
public void act(float delta) {
}
public void draw(Batch batch, float alpha) {
batch.draw(image, this.getX(), this.getY(), this.getWidth(), this.getHeight());
}
}
For the screen:
public class GameScreen implements Screen {
public Stage stage;
public BackgroundColor backgroundColor;
public Image black;
public GameScreen() {
stage = new Stage(new ExtendViewport(540, 900, 540, 960));
Gdx.input.setInputProcessor(stage);
setupStage();
}
private void setupStage() {
backgroundColor = new BackgroundColor(0);
stage.addActor(backgroundColor);
//this is the black layer
black = new Image(AssetLoader.black);
black.setBounds(0, 0, stage.getWidth(), stage.getHeight());
stage.addActor(black);
black.addAction(Actions.sequence(Actions.fadeOut((float)0.5), Actions.touchable(null)));
}
#Override
public void show() {
}
#Override
public void render(float deltaTime) {
Gdx.gl.glClear(0);
stage.act(Gdx.graphics.getDeltaTime());
stage.draw();
}
So, I kinda figured it out...
apparently having a different Image as the first layer of the stage solves the issue.
I added in a random Image before the backgroundColor = new BackgroundColor(0); and that fixed it.
I still have no Idea what causes this, maybe I missed something...
Would be great if you could tell me what is going on here!
Cheers

render to FrameBuffer not working in combination with ShapeRenderer in a custom Actor (libgdx)

I try to implement a custom Actor which displays contents of a FrameBuffer by extending Image. Inside I'd like to draw using a ShapeRenderer.
public class CustomActor extends Image {
private FrameBuffer frameBuffer = null;
private ShapeRenderer shapeRenderer = new ShapeRenderer();
private int width;
private int height;
public CustomActor() {
width = Gdx.graphics.getWidth();
height = Gdx.graphics.getHeight();
shapeRenderer.setAutoShapeType(true);
}
#Override
public void draw(Batch batch, float parentAlpha) {
if (frameBuffer == null) {
frameBuffer = new FrameBuffer(Pixmap.Format.RGB565, width / 2, height / 2, false);
TextureRegion textureRegion = new TextureRegion(frameBuffer.getColorBufferTexture());
textureRegion.flip(false, true);
setDrawable(new TextureRegionDrawable(textureRegion));
}
frameBuffer.begin();
// render content
Gdx.gl.glClearColor(0, 1, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
shapeRenderer.begin(ShapeRenderer.ShapeType.Filled);
shapeRenderer.setColor(Color.WHITE);
shapeRenderer.rect(0, 0, frameBuffer.getWidth() / 2, frameBuffer.getHeight() / 2);
shapeRenderer.end();
if (frameBuffer != null) {
frameBuffer.end();
}
super.draw(batch, parentAlpha);
}
}
When deleting the ShapeRenderer part I can see the green background in the scene. But as soon as I use the ShapeRenderer the content is black. There is no white rectangle visible.
Any ideas what I am doing wrong?
Just found out that using my own SpriteBatch (with begin() and end()) after the FrameBuffer end() it works. So the problem seems to have to do with the calling order of the FrameBuffers methods and the SpriteBatches methods. Ending the given actor batch before beginning the FrameBuffer and "re"-beginning it to draw the actor is also working (see comment above).