Mercurial > mamba
comparison mamba/level.py @ 561:9afaa1969d6f
Level format 2 support
* * *
Allow for blank author
* * *
Fix thinko in write code
author | Neil Muller <drnlmuller@gmail.com> |
---|---|
date | Tue, 18 Oct 2011 11:41:28 +0200 |
parents | 6c61d5862310 |
children | 2d3dee657638 |
comparison
equal
deleted
inserted
replaced
560:a85993b00fd7 | 561:9afaa1969d6f |
---|---|
4 | 4 |
5 import pygame | 5 import pygame |
6 from pygame.surface import Surface | 6 from pygame.surface import Surface |
7 from pygame.sprite import RenderUpdates | 7 from pygame.sprite import RenderUpdates |
8 | 8 |
9 from mamba.constants import UP, DOWN, LEFT, RIGHT | 9 from mamba.constants import UP, DOWN, LEFT, RIGHT, VERSION |
10 from mamba.data import load_file | 10 from mamba.data import load_file |
11 from mamba import sprites | 11 from mamba import sprites |
12 | 12 |
13 from StringIO import StringIO | 13 from StringIO import StringIO |
14 | 14 |
91 class Level(object): | 91 class Level(object): |
92 def __init__(self, level_name, level_namespace, source=None): | 92 def __init__(self, level_name, level_namespace, source=None): |
93 self.level_name = level_name | 93 self.level_name = level_name |
94 self.level_namespace = level_namespace | 94 self.level_namespace = level_namespace |
95 self.source = source | 95 self.source = source |
96 self.author = '' | |
96 self.load_level_data() | 97 self.load_level_data() |
98 | |
99 def load_format_1(self, level_data): | |
100 """Load the original map format""" | |
101 self.name = level_data[0].strip() | |
102 tileset_name = level_data[1].strip() | |
103 self.tileset = Tileset(tileset_name) | |
104 self.background_track = level_data[2].strip() | |
105 tiles_ascii = [line.strip() for line in level_data[3:]] | |
106 try: | |
107 end = tiles_ascii.index("end") | |
108 except ValueError: | |
109 raise InvalidMapError('Missing "end" marker in level') | |
110 sprites_ascii = tiles_ascii[end + 1:] | |
111 tiles_ascii = tiles_ascii[:end] | |
112 self.tiles_ascii = tiles_ascii | |
113 self.sprites_ascii = sprites_ascii | |
114 | |
115 def load_format_2(self, level_data): | |
116 """Load the second mamba map format""" | |
117 try: | |
118 self.name = level_data[1].split('Name:', 1)[1].strip() | |
119 tileset_name = level_data[3].split('Tileset:', 1)[1].strip() | |
120 self.background_track = level_data[4].split('Music:', 1)[1].strip() | |
121 except IndexError: | |
122 raise InvalidMapError('Incorrectly formatted map header') | |
123 try: | |
124 # Missing author isn't fatal | |
125 self.author = level_data[2].split('Author:', 1)[1].strip() | |
126 except IndexError: | |
127 self.author = '' | |
128 self.tileset = Tileset(tileset_name) | |
129 tiles_ascii = [line.strip() for line in level_data[5:]] | |
130 try: | |
131 end = tiles_ascii.index("end") | |
132 except ValueError: | |
133 raise InvalidMapError('Missing "end" marker in level') | |
134 sprites_ascii = tiles_ascii[end + 1:] | |
135 tiles_ascii = tiles_ascii[:end] | |
136 self.tiles_ascii = tiles_ascii | |
137 self.sprites_ascii = sprites_ascii | |
138 | |
139 def check_format(self, level_data): | |
140 """Determine which format to load""" | |
141 if (level_data[0].startswith('Version: ') and | |
142 level_data[3].startswith('Tileset: ')): | |
143 # Looks like a version 2 level file | |
144 file_version = level_data[0].split('Version: ', 1)[1].strip() | |
145 try: | |
146 file_version = tuple([int(x) for x in file_version.split('.')]) | |
147 # We only compare on the first two elements, so point | |
148 # rleases work as expected | |
149 if file_version[:2] <= VERSION: | |
150 return 2 | |
151 else: | |
152 raise InvalidMapError("Unsupported map version") | |
153 except ValueError: | |
154 raise InvalidMapError("Unrecognised map version") | |
155 else: | |
156 # We assume anything we don't recognise is format 0 and rely on the | |
157 # error checking there to save us if we're wrong. | |
158 return 1 | |
97 | 159 |
98 def load_level_data(self): | 160 def load_level_data(self): |
99 """ | 161 """ |
100 This file format is potentially yucky. | 162 This file format is potentially yucky. |
101 """ | 163 """ |
102 if self.source is not None: | 164 if self.source is not None: |
103 level_data = StringIO(self.source) | 165 level_data = StringIO(self.source) |
104 else: | 166 else: |
105 level_data = load_file('levels/%s.txt' % (self.level_name,)) | 167 level_data = load_file('levels/%s.txt' % (self.level_name,)) |
106 self.name = level_data.readline().strip() | 168 # XXX: Should we have some size restriction here? |
107 tileset_name = level_data.readline().strip() | 169 level_data = level_data.readlines() |
108 self.tileset = Tileset(tileset_name) | 170 level_format = self.check_format(level_data) |
109 self.background_track = level_data.readline().strip() | 171 if level_format == 2: |
110 tiles_ascii = [line.strip() for line in level_data.readlines()] | 172 self.load_format_2(level_data) |
111 try: | 173 elif level_format == 1: |
112 end = tiles_ascii.index("end") | 174 self.load_format_1(level_data) |
113 except ValueError: | 175 else: |
114 raise InvalidMapError('Missing "end" marker in level') | 176 # generic fallback |
115 sprites_ascii = tiles_ascii[end + 1:] | 177 raise InvalidMapError("Unrecognised map version") |
116 tiles_ascii = tiles_ascii[:end] | 178 self.setup_level(self.tiles_ascii, self.sprites_ascii) |
117 self.tiles_ascii = tiles_ascii | |
118 self.sprites_ascii = sprites_ascii | |
119 self.setup_level(tiles_ascii, sprites_ascii) | |
120 self.make_background() | 179 self.make_background() |
121 | 180 |
122 def validate_level(self): | 181 def validate_level(self): |
123 old_tiles_ascii = self.tiles_ascii[:] | 182 old_tiles_ascii = self.tiles_ascii[:] |
124 old_tiles = self.tiles[:] | 183 old_tiles = self.tiles[:] |
134 if save_file is None: | 193 if save_file is None: |
135 if level_dir is None: | 194 if level_dir is None: |
136 level_dir = 'levels' | 195 level_dir = 'levels' |
137 file_path = '%s/%s.txt' % (level_dir, self.level_name) | 196 file_path = '%s/%s.txt' % (level_dir, self.level_name) |
138 save_file = load_file(file_path, 'wb', is_user_dir=is_user_dir) | 197 save_file = load_file(file_path, 'wb', is_user_dir=is_user_dir) |
139 save_file.write('%s\n' % self.name) | 198 save_file.write('Version: %d.%d\n' % VERSION[:2]) |
140 save_file.write('%s\n' % self.tileset.name) | 199 save_file.write('Name: %s\n' % self.name) |
141 save_file.write('%s\n' % self.background_track) | 200 save_file.write('Author: %s\n' % self.author) |
201 save_file.write('Tileset: %s\n' % self.tileset.name) | |
202 save_file.write('Music: %s\n' % self.background_track) | |
142 self.update_tiles_ascii() | 203 self.update_tiles_ascii() |
143 for tile_row in self.tiles_ascii: | 204 for tile_row in self.tiles_ascii: |
144 save_file.write('%s\n' % tile_row) | 205 save_file.write('%s\n' % tile_row) |
145 save_file.write('end\n') | 206 save_file.write('end\n') |
146 for sprite_ascii in self.sprites_ascii: | 207 for sprite_ascii in self.sprites_ascii: |