BrIK Breaker is a project that expands the functionality of Assignment 4, which utilized objective functions to implement inverse kinematics (IK). Using paddles attached to chains of links, the player's goal is to knock a ball into several bricks laid throughout the screen.
The first key change to the code is that it now allows the links to be based in locations besides the origin while still properly performing the IK computations (this involved subtracting the offset of the base of a given chain's first link from the target position). Once this was accomplished, I implemented 5 of these chains, allowed only 1 to be active at a time, and allowed the player to swap between them using 'Q', 'W', 'A', 'S', and SPACE.
Attached to the end effector of every chain is a shape drawn using cube.obj. This was done by using the joint matrix computed at the last link to determine the position and rotation of the "paddles". The red bricks and gray walls were also drawn from cube.obj, so since there are multiple objects that should collide with the ball, I created a super class called "Barrier". In every call to render(), we check if the ball collides with any of the Barriers. How was this done?
The Ball object is essentially just a particle with a drawing using sphere.obj. Thanks to polymorphism, I could store pointers to every Paddle, Brick, and Wall in a public static list of Barrier pointers, which Ball can access. Barrier.h contains a glm::mat4 and a method getMatrix(), which are used to obtain the transformation matrix. Thus, the Ball uses the inverses of these matrices to transform into the Barriers' local spaces; this way, we are always checking the ball against a uniform 1x1 square centered at the origin). Then it checks if its current position lies within the boundaries of the Barrier; if so, then it simply negates its x or y direction (depending on which side of the cube it hit) and uses the Barrier's matrix to transform back out into world space.
Upon a collision with a Brick, the memory associated with that Brick is deallocated, and the pointer to it is removed from the static list of Barrier pointers. How do we know when all of the Bricks are gone? Well, each subclass of Barrier ALSO has its own static list. Brick.h contains a static list of pointers to every Brick instance, and upon collisions, the pointers are removed from both lists. Once the list of Brick pointers is empty, the game has been won!
If you take too long, you won't beat the best time, so try your best to get the highscore!