Live demo available at http://damp-bastion-84920.herokuapp.com/
At the very start of the game, the player starts at level 1. Inactive neutral shapes will slowly drift down from the sky. These blocks can be activated by hitting them with force cubes, which are generated by either left-clicking or right clicking. A left-click creates a weak cube, and a right-click creates a strong cube. The cubes fire upwards, and are used to activate & juggle neutral shapes.
Knocking any two neutral shapes together will cause them to activate, and fall faster. If the two neutral shapes are the same color, they become positively charged. Positive shapes can be knocked into other neutral shapes of the same color to spread the positive charge. When positive shapes hit the ground, they give you points and restore missing health.
If the shapes are allowed to touch the ground, though, then health is lost and the shapes become negative instead, docking points. Just like positive shapes, if a neutral shape touches a negative shape, the neutral shape will become negative, too!
As you get more points, you'll level up. At first, there will only be one color to manage, but at every 10th level, a new color gets added. More colors to deal with means having to be more careful while trying to match colors!
This game was created as a personal project to teach myself about application states and state logic. I chose to create a game because games naturally have multiple states that the application could be in at any point in time. For example, each shape can have a total of 4 states: Neutral-Inactive, Neutral-Active, Positive, and Negative. This is important because the main control mechanic in the game is a collision function, which tells the game engine what to do by looking at the sources of the collision. For every collision that happens, the state of the source shapes has to be taken into account: for example, was the collision a positive + positive collision? Or was it a neutral + positive collision? Or could it have been a positive + ground collision? Thus, I had to rigorously test my application many times in order to ensure that every possible type of collision was taken into account. This app was an extremely rewarding project--not only did I learn a lot about application states and logic, I also got my first taste of game development.
The basic page layout was done in very sparse HTML/CSS. For the core physics engine, I chose MatterJS because it's extremely lightweight--it does exactly what I needed it to do, and not too much more. Although MatterJS has a built-in basic rendering engine, I instead chose to integrate it with pixi.js. This is because pixi.js has full WebGL support, which makes it hardware-accelerated (it runs faster). Finally, I used HowlerJS to handle the audio for the game, because Javascript's default audio function will only play one sound at a time, which would be problematic since collision-event audio would need to be played over the background music.