0

In my game that I am creating, I am using blocks. To simplify my life, I created a class that accepts an array of blocks, and adds them to the block set for me.

Block set (in World class):

Set<Block> blocks = new HashSet<Block>();

BlockCollection class:

public class BlockCollection
{
    private World world;
    Set<Block> blocks = new HashSet<Block>();

    public BlockCollection(World world, Vector2 position, Block[] blocks)
    {
        this.world = world;

        for (Block block : blocks)
            this.blocks.add(new Block(new Vector2(block.position.x + position.x, block.position.y + position.y)));
    }

    public void flip()
    {
        //Flip the set
    }

    public void add()
    {
        world.blocks.addAll(blocks);
    }
}

(The library that I am using is libgdx, the Vector2 class is basically a vector with an X float and a Y float)

I added an array of blocks that looks like this:

Block[] spike = {
        new Block(new Vector2(0, 0)),
        new Block(new Vector2(1, 0)),
        new Block(new Vector2(2, 0)),
        new Block(new Vector2(3, 0)),
        new Block(new Vector2(1, 1)),
        new Block(new Vector2(2, 1)),
        new Block(new Vector2(3, 1)),
        new Block(new Vector2(1, 2)),
        new Block(new Vector2(2, 2)),
        new Block(new Vector2(1, 3)),
        new Block(new Vector2(2, 3)),
        new Block(new Vector2(1, 4)),
};

It works, but now I'm trying to add functionality to flip the set of blocks in the flip() method of the BlockCollection class. It would help me not need to hardcode every single variation of every single object I make with blocks.

Can anyone share any insight, maybe an equation, of how to do this? Any help is much appriciated.

EDIT: By flip, I mean flip the shape along the x axis, similarly to flipping an image. Example:

Original vs. Flipped
00100 | 11111
01110 | 01110
11111 | 00100

LulzCop
  • 131
  • 1
  • 9
  • 1
    The first thing you'll have to do is stop using `Set`. [Sets aren't ordered](http://docs.oracle.com/javase/7/docs/api/java/util/Set.html), so as soon as you take your array of blocks and add them to your `HashSet`, they no longer have any order. If you need order, you could use one of the [`SortedSet`](http://docs.oracle.com/javase/7/docs/api/java/util/SortedSet.html) implementations. That would at least get you headed the right way. – T.J. Crowder Jan 05 '13 at 18:23
  • The thing is, I don't need any order. I used sets because I didn't want two blocks in the same space. – LulzCop Jan 05 '13 at 18:30
  • What do you mean by flip the set? Turn, say, `1, 2, 3` into `2, 3, 1`? – fge Jan 05 '13 at 18:33
  • Wat do you mean by "flipping the set"? I understood it as reversing the order of the `Block`s in `blocks` but apparently that's not what you want. Or do you mean "swapping the X and Y coordinates of the `Vector2`s in each `Block`"? – Mattias Buelens Jan 05 '13 at 18:34
  • I added an example to the bottom of the question, sorry for the lack of clarity. – LulzCop Jan 05 '13 at 18:39
  • 1
    Still not clear, I'm afraid :( Where is your original set and the expected result in your example? – fge Jan 05 '13 at 18:39
  • @LulzCop is my answer any close to what you want to achieve? It reverses all blocks in your set. – fge Jan 05 '13 at 18:41
  • OK, Lemme see if this helps clarify: I have the set, with 9 blocks. The 1s represent blocks, 0s represent spaces. What I want to do is change the Y-value of each individual block, so that it appears like the flipped image in the OP. Sorry if I'm bad at explaining :/ – LulzCop Jan 05 '13 at 18:47

2 Answers2

0

If by "flipping the set", you mean to invert the order of all elements in it, the first thing you should do is use a LinkedHashSet for blocks and not a HashSet: a LinkedHashSet will preserve insertion ordering. A HashSet makes no such guarantee.

The .flip() method could then be written like this:

public void flip()
{
    List<Block> l = new ArrayList<Block>(blocks);
    Collections.reverse(l);
    blocks.clear();
    blocks.addAll(l);
}
fge
  • 119,121
  • 33
  • 254
  • 329
0

You probably want to change your data structure and use the coordinates as keys for the Blocks. If you know the size of your image at construction, you could use a two-dimensional array to store all your blocks, with the Y coordinate as first index and the X coordinate as second index:

this.blocks[y][x] = block;

Then, flipping along the X axis can be accomplished by simply reversing the order of the rows:

public void flip()
{
    List<Block[]> blocksAsList = Arrays.asList(blocks);
    Collections.reverse(blocksAsList);
    blocks = blocksAsList.toArray();
}

You didn't elaborate much as to what Block and BlockCollection actually represent. In your example, Block seems to have its own Vector2. Does it own and control that position? Can a Block be owned by none, one or multiple BlockCollections? If a Block controls its position, what should happen to a BlockCollection containing a Block which has changed its position? Can and/or should the BlockCollection update a Block's position when flipping? Does Block really need its own position? ...

Community
  • 1
  • 1
Mattias Buelens
  • 19,609
  • 4
  • 45
  • 51
  • Thanks for the answer! About the second part of your answer, Block _technically_ can update its own position, but it doesn't. BlockCollection is a convenience class of sorts, its purpose is to take an array of blocks, and wrap an object around it, so that I can easily manipulate those blocks independently from other blocks. – LulzCop Jan 05 '13 at 19:27