Make an image fade in and out

One question solved, the next one appears ^^

I’m trying to make my hero invincible, once he was hit by an enemy. This works just fine, but I want him to be animated. Something similar to the incincible state of super mario. Sadly, the setOpacity(double) only exists for Node. GraphicsContext.setGlobalAlpha(double) results in the whole stage flickering.

So how can i make my javafx.image of the Player flicker?

Greetz and Thx

Half_NO_oB

I usually put in a timer or work off the frames per second. Since the frames per second is capped at 60, I would do

if(framesPerSecond < 30)
drawPlayer

That will make him flicker. If you want to actually fade him in and out, I’m not too sure.

Well I do have a something like a timer. I don’t cap the framerate yet, and im not that familiar with timers (besides AnimationTimer).

I use a counter that counts the invincibility of the player. If that counter hasn’t reached 0, a variable called alpha is manipulated. Once it hits 0.0 or 1.0 it becomes -alpha. The whole screen is flickering like I want my player too, it’s just the whole stage and not the player only ;D Kinda like disco lights :o

I know FadeTransition but i can’t use setEffect on an javafx.Image. The same goes for setOpacity or setGlobalAlpha.

I could of course place a rectangle over the player that would accept setOpacity, but the sprite of the player isnt rectangular so it will have an impact on the background as well… I could also use a spritesheet with diffrent opacities, but that would get too complex to make one with 4 diffrent opacities in any state.

EDIT: Thanks for the suggestion, I’m sure it would work out, although im pretty sure that there will be a better way…

EDIT EDIT: I’ve tried a workaround, putting the image in an ImageView and setting the opacity there. it would be working just fine, but the previous position of the image arent cleared off and it results in the whole screen being filled with my player sprite. If i could fix that, it would be fine…

The best way to do animation in JavaFX is via the AnimationTimer. It has the best granularity, running at 60fps. I’d run all animations through a single AnimationTimer.

For a “flicker function,” I’d consider having a variable that ranges from 0 to 1.0 and back (to use as an Opacity argument), with the increment being something like 0.2 (for 6 blinks per second), where the function is incremented by the AnimationTimer.

Images are generally displayed via ImageView, and ImageView has a setOpacity() method. If you have sprite sheet, won’t each image of the sheet be displayed via an ImageView node? How are you handling sprite animation? The minimal sprite animation I’ve done was with a single ImageView that picks from a sprite sheet of images. If you do that, then you can use the setOpacity() for that ImageView to turn the hero visible/invisible.

The graphic image you use has transparent pixels for the non-hero portions, yes? (alpha = 0). If so, fading the hero sprite directly via setOpacity() should work as long as there is another graphic behind the hero.

If the whole screen is flickering, you are probably changing the opacity of the wrong thing!

My main loop also consists of an AnimationTimer, i just haven’t implemented the FPS cap.

The flickering function is pretty much exactly as you suggested, just with value of 0.25. Just like this:


if(!isInvincible)
		{
			for(Enemy e : EntityManager.getInstance().getEnemyList())
			{
				if(this.checkCollision(e))
				{
					health -= 1;
					isInvincible = true;
					invincibleCounter = 50;
				}
			}
		}
		else
		{
			invincibleCounter--;
			if(invincibleCounter < 1)
			{
				isInvincible = false;
			}
			else
			{
				if(alpha == 1.0 || alpha == 0.0)
				{
					opacityChange = -opacityChange; //this is 0.25 and defined in the constructor of my player
				}
				alpha += opacityChange;
			}
		}


I have an animation class, where every possible state has an Array of Images saved. I load them into a BufferedImage(awt) and by using BufferedImage.getSubImage(…) I convert each frame into an image. The animation class then loops through the current state array and returns the current frame. Then I use GraphicsContext.drawImage(animation.getcurrentframe().getimage(),x,y,width,height) to render it onto the screen. My Player.render(gc) looks something like this:


if(facingLeft && isInvincible)
		{
			gc.setGlobalAlpha(alpha);
			gc.drawImage(animation.getImage(), (int) (tx + x - width / 2), (int) (ty + y - height / 2)); 
		}

The GraphicsContext is passed as an argument and fills the whole screen, therefore my whole screen is “flickering” while the player is invincible.

It might be that I’m confused about what exactly a node is… Why would i use a ImageView if I can display with an javafx.Image object?
Converting the animation.getImage() into an ImageView and then displaying it worked, but the positions of the player before weren’t cleared. So there was a long chain of player sprites everywhere I went. If you could help me fix that it would be perfectly fine :DD

If you need the whole code, I can upload it anytime, just tell me.

Thx and Greez

HalfNOoB