dGFisher
dGFisher

Reputation: 107

Creating "Pixel" Type Shapes in 2D Arrays

I am a beginner programmer currently making a grid-based strategy game where characters can create differently shaped targets, move those targets around within range, and "fire" the target to pass them a list of enemies in the target squares (cells of a 2d array).

I plan on having a lot of these shapes, and having them come in different sizes as well, things like: plus, x, cone, v, hand, eye, smile, square, circle, etc. Complexity is increased by some targets which change facing with the player. Currently I do this by filling an ArrayList of Points as such:

public ArrayList<Point> getTargetArea (int facing, Target tCenter){
    ArrayList<Point> targetArea = new ArrayList<>();
    int x = tCenter.getX();
    int y = tCenter.getY();
    switch (shape){
        case "Dot":
            break;
        case "Small X":
            targetArea.add(new Point(x-1,y-1));
            targetArea.add(new Point(x+1,y+1));
            targetArea.add(new Point(x+1,y-1));
            targetArea.add(new Point(x-1,y+1));
            break;
        case "Small Cone":
            if (facing==GC.FACING_UP){
                targetArea.add(new Point(x-1,y-1));
                targetArea.add(new Point(x,y-1));
                targetArea.add(new Point(x+1,y-1));
            }
            else if (facing==GC.FACING_RIGHT){
                targetArea.add(new Point(x+1,y+1));
                targetArea.add(new Point(x+1,y));
                targetArea.add(new Point(x+1,y-1));
            }

            and so on...

I acknowledged this as a temporary measure when I first set it up, and now that I'm returning to add more complicated shapes (The larger ones have 40+ Points) I figure its time to revisit how this is accomplished. If I were to stick with this design, I would either pre-create each different type of targetArea (cone, x, etc) as private static final ArrayList or create them in methods.

I was thinking that parsing the shapes from a text file might be a better way to do it, but as a new programmer, I might be missing some obvious way to accomplish this task easily.

So, to focus:

What would be the best way to add grid shapes to a 2D array?

Upvotes: 0

Views: 840

Answers (1)

Andy Turner
Andy Turner

Reputation: 140309

You have a couple of options.

Firstly, you could declare your shapes in your source code, e.g. using a byte array:

byte[][] shape = {  // e.g. for small x
  { 1, 0, 1 },
  { 0, 0, 0 },    // Is there a 1 missing from the middle?
  { 1, 0, 1 },
};

Then you can render this into your target area like this:

for (int r = 0; r < shape.length; ++r) {
  for (int c = 0; c < shape[r].length; ++c) {
    if (shape[r][c] != 0) {
      targetArea.add(new Point(x + c, y + r));
    }
  }
}

You might also want to introduce an offset parameter, in this case to shift it by (-1, -1), so that the center is at (x, y).

The two disadvantages of this are:

  1. Arrays are mutable, so you could accidentally stomp the data in the array if you don't reallocate it every time.
  2. It is a little bit tricky to see what the shape is. You can squint and turn your head, but it is a little abstract.

The solution to the first point is to use some immutable structure. For example, you could use a string, something like:

String shape = "X X\n"
             + "   \n"
             + "X X\n";

which you then split into lines, and add a point where you find the X. It is still a bit hard to see the shape though.

A solution to the second point is to store the images as bitmapped images. You can load an image from a file using ImageIO, giving you a BufferedImage. You can query the pixel color using BufferedImage.getRGB(). So, just go through all x and y in the image, and check if the pixel is, say, white (add the point) or black (don't add the point).

Upvotes: 1

Related Questions