Android canvas create screen flash for few seconds - java

I am trying to accomplish having the android canvas flash from blue to red. I would like to control the flashing to be adjustable. For example change colors every 100 milliseconds for 3 seconds.
I have tried using Timer and Threads how ever the application seems to crash. I tried with and without invalidate(). I am assuming my logic is off or that i do not fully understand how its executing. Possibly it happens to fast I cant see and crashes or creates too many threads that crash the app.
Pseudo code
// canvas change color to blue
// wait 100 milliseconds
// canvas change color to red
// wait 100 milliseconds
// canvas change color to blue
// execute for 3 seconds
I would put code but since I tried multiple solutions each having the same crash or hanging effect I am assuming they won't be that helpful.
I know I can either create a rectangle shape drawable to fill the screen or just color the whole canvas which is probably the better approach.
I have two paint objects created and if I fill the canvas regularly they both work of course.
Paint paint2 = new Paint();
paint2.setColor(Color.RED);
paint2.setStyle(Style.FILL);
canvas.drawPaint(paint2);
Paint paint1 = new Paint();
paint1.setColor(Color.BLUE);
paint1.setStyle(Style.FILL);
canvas.drawPaint(paint1);
Just to sum up: I would like the canvas to flash between blue and red every 100 milliseconds for 3 seconds. But would also like both the delay (100 milliseconds) and the duration (3 seconds) to be adjustable so I can increase or decrease them.
I have tried using:
Timers
Threads
Shape drawable
System.currentTimeMillis()

Related

Full Width Graphics Cause Major Lag

I'm creating a game with processing java. I optimized the game as much as I could making sure the image textures are very small, drawing only certain portions of the map, etc., and the game runs consistently at 60 FPS. However, when I want to draw an image across the entire screen, for an example, as a tinted overlay (as seen from the image below)
the FPS significantly decreases, going from 60 FPS to around 40 FPS. The same happens if I use a fullscreen graphic, like a rect(0, 0, width, height) the FPS will still decrease when the graphic is quite large, spanning the width of the entire screen. Literally something as simple as the code below causes lag.
PImage fullscreenImg;
void setup() {
size(displayWidth, displayHeight);
fullscreenImg = loadImage("img.png");
}
void draw() {
image(fullScreenImg, 0, 0, width, width);
}
Here's a video of the lag happening when a full width image is displayed (the FPS goes from ~30 to ~20): https://www.youtube.com/watch?v=bjKFIgb2fII
I've tried to solve this problem by using the get() function, or reducing the resolution of the image (which just causes the image to be more pixely), and none of it works; the FPS still stays at around 40. Is there any way to make an image that has a very wide width, in my case, covering the entire screen, without decreasing the FPS? Am I doing something wrong?
Thanks for any help!
Make sure you are not loading the image during the draw() method. All of your images should load in your setup() function, and should be stored in a variable (memory), before the main loop executes. Otherwise the image will have to be pulled from the disk every time the game loops, which takes much longer than pulling from memory.
Hopefully this helps, I would recommend posting code samples rather than screenshots of the game (although the game looks very nice), otherwise it is a bit hard to diagnose the issue.

paint()-mehod faster while mouse is moved

I am currently working on a private project that uses a normal java JFrame, in which I paint an image (in form of an int[][] with ARGB-values). Then I plot this image pixel by pixel inside the paint()-method. I have to do this, because I want to shift/zoom the image to my liking.
When I enlarge the window to my screen size (2560*1600) one run takes about 10 secs.
Doing the same whilst just moving the mouse around this time decreases to ca. 1.5 secs. Has anyone an explanation for this 7-time boost?
Thanks!
Bike

JavaFX - Game loop canvas high CPU usage

I'm working on a simple JavaFX 2D game and I encounter performance issues.
I am rendering my game into a canvas which is updated each frame.
But updating the canvas at 60 FPS strongly increases my CPU usage, and of course my GPU usage.
It doesn't come from big calculations because I tried with very basics manipulations in the canvas, as shown below, and the problem was still there.
Based on research I have made, I use a TimeLine to implement my game loop. It seems to be the best way to update the canvas at the frame rate I want :
private void initGameLoop()
{
final Duration oneFrameAmt = Duration.millis(1000/60);
final KeyFrame oneFrame = new KeyFrame(oneFrameAmt, actionEvent ->
{
gameView.getRenderer().render();
});
gameLoop = new Timeline();
gameLoop.setCycleCount(Animation.INDEFINITE);
gameLoop.getKeyFrames().add(oneFrame);
}
In this configuration I'm running my game loop at 60 FPS, and the changes are running on the FX application thread.
My render function is very simple :
public void render()
{
gc.clearRect(0, 0, 50, 50);
gc.setFill(Color.BLACK);
gc.fillRect(0, 0, 50, 50);
}
gc is the graphicsContext2D of my canvas.
My canvas is scaling on my application's window size, but I'm simply redrawing a 50x50 black rectangle each frames, at 60 FPS my CPU usage increases by 8-10% on default window size, but on full screen my CPU usage increases by 25% to 30% which is insane.
The hardware acceleration is running, besides my CPU usage, my GPU usage is around 30%.
I can't just stop rendering the canvas when nothing happens in the game, because I need to render my animations.
And basically redraw only partials areas of the canvas doesn't change anything because my basic test (shown above) only redraw a 50x50 pixels rectangle on the upper left corner of the canvas, and it still uses 25%+ of the CPU.
All the examples of game loop or animations made with JavaFX that I have found on the web uses the same techniques, but every one I have tried so far have a high CPU usage.
My rendering is very smooth and fluid but the CPU usage is way to high for what it makes. I can't seem to find why doing so little takes so much on my CPU and GPU and can't find a solution on how to improve my game perfomances. From what I have found on my research, canvas seems to be the best way to render a game in JavaFX.
My questions are : Is there any way to improve performance using a canvas ? Should I be using the scene graph with multiple elements ? Or is there any solution that I have not think of yet ?
Thanks for your help !
Conceptionally JavaFX rendering always has a CPU and a GPU portion. In the CPU portion the geometry is prepared to be rendered and the GPU portion finally does the rendering. Canvas rendering is the slowest option because the API forces you to always create new objects in each frame when you want to change something which means that you always suffer from the slow CPU portion of the rendering. On the other hand scene graph rendering can be faster if the changes you apply to your scene are only translation transforms (which can be extended to rotations and scaling with the appropriate rendering hints) because then you suffer from the slow CPU portion only once but not in every frame. If you constantly have to change the geometry too, then you are lost with both approches and the only option is to go for 3D rendering (which is what I do) via a triangle mesh. The nice thing is that in JavaFX 3D rendering can be easily combined with 2D rendering to get the best of both worlds.

Make a dynamically re-sized, BufferedImage, scroll, that renders actively

I have stumbled upon a bottle neck that I would love to fix.
I need to make a BufferedImage grow with time, but the Buffered image should support scrolling as my application requires that the Bufferedimage grow a significant size over time. However the draw calls are not done by the event dispatch thread.
I have a while loop that performs the render calls. What I attempted was to create an instance of a Canvas and add it to a JScrollPane however when I take this approach, the JScrollPane performs its own draw calls and I am not sure how the JScrollPane will detect that the canvas has resized at runtime.
The other issue is that since within the canvas I use a BufferedImage to draw onto, I cannot get it to resize with a temporary BufferedImage.
Here is how I attempted to create a new, larger BufferedImage
if(needsToBeResized)
{
BufferedImage temporaryBufferedImag =
new BufferedImage(originalImage + extraSpace, height, originalImage.getType());
Graphics g2d = temporaryBufferedImag.createGraphics();
g2d.drawImage(originalImage, 0,0,null);
//I presume that this should copy the graphics object with the original img
originalImage = temporaryBufferedImag;
g2d.dispose();
}
If it helps I am developing an oscilloscope type application that needs to be able to keep plotting values real-time but I also need to be able to show the history of values.
Render each interval in its own "mini" BufferedImage. So, for a gross example, say you render every second, and you want to show 20 seconds of history.
So, you render your current second in to a "1 second sized" image. Then you take your cache of the images from the previous 19 seconds, and you stamp them all together, one after the other in to your new total image, and display that.
Next second, you drop off the oldest image, create a new one, stick it on the end, rinse and repeat.
If your overall frame size changes, when you get to render all of the pieces all over again…c'est la vie.
Obviously you will be sampling more than once a second, but you get the gist of it.
All this assumes this is cheaper than simply re-rendering the entire thing from scratch each time.

Smooth animation (Java SWT)

i've got a question about drawing animations in Java (SWT).
I try to draw an animation of some process.
When i use canvas.redraw() program firstly erases everything that has been drawn and then draws again.
My program draws about 1000 of rectangles per time step (this big quantity is necessary) so animation doesn't looks smooth - it blinks all the time.
Is there a way to make it look smoother, for example to paint new objects over old ones, without erasing them (that would look better anyway)?
The solution for flickering when doing custom painting is to use double buffering. The SWT Canvas object has built-in double-buffering, use it by adding the flag to the styles in the constructor:
Canvas myCanvas = new Canvas (parentComposite, SWT.DOUBLE_BUFFERED);

Categories