Screen transitions, legend of zelda gbc games

So, a favorite set of games of mine has always been the legend of zelda GBC games (link’s awakening, oracle of seasons, oracle of ages – yes, LA was on the Game boy originally but they’re similar in gameplay mechanics/graphics)

Image

The game uses 16×16 tiles, and every room is 10 by 8 tiles. Pretty amazing if you ask me. Dungeons and the map are laid out in a grid of these 10×8 tile rooms. It’s quite elegant how they did this and managed to well, make it work on something so tiny. I’m pretty impressed!

I was interested in using a similar type of map system in my next game, and got thinking about what it would take to do in Flixel. Quite a fun problem to think about. Let’s see. These are my initial thoughts and attacks at the problem, maybe you’ll learn something too.

Requirements:

-Touching the edges of a map must push you a tile forward, but move the camera view an entire screen in the direction of travel.

-Enemies and events need to be able to be triggered. Unlocked doors must stay open, bosses defeated stay dead, etc. That is, each screen must be able to maintain state for some period of time

-Enemies/bullets can’t travel from one screen to the next.

Tackling this problem one step at a time:

1. Making the map appear. Using tilesets, just draw this in a map editor. For simplicity let’s say I’m going to use one tileset for my map tiles. Then I export this gigantic map as a CSV (comma separated values – like “1,2,3,4,4,4,4”) , which with a quick calculation probably wouldn’t be more than a couple hundred KB (assuming I have over 100 tiles, my screens are 8×10 tiles, and I have like a 1000 screens, which is probably overcounting by a bit). Not a memory problem, in any case. We can pick which of the tiles we want to assign certain properties. E.g., some tiles act as holes, some as spikes that do damage – we can either replace these tiles with sprites at draw-time, change their properties to be one way, etc.

A few caveats with this. Drawing the whole map is obviously a horrible idea, we don’t want to have to deal with that being redrawn constantly, and in any case it’s just inefficient. So, we’ll want to only show one part at a time, and maybe have neighboring grids in memory for easy drawing, which leads to

2. Traversing the map.

Ahead of time, we know that our screens can be represented as a grid of points – you might start at screen (4,2). Now, luckily, our screens are equal sized *and* grids! So, it’s just a matter of some array index trickery and we can pull out grid-sized chunks from our whole-map CSV. We might have small 80-member CSVs (10×8) of mappings to tiles, one for the current screen, and one for up, down, left, and right (if they exist). So, we’d create tilemaps out of these CSVs and have them drawn.  When we want to move screens, we just push our character a tile forward, and move the camera an entire screen in whatever direction. Watch a video of zelda to see how this works. It visually works quite well and you can’t really tell that your character has moved completely across the screen!

Once you’re in the new map, of course you will trash those other tilemaps from memory, and find your new neighbor tilemaps, and load those into memory.

It’s kind of like your traversing a building, but you only really can see parts at a time and process that visually. If we had to process every thing in the building at once, even though we’re not there, that would be tiring!

3. Dealing with sprite generation.

In a screen , we’ll have enemies, one-way doors, locked doors, NPCs, etc. I’m not sure 100% how I want to do this. I could create a tilemap that maps tiles to certain enemies. That is how I did pills/notes/doors/entrances in my previous game. That might be annoying on my end because I would have to hand-code this mapping. But it wouldn’t be TOO annoying. However, I would end up with an enemy/sprite whatever CSV map the same size as my map-map. The other idea is exporting data to XML and parsing that instead, but maybe that would take up more space in the XML file. Not something to worry too much over, though. In some way, there will be a way to map sprites to tiles, etc.

4.  But what if we unlock a door? NOW WHAT? OR KILL A BOSS?

There’s a few ways to go about it. My favorite at the moment would be to store a dictionary into the save file for our “state” – it would have two keys, an “area’ and “subarea” key. E.g., “Dungeon 1, screen (2,3)”. With in it is just an array of objects. When you enter a screen, this array is generated from anything that holds state – a boss that may be alive at first, but dead forever later, a teleporter that is activated only past a certain event in the game. The state of tehse objects is saved as necessary, so if the boss is dead then I’d leave some data in my array saying that the boss should be dead.
How will this be made to work? Well, there are different kinds of sprites. There are sprites that don’t really have state – say a turnstile object, or a one way door. These things are *Always* where they are on the map, no matter what! Thus we don’t label them as stateful. A boss, on the other hand, will be “stateful” – is it dead? or alive?

So, we just take our array of numbers that maps to certain sprites. I’ll have to hard code whether a sprite is stateful, but if it’s not, we stick it on the screen. Otherwise, we look into our saved data for the specific screen’s  “state”. If it doesn’t exist, this means we have visited the screen for the first time, and so everything should have  default behavior ( a door should be locked, the boss should be there, etc.) If the entry in our large dictionary IS there, we use the state that we stored (maybe one door is open, a wall is broken,…)

This very well might be what I go with, it seems like it would work quite nicely. I shouldn’t need to store more than a few things per screen, anyways, so storage shouldn’t be an issue.
5. Enemies shouldn’t be able to move between screens! Or maybe they should for scary effects!

Not too hard. Just set bounds on where it can move based on what screen it spawns on. Maybe set “max/min x/y” value when you create the enemy object ,and don’t let it move outside. Likewise with bullets!

—–

So that lets us create dungeons, bosses, and some basic state. There is, of course, the question of how to handle global state (what dungeons are open? What events have I triggered? Etc), but that comes more into play with the actual game, I’d say.

An elegant way of handling events would be what to think about next, I think…

 

annnnd it kind of works, screen moving. I have a LOT to think about still, though,.

Advertisements

4 Comments on “Screen transitions, legend of zelda gbc games”

  1. Ben Reynolds says:

    Great discussion! I love the classic Zelda games as well, and it’s cool to see how you’ve handled some of the game mechanics — I’ve been planning to make a similar game sometime in the future.

    • seagaia says:

      Thanks! There’s a lot of other interesting challenges with zelda elements as well. I’m surprised I never realized this while playing those GBC zeldas, until now. I have even more respect for the developers of those games now.

  2. I have been scouring the Web to find out how to recreate Pitfall (from Atari 2600) in AS3. The concept of changing screens was the same there (except in Legend of Zelda the screen transitions / scrolls, or is it the player that scrolls?) Pitfall had 256 “screens” to the left and right. Zelda was 4-way directional. My question is how to easily store and access enemy and other sprite objects when switching screens, w/o having to create an array that has 256 elements and add sprites to each an every one of those screens! I would prefer that my enemies and sprites be deterministic, not randomly generated, which could be alot of work.

    Here is a layout of Pitfall in all its glory: http://pitfallharry.tripod.com/MapRoom/PitfallMap.html

    Any ideas?

    • seagaia says:

      Hey, I would suggest using a level editor to create your levels and then store it in some data serialization format that can be embedded into your game (JSON, XML, or YAML work, or if simple enough, just a CSV). You can use this to generate an array of 256 objects, one for each screen, each which contains data of what should be on the screen and where.

      So in your editor, say you put a pit in screen 2. This exports in some text format, which you parse in-game, and then dynamically create the pit when on screen 2 and place it there – then when you leave the screen, just remove the pit from memory.

      I have a few other posts floating around the blog on how I stored enemy data in Anodyne.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s