Sunday, May 15, 2011

Implementing a HeartLight clone in XNA, continued (2)

One if the issues with my implementation I’ve been trying to resolve is the way HeartLight implements falling blocks. There are at least few levels to test this, my favourite is the level 20 which starts with several stones and hearts falling from the top to the bottom. The way they fall and interact during falling determines the way the board looks like when all the blocks finally fall and do not move anymore (and this is when player can start the level).

The level in HeartLight, after blocks finally fall down looks like this:

If you try this level in my original implementation you’ll however end up with following:


Most blocks completely miss their destination and although the physics I’ve implemented feels ok, it surely gives different output.

Unfortunately, I do not have the source code of HeartLight. The only way to “debug” the implementation was then to slow down both versions (mine and the original) and stone-by-stone, heart-by-heart try to find the difference in the way objects fall. I also tried to validate each single observation by slight changes in the implementation. It was then “reimplement – rethink – reimplement -rethink” cycle.

The first big difference I’ve found concerns the way blocks “bounce” when they fall down. I’ve mentioned this last time but when there’s an empty space to the left/right of the block, the block is supposed to move there (bounce). It turned out however that there’s a one frame delay in this move. This has a huge impact on the way blocks interact when they fall, as a free square not occupied by an object because of the delay can be occupied by another object.

Another very subtle difference I have found (and this was quite tricky) is the way HeartLight implements per-frame loops for X axis and Y axis. My first approach was to analyze rows from the lowest in the outer loop and then columns in the inner loop. HeartLight however has this inverted – the outer loop is for columns and the inner – for rows.

What’s important is that the final output of a fixed physics routine is now correct (below). Compare it with the first screenshot taken from the original version.

Next issue to fix is the way bombs explode. There’s also a great testing ground (below). In my implementation this level is currently completely unplayable.

Expect then to hear more on that in the future.

No comments: