Ray Breaker

Demo


Introduction

When I discovered "block breaker" games where you shoot a stream of balls around the screen and break square bricks, I thought wouldn't it be much more fun if blocks weren't limited to squares aligned in a grid? What if there were various shapes falling at various angles? And wouldn't it look a lot cleaner and easier to read angles if it was a ray of light instead? And since it is a ray of light, let's include prisms!

Exactly which shapes to use took a long time to figure out. I started with pieces of fruit, then tried alphabetical letters.
But in the end I had these 3 worlds: Impossible Shapes, Pentominoes and Origami Animals.

screenshots of the three worlds

Features


Implementation Details

I chose to make the game a native Android application for a number of reasons. I already had some experience making native Android games. I have substantial experience developing in Java and I also teach Java. I wanted to test a prototype as soon as possible and learning a game engine would have postponed it. And I felt it gave me better control over the game's interaction with the OS and hardware.

The game always works in native resolution regardless of aspect ratio. All the bitmaps are downscaled accordingly the moment they are loaded to precisely match screen width. The same is also true for menu icons. As a result, the game always uses the entire screen while maintaining sharp and consistent look.

Each shape's outline is stored as a series of coordinates that match the outline of the shape in the original unscaled bitmap. When the bitmap is scaled down, the outline coordinates are scaled down accordingly. This way all the intersection and reflection calculations happen directly in screenspace. The only situation where this causes a problem is when the device's resolution changes, in which case the game will notice current resolution doesn't match the resolution recorded in the save file and simply recalculates outlines.

Because the game has various complicated shapes that fall at random angles and initial positions, the game is not grid-based. This makes many of its aspects much more challenging to implement than would have been in a grid-based game. And because I wasn't using an existing game engine, I implemented all the math behind collision-detection, reflections, and ray propagation myself.


Gyrolighting

Designing the look of pentominoes (World 2) presented a challenge. It is practically impossible to give a shape volume without the help of light and shadows. And if there are shadows, there is lighting direction. And since a shape can be rotated at any angle, the shapes will have inconsistent lighting direction between each other. Although this is also a problem for the other two worlds, this is particularly problematic for pentominoes due to the fact they consist of square blocks. One solution would be to draw pentominoes programmatically which would allow me to give all the shapes on the screen consistent lighting regardless of their angle. However, I decided to take it a step further and tie lighting direction to gyroscope output.

If the game doesn't detect a gyroscope, it is programmed to use the output from accelerometers instead. This results in slightly less smooth animation and the lighting movement being reversed if the phone is held upside down. However, most of the time it is very difficult to tell the two methods apart.

Since I already integrated gyroscope/accelerometers output into the game and enable/disable it as needed, I decided to use it to give two backgrounds a parallax effect. When the user rotates the screen a bit, the background moves giving an illusion of depth. The two backgrounds are Cozy Room and Parallax.


Leaderboards & Achievements

Ray Breaker has integration with Google Games. Because the game's genre is arcade, it was important to implement a leaderboard and let players compete with each other for the highest score. Since the three worlds are substantially different, I gave each world a separate leaderboard.

The game also has achievements. The player is rewarded for reaching a certain turn count for the first time, for achieving a certain state in the game, such as 50 simultaneous reflections, and for investing substantial time in the game (e.g. destroy 1000 shapes in total). When designing achievement icons, I noticed that when an achievement is unlocked, the icon appears as a circle, so I made all achievement icons round. I also tried to give them a luxurious look, since they are rewards, and at the same time consistent with the theme of the game. I am particularly happy with how Lux Perpetua and Lux Aeterna achievements turned out.

achievement icons

Unlockable Content

Ray Breaker currently has 3 worlds, that let you play with completely different shapes, plus 14 backgrounds. Everything except the first world and the default background is unlocked through gameplay.

In the beginning I wanted to reward the player with unlocks for achieving certain milestones, mainly for surviving until a certain turn. But after some playtesting I changed my mind. My original thought process was that as players learn the game, they get better at it. As their highscores get better and better they gradually unlock content. In other words, players are directly rewarded for getting better at the game. But I soon learned that player's initial skill at the game can differ drastically and plays a much bigger role at determining their highscores than the learning curve. As a result, some players would unlock all the content in a matter of days, while other have would have no chance to ever experience it.

To address this, I changed the unlock system to something that had a much less direct relationship with player's skill. I introduced coins that have a certain chance to appear each turn. Each unlock has a certain price (worlds generally costing more than backgrounds) and players can spend the coins that they collected to unlock what they like.