Cloning Zelda, part 3A: Coordinated
Last time I said we'd be fixing the walk code so that Link can't walk through walls/water/etc anymore, and adding in the missing Armos statues to the map. I should've known that was a bit ambitious to tackle both in a single chunk, and indeed it was. So Part 3 will be split into two sections; this is the first.
The first thing I needed to figure out was how to restrict Link's movement on the map. I had a vague idea involving the map data's use of tile coordinates to the overworld tile image I used... I tried to keep all of the "walkable" tiles in that first column, but since I used decimal digits instead of hex digits to address the tiles, I was limited to a 10-tile column, which meant I would be leaving out the dock and stairs tiles if that was my only criteria. Nevertheless, I tried to keep all of the walkable tiles confined to a small space on the image, and figured I'd deal with it in the code.
The code side, in fact, turned out to be fairly straightforward: I added a new routine to the mapScreen class to report on whether a particular (x,y) space on the map screen is walkable. I called it, oddly enough, cellIsWalkable(). It was pretty straightforward... given the x,y coordinates to test, I first had to figure out the 16x16 cell containing those coordinates by dividing x and y each by 16. Once I knew the specific cell containing the target point, I could then check the tile it was using to see if it met "walkable" criteria. Here's the updated map.js file with the new function.
In the process of coding up this whole movement-restriction thing, I realized something else: the original game isn't strictly top-down. In a kind of a stab at a pseudo-isometric interface, Link can kind of "sidle up" to unwalkable cells from below, like so:
As you can see, it lends a bit of a sense of layering to the game, enhancing the illusion of a 3-dimensional playing field. I decided the best way to accomplish this overlap was to relocate the main y-position from the top of Link's head, to his middle. Then all "can I go up?" type requests are made from that center point--not from the top of his head--and the overlap works as it should.
Once I'd relocated Link's y-position, I decided to move his x-position to the sprite's center as well, to better handle movement restriction along the x-axis (I wanted to be able to block Link from walking into walls on both his sides, not just on the left). I then modified the cellIsWalkable() tests along the x-axis to account for an 8-pixel offset on either side, and the work was done (Refer to the image at the top of this entry to see how the axis relocation was done). Or, refer to the modified player.js file for more details of how it all fits together.
I'll get to monsters in the next entry.