I'm working on a roguelike using Objective-C/Cocoa to learn more. I've gotten most of the basic functionality out of the way, but I still have one problem I've been trying to figure out.
Here's a breakdown of the process:
First, the map is loaded:
NSString* mapPath = [[NSBundle mainBundle] pathForResource:mapFileName ofType:mapFileType];
NSURL* mapURL = [NSURL fileURLWithPath: mapPath];
currentMap_ = [[Map alloc] initWithContentsOfURL: mapURL];
worldArray = [[NSMutableArray alloc] init];
itemArray = [[NSMutableArray alloc] init];
[self populateMap];
return;
Then, in the populateMap function, it goes through each cell of the loaded map, using NSPoints and a loop, and creates objects based on the data from the map in WorldArray. For items, normal floor is put in where the item is, and an item is then made in itemArray. Both arrays are 30x30, as determined by the height of the map.
Here is the populateMap code:
- (void)populateMap
{
NSPoint location;
for ( location.y = 0; location.y < [currentMap_ height]; location.y++ )
{
for ( location.x = 0; location.x < [currentMap_ width]; location.x++ )
{
char mapData = [currentMap_ dataAtLocation: location];
for ( GameObject *thisObject in worldDictionary )
{
//NSLog(@"char: <%c>", [thisObject single]);
if ( mapData == [thisObject single])
{
NSString* world = [thisObject className];
//NSLog(@"(%@) object created",thisObject);
[self spawnObject:world atLocation:location];
}
}
for ( Item *thisObject in itemDictionary )
{
//NSLog(@"char: <%c>", [thisObject single]);
if ( mapData == [thisObject single] )
{
NSString* item = [thisObject className];
NSString* floor = [NormalFloor className];
//NSLog(@"(%@) object created",thisObject);
[self spawnItem:item atLocation:location];
[self spawnObject:floor atLocation:location];
}
}
if ( mapData == '1'
&& [player_ stepsTaken] <= 0)
{
//NSLog(@"player spawned at (%f, %f)",location.x,location.y);
player_ = [[Player alloc] initAtLocation: location];
}
if ( mapData == '1' )
{
//NSLog(@"floor created at (%f, %f)",location.x,location.y);
[worldArray addObject:[[NormalFloor alloc] initAtLocation: location]];
}
}
}
[self setNeedsDisplay:YES];
}
This is what is called when things are spawned:
- (void)spawnObject: (NSString*) object atLocation: (NSPoint) location
{
//NSLog(@"(%@) object created",thisObject);
[worldArray addObject:[[NSClassFromString(object) alloc] initAtLocation: location]];
}
- (void)spawnItem: (NSString*) item atLocation: (NSPoint) location
{
//NSLog(@"(%@) object created",thisObject);
[itemArray addObject:[[NSClassFromString(item) alloc] initAtLocation: location]];
}
worldArray and itemArray are what the game works on from that moment onwards, including the drawing. The player is inside of worldArray as well. I'm considering splitting the player into another array of characterArray, to make it easier when I add things like monsters in the not so distant future.
Now, when I load a new level, I had first considered methods like saving them to data and loading them later, or some sort of savestate function. Then I came to the realization that I would need to be able to get to everything at the same time, because things can still happen outside of the player's current scope, including being chased by monsters for multiple floors, and random teleports. So basically, I need to figure out a good way to store worldArray and itemArray in a way that I will be able to have levels of them, starting from 0 and going onward. I do need a savestate function, but there's no point touching that until I have this done, as you shouldn't actually be allowed to save your game in roguelikes.
So to reiterate, I need to have one set of these arrays per level, and I need to store them in a way that is easy for me to use. A system of numbers going from 0-upward are fine, but if I could use something more descriptive like a map name, that would be much better in the long run.
I've figured out my problem, I'm using an NSMutableDictionary for each and storing them with the keys that correspond to each level. Works like a charm. Bigger problems elsewhere now.