Courtyard Escape

By Robert Liu

Game Description

Player 1

You heard some weird scuffling sounds and saw some movement in your courtyard.. it seems whatever you're trying to catch is not visible to the naked eye. There's a key somewhere in this courtyard that can be used to get out. Catch the culprit before it escapes!

Player 2

It seems this planet isn't uninhabited after all. Our species just can't see the natives. You have been chased into an enclosure and there is a key somewhere within this large courtyard to access a secret exit. Find this key and get to the door before you get caught!

The key that's hidden somewhere in the garden. Step on it to acquire it.

The hidden door the key opens. Only look for the door after you find the key!

Game Rules:

The screen displays only one person's point of view at a time. The camera will switch upon pressing 'c', which by game rules happens every 3 seconds. Players - watch the what the other player sees to figure out where he is!


Player 1:

Forward: W

Back: S

Left Strafe: A

Right Strafe: D

Camera Movement: Mouse

Player 2:

Forward: Up Arrow

Back: Down Arrow

Left Strafe: Left Arrow

Right Strafe: Right Arrow

Camera Movement: Mouse


This project includes basic collision detection, mutiple camera implementation, camera constraints, fog, and texture mapping.

Graphics Technologies Implemented:

Collision Detection

After much research, I decided to forego the algorithms I found online as they sometimes implemented functions I didn't have access to. Instead I initially created an algorithm of O(n) complexity in which for any given point, 8 spaces needed to be checked for constraints. It would use a 3D array array[x][z][8]. The third dimension would handle each of the 8 possible spaces around the current space. This proved unecessary as I simplified the algorithm down to simply using a 2D array, in which the move functions would first calculate a new point and check if it was valid, if not it would discard the new point and simply keep the old value. This proved to be the quickest and easiest implementation of 2D spatial collision detection I could come up with. To expand on this algorithm, I could include 3D collision which would just implement two more values for y-directional movement. I could also implement logic to check for the availability of boxes diagonal to the current box so that when I walk diagonally into a wall, I won't walk through it, but I will walk along it in the direction of the diagonal.

Grid is upshifted to account for 3D viewing angle. The bench would take up every grid outlined in the photo.

Object sizes for Collision

In order to find the boundaries of each object, I needed to first know the size of each object after I scaled them to the size I wanted them to be. Unfortunately when I first implement the mesh model, all I need to specify is a position, and the object takes up space around that specific location according to the obj file. In order to measure each object, I enlarged my key object and placed them at intervals through each object so I could measure the approximate size of the objects in the world.

This bench is 10 units wide.


In order to have two players, I had to create two cameras. To do this, it was a matter of creating another set of variables necessary for view matrix computation and varying said values according to player 2 inputs instead of player 1. Additionally, to keep the camera from going crazy while trying to remove flying/digging, I found that the look at point needed to be constrained as well in order to have seamless grounded camera control.


I decided to implement fog because I did not like to see objects suddenly cut off in the world infront of me. In order to do this, I used an equation that let me control how far back the fog starts coming in, and how dense the fog was. This let me tweak my values until I found the sweet spot where the fog wasn't ridiculously dense, but still thick enough to mask the culling. Plus it helped create the creepy/tense atmosphere I was looking for. The vertex shader calculated the final "visibility" value which then was used by the fragment shader to blend with the pixels in question. There were two ways to implement the fog - linear or exponential. Exponential was chosen for a more realistic effect. Refer to Relevant Resources section at the bottom of the page for fog equation reference.

This is the world without fog.

Notice the fountain disappearing on the bottom right?(circled in red)

Now the fountain is all gone and the Jesus statue is disappearing!

With high density the fog even interferes with object colors right infront of the camera.

With low density there's virtually no fog.

With high gradient the fog is closer to us.

With low gradient the fog is pushed further back and we can see further.

With fog set just right, the disappearing images are just well enough hidden while maintaining sufficient visibility!


One interesting challenge was to put a skybox in with my fog already in place. This would have made my world a lot more impressive as the skybox helps provide the illusion of depth in the background. However, I couldn't get the skybox to work, so instead, to still maintain that "depth" in the sky, I decided to at least include a white sphere model as a moon. My initial problem was that the moon, after walking a certain distance away, would disappear due to culling. At this point, I had already created most of my world, so I was not going to resize my entire map to include the moon. I tried moving the moon closer so that it would never be out of sight within the boundaries of the map, but the moon was so close to the map that it looked more like a ceiling light than something thousands of miles away from Earth. So instead, I decided to make the moon's position variable according to the camera position. This way, the moon would look as it does in real life - never any closer or further away no matter where we stand because the distance we move is so negligible compared to our distance from the moon.

At first, the moon seems okay. It appears to be close enough to be a ceiling light when we strafe around... because it is.

Once we move far away enough, the moon will start to be cut off. It's a smaller circle because we're slicing through the original sphere of the moon.

If we move far away enough, the moon will stop rendering completely. Where's that light coming from? :O

This is the moon in its fixed position, as it should be. Our 3 steps closer to the moon is too small of a distance change relative to our distance from the moon, so the moon appears to have not gotten any closer.

Youtube Demo Video

Relevant Resources

Links to object file sources, file type convertors and online decompressor:

Object files are here, here, and here.

Object file convertor is here.

Image file convertor(for textures - .bmp) through here.

Decompressor(.rar, etc.) is here.

Youtube Link to Fog Video through here.