Now that my prototype is complete, I wanted to take some time and review the decisions I made. Since it's only a prototype, I'm not taking the lack of content into consideration. A future build would include more tilesets, enemies, and abilities. The prototype also lacks a menu, saving system, ending, and proper introduction.
This is how I learned to scale objects visually in the game. I wanted a dynamic screen that would adjust according to the size of the browser window so I started to tinker around. I realized it was easier to scale visually at the end, when drawing the objects on the screen, rather than scaling each calculation individually. I also found that the object designs I had in mind didn't allow for items or dynamic tiles that can break. To remedy this, I changed the container (array) originally intended for enemies into a container for any dynamic entity that can collide. I then added a method to every collidable entity that runs when the player collides with it. That way a power-up can respond differently than an enemy even though the same method name is called.
Gameplay with a smaller scale
I wanted to look for a better looping option to replace setInterval/setTimeout. The solution was to use requestAnimationFrame. There are a few things to consider when using requestAnimationFrame though. Unlike setTimeout/setInterval, you don't have control over the amount of time between each call. This is because requestAnimationFrame is set to run as close to 60 FPS as it can. If this is too fast, you can artificially slow it down within your own code. Another negative to requestAnimationFrame (that will disappear eventually) is the lack of browser support. It's still under development, so you need a prefix in front of it which depends on your browser. Not only that, some browsers have virtually no support for it. Chrome and Firefox adopted requestAnimationFrame fairly early, but Safari didn't until Safari 6.0. Internet Explorer was the same way and didn't have support until IE10. Opera still has no support to date.
Here is the code I used in order to avoid prefix discrepancies
Including audio was another hurdle when using audio tags. In this case, each browser supports different audio formats. I wanted to use Ogg Vorbis since it's open source, but IE and Safari don't support it. The solution was to add a second set of audio files that use the AAC format. AAC doesn't require a license or payment so I can avoid the chance of legal threats that using the MP3 format would allow.
In order to make the game more efficient, I made a couple changes to the code. An object is only drawn or updated if it's within a certain distance of the player.
Here is an example with the drawing/update distance reduced
The second change I made was to the map builder. Each map is contained within a 2-D array. Each position in this array contains a single letter that corresponds to a tile type. An "X" is a solid tile, an "A" is a background tile, a "Z" is a crumbling tile, and an "O" is the lack of a tile. The builder runs through each row and places a tile in the world according to the letter. Solid and background tiles automatically check their neighboring ones to decide which tile to display from the tileset. That way tiles with nothing above them have grass and cliffs have corners/edges. The change I mentioned was to move tiles in the center of groups to the background tile container. I did this because background tiles are simply displayed on the screen and have very little properties to them. No collision checks are made against these tiles, and since you can't collide with a tile in the center of a group, it avoids unnecessary calculations.
Here is an example with the background tiles hidden
Collision detection could use an overhaul as well. If an object was moving at a fast rate, it was possible for it to jump right over another object. What I mean by that is if a ground tile is ten pixels wide and the player was moving at twenty pixels per frame, the player could pass the ground tile without ever having overlapped. My solution was to add a cap to velocity, but that is fairly limiting to a game. A better solution would be to calculate movement of objects in smaller increments when they are within a certain distance. This can be implemented along with a collision grid that reduces the amount of objects you need to check against.
The idea from this point is to make these changes in the next iteration of the game. I knew about some of these issues when I started, but creating the prototype put a lot into perspective. I realize how important some of these changes actually are, and I can design around them. I also picked up a lot of smaller knowledge that I hadn't considered before, and this will factor into the redesigning. I wouldn't have learned any of this if I didn't get my hands dirty and create something.