3

I am developing a game on Android that involves a grid of objects. Right now I am using an array to store the objects, like this:

public class ObjectBuffer {

  private final Object[] buffer;

  private final int playfieldWidth;

  ObjectBuffer(int playfieldWidth, int playfieldHeight) {
    super();
    this.buffer = new Object[playfieldWidth + (playfieldHeight * playfieldWidth)];
    this.playfieldWidth = playfieldWidth;
  }

  public static int getX(int id) {
    return id % playfieldWidth();
  }

  public static int getY(int id) {
    return id / playfieldWidth();
  }

  public Object get(int id) {
    return this.buffer[id];
  }

  public Object get(int x, int y) {
    return this.buffer[x + (y * this.playfieldWidth)];
  }
}

But, my questions is, is this the best way to accomplish this? I chose an array (as opposed to a list, ArrayList, or some other container) because once the width and height of the playfield are set, they do not change. The objects are there for state, and once they are instantiated and added to the array, they may be updated, but are not rearranged.

My question is similar to Storing objects for locating by x,y coordinates, but different enough that I wanted to ask my question separately. My requirements are different from his, and I don't think that a spatial index would be warranted in this situation. Please correct me if I'm wrong.

I should also mention, the array's dimensions will usually be 10x10 (100 elements), but may need to be able to accommodate a modest increase; but will not need to handle more than about a 15x15 grid (225 elements). These dimensions will always be known when generating the grid. After the grid has been generated, the dimensions will not change.

Community
  • 1
  • 1
DavidDraughn
  • 1,110
  • 1
  • 8
  • 15
  • For your game, I'm guessing that each point in the grid can hold a Object like a bullet, battleship, elf, or whatever. Can two of them be at the same point? If so, you may need to use some sort of Collection at each of the points on the grid. – user949300 Jan 06 '12 at 17:48
  • Each location in the grid will hold a bubble, and each bubble can be a different color, or have other attributes. The bubbles don't overlap, when tapped, that bubble, or other bubbles around it, will 'pop' and disappear, then the bubbles above will fall down to take it's place. – DavidDraughn Jan 06 '12 at 18:43

3 Answers3

1

A multidimensional array would be a better solution:

Object[][] playfield = new Object[w][h];

This gives more readable code, since you can refer to an element as playfield[x][y] instead of playfield[x + y * WIDTH]. Another option, if you want to use Collections, would be the Table classes in Google Guava.

Russell Zahniser
  • 16,188
  • 39
  • 30
  • I would be open to using a multidimensional array, but what is better about it? With a one-dimensional array, you have one array object plus one object per element. With a multidimensional array there are objects for each array (so 10 rows and 10 columns means 11 array objects) and then the objects that go into the elements. That means that to use a multidimensional array, I need to increase the number of objects by 11% (for a 10x10 playfield). aside from the math involved in converting between the xy address and the array index, I don't see any other benefits. – DavidDraughn Jan 06 '12 at 17:22
  • So a 10x10 playfield is 10 extra objects. Unless your playfield is huge, 10s or even 100s of extra objects is no big deal. – user949300 Jan 06 '12 at 17:44
  • @user949300 That's true, having a few extra objects is no big deal. But why create them if you don't need to? Especially on a phone or other mobile device, where memory is more limited than a computer, it's best not to create more objects than you need to. With that said, the math involved with getting an index from x and y coordinates and x and y coordinates from an index IS a negative. However, it's not a big enough deal for me to switch my implementation. Is there other reasons to make the switch? – DavidDraughn Jan 06 '12 at 18:20
  • As soon as the shape of your array changes (say, row 4 is the special Spinal Tap row that goes to 11 while all the others have 10) you'll regret your decision. :-) – user949300 Jan 06 '12 at 19:14
  • @user949300 if you change your answer to say that a multidimensional array is another solution (or similar) instead of a better solution, then, I will choose it as an answer to my question, because of the three, it comes closest. – DavidDraughn Jan 06 '12 at 19:34
  • @DavidDraughn it was originally Russels answer - talk to him and give him the credit. – user949300 Jan 06 '12 at 20:14
  • oops, I just had the user949300 text in the comment box by habit. lol My bad. @Russel Zahniser if you change your answer to say that a multidimensional array is another solution (or similar) instead of a better solution, then, I will choose it as an answer to my question, because of the three, it comes closest. – DavidDraughn Jan 07 '12 at 04:54
1

Better option would be to make a class point

    class Point
    {
    int x;
    int y;

    //getter and setter methods for x and y

public void setCoordinates(int x, int y)
{
this.x=x;
this.y=y;
}

    }

then create an array of Point objects

Point[] mypoints

when you want to set co-ordinates for mypoint[i]

mypoint[i].setCoordinates(30,40)
Rajesh Pantula
  • 10,061
  • 9
  • 43
  • 52
  • The class that I store have the x and y coordinates along with the index, ImageView that presents that location to the user, and other state information. Thanks for your suggestion. – DavidDraughn Jan 06 '12 at 17:33
1

Collections aren't just about supporting data structures of a dynamic size, they're for defining data structure behavior. There's nothing inherently wrong with using an array (at some point in the call stack it will be anyway), but defining a collection allows you the flexibility of calling methods to get what you need rather than referencing array coordinates. That way if you need to change the behavior of the coordinate system (for instance, say you wanted to mask the contents of a grid reference from another player?) you won't necessarily need to touch the code that iterates through your array.

Mike Yockey
  • 4,565
  • 22
  • 41
  • I don't see how I can fulfill my needs with a collection in a way which would allow the performance and simplicity of my ObjectBuffer class. I would need to define a key. The best I can think of would be the index that I'm using now. To retrieve the object at a specific location, I would need to search the collection for the correct key (or the collection would). Even using a hash, that process seems much slower than pointing to a reference (the index of an element in an array). In a way, my ObjectBuffer class is a type of collection, just not one that is included with Java. (to be continued) – DavidDraughn Jan 06 '12 at 18:39
  • (continued from last comment) Please help me understand how to implement what you describe. I can provide more details of my implementation if needed. – DavidDraughn Jan 06 '12 at 18:39