2
votes

My app that I am trying to create is a board game. It will have one bitmap as the board and pieces that will move to different locations on the board. The general design of the board is square, has a certain number of columns and rows and has a border for looks. Think of a chess board or scrabble board.

Before using bitmaps, I first created the board and boarder by manually drawing it - drawLine & drawRect. I decided how many pixels in width the border would be based on the screen width and height passed in on "onSizeChanged". The remaining screen I divided by the number of columns or rows I needed.

For examples sake, let's say the screen dimensions are 102 x 102.

I may have chosen to set the border at 1 and set the number of rows & columns at 10. That would leave 100 x 100 left (reduced by two to account for the top & bottom border, as well as left/right border). Then with columns and rows set to 10, that would leave 10 pixels left for both height and width.

No matter what screen size is passed in, I store exactly how many pixels in width the boarder is and the height & width of each square on the board. I know exactly what location on the screen to move the pieces to based on a simple formula and I know exactly what cell a user touched to make a move.

Now how does that work with bitmaps? Meaning, if I create 3 different background bitmaps, once for each density, won't they still be resized to fit each devices screen resolution, because from what I read there were not just 3 screen resolutions, but 5 and now with tablets - even more. If I or Android scales the bitmaps up or down to fit the current devices screen size, how will I know how wide the border is scaled to and the dimensions of each square in order to figure out where to move a piece or calculate where a player touched. So far the examples I have looked at just show how to scale the overall bitmap and get the overall bitmaps width and height. But, I don't see how to tell how many pixels wide or tall each part of the board would be after it was scaled. When I draw each line and rectangle myself based in the screen dimensions from onSizeChanged, I always know these dimensions.

If anyone has any sample code or a URL to point me to that I can a read about this with bitmaps, I would appreciate it.

BTW, here is some sample code (very simplified) on how I know the dimensions of my game board (border and squares) no matter the screen size. Now I just need to know how to do this with the board as a bitmap that gets scaled to any screen size.


 @Override
   protected void onSizeChanged(int w, int h, int oldw, int oldh) {
      intScreenWidth = w;
      intScreenHeight = h;

      // Set Border width - my real code changes this value based on the dimensions of w
      // and h that are passed in. In other words bigger screens get a slightly larger
      // border.
      intOuterBorder = 1;

      /** Reserve part of the board for the boardgame and part for player controls & score
          My real code forces this to be square, but this is good enough to get the point
          across.
      **/
      floatBoardHeight = intScreenHeight / 4 * 3;

      // My real code actually causes floatCellWidth and floatCellHeight to
      // be equal (Square).
      floatCellWidth = (intScreenWidth - intOuterBorder * 2 ) / intNumColumns;
      floatCellHeight = (floatBoardHeight - intOuterBorder * 2) / intNumRows;

      super.onSizeChanged(w, h, oldw, oldh);
   }


I think I found the answer. I might not be able to find the exact width/height and location of each playable square within a single scaled bitmap, but by looking at the Snake example in the SDK, I see it doesn't create 1 bitmap for the entire board and scale it based on the screen dimensions - instead it creates a bitmap for each tile and then scales the tile based on the screen resolution and the number of tiles wanted on the screen - just like I do when I draw the board manually. With this method, I should be able find the exact pixel boundaries for all of the playable squares on the board. I just have to break the board into multiple bitmaps for each square. I probably will have to do a similar approach for the borders, so I can detect their width/height as well after scaling.

Now I will test it to verify, but I expect it to work based on what I saw in the Snake SDK example.

--Mike


I tested a way to do what I was asking and it seems to work. Here is what I did:

I created a 320 x 320 bitmap for a board. It was made up of a border and squares (like a chess board). The border was 10 pixels in width all the way around the board. The squares were 20 x 20 pixels.

I detected the width and height of the screen through onSizeChanged. On a 480 x 800 display, I would set the new width for the board to be 480 x 480 and use the following code to scale the whole thing:


protected void onSizeChanged(int w, int h, int oldw, int oldh) {        
    floatBoardWidth = w;
    floatBoardHeight = floatBoardWidth;

    bitmapScaledBoard = Bitmap.createScaledBitmap(bitmapBoard, (int)floatBoardWidth, (int)floatBoardHeight, true);      

        super.onSizeChanged(w, h, oldw, oldh);
}

Now in order to detect how many pixels wide the border was scaled to and how many pixels in height & width the squares were scaled to, I first calculated how much the over all image was scaled. I knew the bitmap was 320 x 320, since I created it. I used the following formula to calculate how much the image was scaled:

floatBoardScale = floatScreenWidth / 320;

In the case of a 480 width screen, floatBoardScale equals: 1.5. Then to calculate what my border within the full bitmap was scaled to, I did:

floatBorderWidth = 10 * floatBoardScale;

10 was the original border width in my 320 x 320 bitmap. In my final code I won't hardcode values, I will use variables. Anyway, in the case of this formula, the new calculated border width should be: 15

When I multiplied the same scale factor to the board squares (that were 20 x 20 in the original bitmap) I got new values of 30 x 30. When I used those values in my formulas to calculate what square a person touched, it worked. I touched every corner of the squares and in the center and it always calculated the right location. Which is important, so no matter what the screen resolution, I know where the user wanted to move a piece and visually it shows up in the right location.

I hope this helps anyone who may have had the same question. Also, if anyone has a better method of accomplishing the same thing, please post it.

1

1 Answers

2
votes

A couple things. First, start reading about how to support multiple screens. Pay close attention to learning about dips and how they work.

Next, watch this video (at least the first 15-20 minutes of it).

This subject isn't a cakewalk to grasp. I found it best to start playing around inside my code. I would suggest creating a surfaceview and start messing around with some bitmaps, different emulators (screen sizes and densities), and the different types of drawable folders.

Unfortunately, there is more to this topic than I think Google wants to admit, and while it's definitely do-able is isn't simple to get started on it for some types of applications.

Finally, you should consider boiling down your question to be more straight forward if you aren't looking for an abstract answer (like this one).

Good luck!