Zelda-Clone

Intro
This is a clone of the original NES The Legend of Zelda and was built during one semester by a team of five students at OSU, myself included. The game was built on MonoGame and C# from the ground-up, and was used as a learning tool to mature our software development skills.
This page will be highlighting interesting game features along with
snippets of
<code>
.
You can find the source code on GitHub and compile the game yourself with Visual Studio.
Ray casting
During the final week of the project, we were given the option to implement any interesting "stretch-goal" features. I discovered the concept of Ray casting and challenged myself to implement a ray casting lighting system.
In simple terms, ray casting is a rendering technique where lines are traced outward from a source point until they intersect with something. For my lighting system, Link is the source point, and the light rays stop wherever they first intersect with the environment (i.e. walls, blocks).
You can play around with the demo below to get an idea of how raycasting works. Just grab and drag around the "light source" with your mouse.
A fixed number of rays are drawn radially from the center. This is fine for learning, but it doesn't provide enough detail to be a convincing light source. Sometimes the rays don't make it into every nook and cranny that a real light would.
So, you might think: "Just increase the number of rays to get more detail." And this does work pretty well:
But it's STILL not good enough, because depending on how complicated the environment is, we may have to generate a huge number of rays in order to get lucky and fill every little crack.
But we can be clever and use a trick! We can cast a ray from Link to every "corner" in the environment. This will guarantee we hit everything that should be lit, and we don't have to use an arbitrarily large number of rays to do it.

Ta-da! But it kinda looks like trash! If we fill in the gaps between rays, and use
some custom shader magic, we can generate a transparency layer to draw
over top of the game.
Ta-da! It's magic... err... not really, just some engineering!
Portals
I got ambitious during that final week of the project and decided to do a second stretch-goal: portals! One of my all-time favorite game series is Portal, which is a must-play puzzle game if you enjoy mixing critical thinking into your gaming.
Implementing this feature wasn't very technically challenging, but the fact that I shipped it in the last couple days before the deadline is a testament to the extensibility of our codebase. Much effort went into writing software that was as maintainable as possible.
If you have never played Portal, there are special tiles that you can shoot with your Handheld Portal Device to place blue and orange portals. Once both colors are placed, anything that goes into one comes out the other, or, as stated in the game, "Speedy thing goes in, speedy thing comes out".
This simple portal mechanic instantly lends to tons of new puzzles. For instance, crossing a gap you otherwise couldn't...

...shooting objects where you can't reach...

...retreiving inaccessible items...

...or even creating unintentional Emergent Gameplay.

Collision Handler
When two objects collide -- like a boomerang into a wall -- something needs to take care of the event! Or else the boomerange would just fly straight through the wall. That's the Collision Handler's job: to take care of things when objects hit each other.

Below is the main loop for the Collision Handler system. I really just wanted to show off the snippet of code. I am proud of how simple it is. I employed the Command Pattern to make this system robust, modular, and readable!

The Collision Handler simply iterates over a list of collisions, where each collision contains two colliding objects. Then the Handler simply looks up the types of the objects in a dictionary (in constant time) and executes the command that knows how to handle the collision!
The advantage is that each command only knows how to handle collisions for a particular pair of object types, making each command very simple (~30 lines of code). This makes debugging and maintaining the codebase a piece of cake. Adding a new type of object to the game only requires updating the dictionary with a couple new commands. The Collision Handler itself doesn't need to be touched!