Android - onDraw canvas with an enlarged camera after character movements

Context:

I am creating an Android game that draws a maze on canvas against the background image, it uses a square block, and so the maze always automatically increases to a 5 x 5 square, a maze that can be 20 x 20. The maze is drawn with a simple run through the set for cycles, and then by drawing lines in appropriate places. All this works great, however, I had a problem with making my onDraw work smoothly. This is due to the fact that every time I am invalid, I have to re-run the for scan and run various if statements to check the positions (unfortunately, this process cannot be improved).

Question:

I am looking to rewrite the way my labyrinth is drawn on canvas, below are the three main functions that I need to implement:

1 - draw the entire labyrinth on the canvas (it's quite simple) 2 - Zoom in on the labyrinth so that only 5 x 5 is displayed 3 - Move the character (which is always in the center of the screen) and draw the next labyrinth timer

Now, as mentioned above, drawing the entire maze is quite simple and will make onDraw much faster, since they do not need to run the for loop on invaldate, this can be done once when the level is first loaded.

In terms of 2 and 3, as I see it, this works, it is a symbol that needs to be drawn in the middle of the canvas, and then a 2-dimensional bird viewing camera that needs to be attached / connected to the movement of the symbols. This camera also needs to be enlarged to such an extent that it displays only 5 x 5 of the total grid of the maze. Then, when the sharkator moves the camera, it moves with the symbol and displays the next section of the labyrinth already drawn. I tried several things and did some re-research, but I have never worked with a canvas before and I don’t know where to start, and if possible.

So, to summarize, the main part of the question is whether their way to connect the birdseye view camera with a symbol that is enlarged and moves with the symbol image.

The following is a snippet of how the maze is currently running, using 2 sets to test loops against 2 sets of logical arrays [] [] that simply store the vertical and horizontal lines that need to be drawn.

@Override protected void onDraw(Canvas canvas) { canvas.drawRect(0, 0, width, 100, background); RectBackground.set(0,0, FullScreenWidth, FullScreenWidth); canvas.drawBitmap(gameBackground, null, RectBackground, null); for(int i = 0; i < 5; i++) { for(int j = 0; j < 5; j++) { float x = j * totalCellWidth; float y = i * totalCellHeight; indexY = i + currentY; indexX = j + currentX; // Draw Verticle line (y axis) if (indexY < vLength && indexX < vLines[indexY].length && vLines[indexY][indexX]) { RectOuterBackground.set((int)x + (int)cellWidth, (int)y, (int)x + (int)cellWidth + 15, (int)y + (int)cellHeight + 15); canvas.drawBitmap(walls, null, RectOuterBackground, null); } // Draws Horizontal lines (x axis) if (indexY < hLength && indexX < hLines[indexY].length && hLines[indexY][indexX]) { RectOuterBackground.set((int)x, (int)y + (int)cellHeight,(int)x + (int)cellWidth + 15,(int)y + (int)cellHeight + 15); canvas.drawBitmap(walls, null, RectOuterBackground, null); } } } } 
+6
source share
2 answers

To make drawing faster, you can double the canvas buffer by drawing directly into a bitmap and blinking a bitmap on a canvas like this. It's very fast.

 private void init() { //variables below are class-wide variables b = Bitmap.createBitmap(cwidth, cheight, Bitmap.Config.ARGB_8888); bitmapPaint = new Paint(Paint.ANTI_ALIAS_FLAG); bitmapPaint.setStyle(Paint.Style.STROKE); bitmapPaint.setStrokeWidth(3); myPaint.setColor(0xff000000); myCanvas = new Canvas(b); } protected void onDraw(Canvas c) { super.onDraw(c); c.drawBitmap(b, 0, 0, myPaint); for(int i = 0; i < number lines; i++) { //draw here using myPath } if(b != null) c.drawBitmap(b, 0, 0, myPaint); myCanvas.drawPath(myPath, bitmapPaint); } 

Then, to "move around", I would suggest using a cropping field. This means that the scale is 1: 1, the image is larger than the viewport displayed on the screen. Indeed, what happens when someone β€œmoves” the bitmap moves under the cropping frame.

You can use BitmapRegionDecoder and display only the area in which the character is located (this may be slow) or with

 public void drawBitmap (Bitmap bitmap, Rect src, RectF dst, Paint paint) 

Here, the src parameter allows you to specify a small area of ​​the displayed bitmap. This is really a harvest field.

+1
source

To zoom in or out, you need to multiply the coordinates by a number (scale factor)

 int x1 = (int)x + (int)cellWidth; int y1 = (int)y; int x2 = (int)x + (int)cellWidth + 15; int y2 = (int)y + (int)cellHeight + 15; RectOuterBackground.set(x1*zoom, y1*zoom, x2*zoom, y2*zoom); 

note that scaling should be a floating point number using zoom = 2, which makes everything twice as big.

if you want to put the camera on top of the cell (xc, yc), you need to do this:

 RectOuterBackground.set( (x1-xc)*zoom, (y1-yc)*zoom, (x2-xc)*zoom, (y2-yc)*zoom); 

Try to draw the entire labyrinth first, and soon you will understand as soon as you draw a bit of the labyrinth, which is only inside the screen.

I hope this helps and let me know if you have questions :)

+1
source

Source: https://habr.com/ru/post/958788/


All Articles