Passages: Flash Version
The original flash version of Passages.
This was my original intention for a horror game called Passages. However, my brother suggested that the game would be much scarier if it was 3-dimensional. So I scrapped this version and began a version in Unity. Currently that version is on hold until I have better resources, mostly with graphics and 3d programming.
I'm a bit saddened to throw this out, because a lot of work went into this. The trickiest part was creating a system for the player's line of sight, which was necessary to mask out everything the player could not see, and thus achieve a scarier feeling
This was an incredibly daunting task for me as an amateur programmer, but here's the logic that went into it.
The player's line of sight resembles a triangle, which casts an infinite number of rays sweeping across a small arc. It is not necessary to trace each individual ray, because the rays conform to any obstacle within the player's vision. Therefore, only certain critical points are necessary to determine the player's line of sight:
- The closest collision between the outermost edge of the player's line of sight and an object.
- Any vertex within the angle of the player's line of sight that is not obstructed by another object.
- The closest collision between the ray cast from the player in the direction of a vertex mentioned above.
So now that I had all the critical points, I needed a way to fit them together in order to simulate the player's line of sight.
I decided to use Flash's lineTo() function to draw the line of sight, starting from the player, sweeping around, and back to the player. To do this I needed to order the critical point in a clockwise direction. However, I ran into a problem: When a ray is cast toward a vertex (type 2) to find the next point on (type 3), the points have the same rotation in relation to the player, so the program would have no way of knowing which to draw to first.
I solved this by casting two rays, an infinitely small rotation from the vertex in either direction, that way the rotation would vary slightly, allowing the correct order and allowing the program to locate the next point no matter which side it was on.
Now the points could be ordered and the line of sight drawn correctly. This clip was then used to mask the rest of the stage.
Even more challenging was actually creating the engine for the passages themselves. The primary characteristic of the passages was that they had to be able to fluxuate in size while still being usable with the line of sight algorithm.
My original thought was just to use rectangles which would fluctuate on their own, but that made corners impossible.
For corners, a vertex had to be able to be manipulated by more than one passage object, one controlling its y coordinate, and the other its x. So I created a centralized array which stored all of the vertices in a level. Each vertex object contained coordinates and a point called "link", which defined which passage would control the x value and which one would control the y value.
Each passage object contained the passsage's inital position and scale, the texture of the passage floor, an array of the associated vertices, the passages connected to it, and whether or not it is currently locked.
Most important here are the vertices and connected passages. A centralized engine would cycle through the player's current passage and each adjacent passage, setting the vertex's position to it's initial position relative to the passage multiplied by a centralized fluxuation value. The engine does not do this to every passage at once because doing so would slow down the engine substantially.
The engine also requires that each edge be known, so I numbered each vertex heading clockwise around the entire level (like a giant connect the dots). An edge is anywhere two vertices are one number off of each other, and in between the first and last vertices.
With that, the passages could finally be used with the line of sight algorithim.
Collision was fairly simple. As each passage was a rectangle, I simply had to check whether the player was inside the bounds, and if not, move him inside.
© 2013 aRobeGames