Canvas: refresh screen on touch - java

I'm trying to make something like Battleships.
By this time I've managed to random spawn and draw them on canvas.
But there's another problem: in the game user will touch the cell and that cell will be painted as yellow (if hit) or draw a dot (if miss).
As far as I see, everything that displays on canvas must be writted in onDraw() method.
The question is: how can I make screen refresh with new data when user touches the screen?
Now the screen looks like this:
This time the ships are visible for debug

Related

Libgdx: the render method

I don't think I understand how the render method works.
From what I read online / saw on youtube tutorials, I gathered that the render method is a looping function that you can use to keep your game updated and read users' inputs. When you want to draw something in the screen you do so in this method, and before drawing anything you clear the screen.
But if I want to draw something stationary, wouldn't it be better to draw it outside the render method (so the computer doesn't have to clear the screen and redraw everything many times)?
What am I missing?
You can't draw outside the render method, because it's the method called on the OpenGL thread. You can't draw to OpenGL from other threads.
If your entire screen is frequently static for more than a few ms, which might be the case in something like a card game, you can disable the continuous refreshing of the screen using Gdx.graphics.setContinuousRendering(false). This will save energy because the GPU and CPU won't have to work as hard. See here for instructions on using it.
As for why this typically isn't done:
Think of a "frame buffer" as a bitmap image in memory that can be drawn to and then shown on screen. Most mobile rendering is done with double-buffering. This means while one buffer is being drawn to (the back buffer), the front buffer that was drawn to on the previous frame is being rendered directly to the screen. They swap back and forth each frame for faster rendering.
The way graphics work is that each item that's drawn modifies the color of pixels in the frame buffer where the item is drawn. Items may be masked or be translucent, and these will alter the color of pixels behind them. The original color of those pixels are lost once something is drawn in front and modifies them
So, even if some item on your screen is static, if there are other items on the screen that move or change color, and they overlap the static item (either in front of or behind), you still have to redraw the whole screen every time anything changes.
If one area of the screen is static and never overlapped by dynamic objects, and the dynamic objects are contained entirely within a rectangle, you could potentially set a viewport that limits drawing to the dynamic area and avoid clearing the whole screen. However, GPUs are designed specifically to be efficient at clearing the whole screen. Because of double-buffering, if you don't clear the whole screen, it's actually likely to harm performance because if you don't clear it, the contents of the screen have to be copied between the front and back buffers before you can start drawing the next frame.
Another strategy is if you have a static object that is very complicated and taxing for the GPU to draw because it has lots of layers or a complicated shader, you could draw it to an off-screen frame buffer object (FrameBuffer class in libGDX) one time, and then render that FrameBuffer's texture to the screen on each frame like a sprite.

Canvas where you can draw with red or blue color and background image

I am trying to make an Android app where an image would always be in the background and when you touch above it, you can draw on it with red and it would be anti-aliased. Also, there would be a revert and a delete all drawings button.
You may record every segments consisted of coordinates drawn by user, every time the ui refresh, clear the Canvas and redraw all the segments. For reverting, you remove the last segment, for deleting all you remove all segments.
Further more, if you need other operation, you may have to abstract an interface (named DrawingOperation for example) with undo/redo method.

Paint Scrollbale Infinite Generating Grid

I am trying to draw a grid of rectangles and I want to be able to draw them off the screen in all directions and then be able to scroll this, changing which are actually in the screen without having to redraw every frame.

Painting a custom Mouse over your preset mouse

I'm making a game and when I add my sprites to my screen, naturally, they are behind my mouse. But I want to add a custom mouse image to my screen, over the mouse.
I already have sprites for the mouse, and I know to to make the image appear wherever my mouse is. The only thing is that I already know its going to appear underneath my mouse. Any suggestions?
Set the image as a custom Cursor. See Toolkit.createCustomCursor(Image,Point,String) for turning the image into a cursor.

How to handle multiple elements in canvas

I'm making a UI application in java and I was trying to draw some graphics to represent a compass in a window. I'm handling the rotation with the mouse dragged event on my canvas but the problem is that everything in my canvas is rotating. I'd like to know if I can handle every elements I draw in my canvas separately so only my arrow will move and not the whole canvas.
Thanks
Presumably you've got a draw loop that draws a bunch of things. Background, compass, arrow for the compass. Maybe some other things.
When you draw with a canvas you issue commands to the context that are akin to loading up a paintbrush with paint.
If you want to paint a red line and then a blue line you pick up some red paint, paint one line, then clean your brush and pick up some blue paint and paint that line.
The canvas context is exactly the same. What you want to do here is paint a bunch of things on a normal canvas context. Then you want to save the context with ctx.save() and do your rotations.
When you translate or rotate or even just set a fill on the context you aren't changing things that were already done, you're just saying "for everything after this point, apply these operations."
So then you paint the compass arrow/needle.
Then call ctx.restore() and continue on your merry way. This will stop the rotation from happening to things drawn after the arrow.
the save and restore functions of the context keep track of the old state so that you aren't drawing everything after the needle with a rotated context. It's kind of like washing a paintbrush, only better, because you can remember that it used to have blue on it instead of having to wash it clean every time.
By the way, if you do want to reset your canvas context to its default state completely (black brushes, default transform, no shadows, etc), you can simply do canvas.width = canvas.width and it will give the context a full reset.

Categories