Crossy Bunny is a recreation of the popular mobile game Crossy Road using OpenGL. The objective is to cross as many roads as possible without being hit by the moving vehicles.
The controls for Crossy Bunny are very simple:
Crossy Bunny is built using a basic scene graph. Each object on screen is a node in a tree, and objects are transformed relative to their parent in the tree. This makes reusing code much easier. For example, in game, the roads and the vehicles in them are contained in a reusable node. This way multiple instances can be created and positioned at different locations while changing nothing about the code or positioning of the cars driving on that road.
By themselves, nodes don't draw anything (just recursively draw their subnodes), so to get things on screen there is a subclass called ShapeNode that handles drawing of OBJ files. tinyobjloader is used to load OBJ files onto the GPU, including the materials and textures (loaded by SOIL) the designer may have used. This turned out to be somewhat complex since the OBJ format allows for a different material for each face. The Shape class uploads a single buffer containing the entire OBJ to the GPU, but tracks segments that have different materials so it can do an OpenGL drawElements call for each one after changing the material properties.
There are 4 different vehicle OBJ files used in the game, and the Road class handles rendering the actual road and the vehicles along the road. When the vehicles move off screen, they are removed from the scene graph, and new ones are added to the right side.
The Scene class represents the overall game scene, and manages a list of roads, removing them when they become invisible and adding new ones as needed. It also manages the camera, lights, character, and ground plane, and can move the character/camera around. There are 5 roads on screen at any given time, and as you forward, roads behind you are removed while new roads in front of you are added. This makes the game world go on forever.
Collision detection is handled by the node hierarchy as well. Leaf shape nodes compute their bounding boxes from all points in the OBJ, and these boxes are transformed by the model matrix. Collisions occur when two bounding boxes intersect.