Mercurial > fhrl
changeset 7:006f78dd763f
populate
| author | Radomir Dopieralski <sheep-devel@sheep.art.pl> |
|---|---|
| date | Tue, 12 Mar 2013 12:29:08 +0100 |
| parents | fc17045bef2f |
| children | 5c4c86502a2f |
| files | fhrl/__main__.py fhrl/rocks.png |
| diffstat | 2 files changed, 114 insertions(+), 49 deletions(-) [+] |
line wrap: on
line diff
--- a/fhrl/__main__.py Mon Mar 11 23:40:17 2013 +0100 +++ b/fhrl/__main__.py Tue Mar 12 12:29:08 2013 +0100 @@ -9,40 +9,61 @@ DX = [0, 1, 0, -1] DY = [-1, 0, 1, 0] - - -def load_image(filename): - f = StringIO.StringIO(pkgutil.get_data('fhrl', filename)) - return pygame.image.load(f, filename) +RES = None -def load_atlas(filename, width=32, height=None): - image = load_image(filename) - image_width, image_height = image.get_size() - w, h = width, height or width - return [ - image.subsurface((x * w, y * h, w, h)) - for y in xrange(0, image_height // h) - for x in xrange(0, image_width // w) - ] +class Resources(object): + def __init__(self): + self.walls = self.load_atlas('walls.png', 48, 32) + self.floor = self.load_atlas('rocks.png', 48, 32) + self.mobs = self.load_atlas('mobs2.png', 48, 48) + self.items = self.load_atlas('items.png', 48, 32) + + @staticmethod + def load_image(filename): + f = StringIO.StringIO(pkgutil.get_data('fhrl', filename)) + return pygame.image.load(f, filename) + + @classmethod + def load_atlas(cls, filename, width=32, height=None): + image = cls.load_image(filename) + image_width, image_height = image.get_size() + w, h = width, height or width + return [ + image.subsurface((x * w, y * h, w, h)) + for y in xrange(0, image_height // h) + for x in xrange(0, image_width // w) + ] class SortedUpdates(pygame.sprite.RenderUpdates): def sprites(self): - return sorted(self.spritedict.keys(), key=lambda s: s.rect.top) + return sorted(self.spritedict.keys(), key=lambda s: s.rect.bottom) class Level(object): - def __init__(self, (width, height)): + def __init__(self, (width, height), resources): + self.resources = resources self.width = width self.height = height self.grid = [ [1] * width for y in xrange(height) ] + self.generate() + self.populate() + + def generate(self): + for i in xrange(30): + x = random.randrange(1, self.width) + y = random.randrange(1, self.height) + for j in xrange(50): + x = max(1, min(self.width - 1, x + random.randrange(-1, 2))) + y = max(1, min(self.height - 1, y + random.randrange(-1, 2))) + self.grid[y][x] = 0 for i in xrange(200): x = random.randrange(1, self.width) y = random.randrange(1, self.height) - self.grid[y][x] = 0 + self.grid[y][x] = 1 for i in xrange(50, 200): x = random.randrange(2, self.width - 3) y = random.randrange(2, self.height - 3) @@ -54,20 +75,46 @@ self.rect(x-1, y-1, w+2, h+2, 1) self.rect(x+1, y+1, w-2, h-2, 1) if w > 2 and h > 2: - if random.choice((0, 1)): - dx = x + random.randrange(w - 2) + 1 + for i in xrange(random.randrange(1, 4)): if random.choice((0, 1)): - self.grid[y][dx] = 1 + dx = x + random.randrange(w - 2) + 1 + if random.choice((0, 1)): + self.grid[y][dx] = 2 + else: + self.grid[y + h - 1][dx] = 2 else: - self.grid[y + h - 1][dx] = 1 - else: - dy = y + random.randrange(h - 2) + 1 - if random.choice((0, 1)): - self.grid[dy][x] = 1 - else: - self.grid[dy][x + w - 1] = 1 + dy = y + random.randrange(h - 2) + 1 + if random.choice((0, 1)): + self.grid[dy][x] = 3 + else: + self.grid[dy][x + w - 1] = 3 + for i in xrange(200): + x = random.randrange(1, self.width) + y = random.randrange(1, self.height) + if self.grid[y][x] == 1: + self.grid[y][x] = 4 self.rect(0, 0, self.width, self.height, 0) + + def populate(self): + self.free = [ + (x, y) + for y, row in enumerate(self.grid) + for x, f in enumerate(row) + if f + ] + random.shuffle(self.free) + self.hero = Hero(self.resources.mobs[0], self.free.pop()) + self.monsters = [ + Mob(self.resources.mobs[1], self.free.pop()) + for i in xrange(20) + ] + self.items = [ + Item(self.resources.items[0], self.free.pop()) + for i in xrange(20) + ] + + def __iter__(self): return iter(self.grid) @@ -84,26 +131,38 @@ self.grid[sy + h - 1][x] = v return sx, sy, w, h - def render(self, surf, tiles): + def render(self, surf): + for y, row in enumerate(self.grid): + for x, f in enumerate(row): + surf.blit(self.resources.floor[f], (x * 48 - 24, y * 32)) nrows = iter(self.grid) nrows.next() for y, (row, nrow) in enumerate(zip(self.grid, nrows)): for x, ts in enumerate(zip(row, row[1:], nrow, nrow[1:])): surf.blit( - tiles[sum((not t) * 2**i for i, t in enumerate(ts))], + self.resources.walls[ + sum((not t) * 2**i for i, t in enumerate(ts)) + ], (x * 48, y * 32) ) +class Item(pygame.sprite.DirtySprite): + def __init__(self, image, (x, y)): + super(Item, self).__init__() + self.image = image + self.rect = self.image.get_rect() + self.rect.topleft = x * 48 - 24, y * 32 - 12 + self.x, self.y = x, y + class Mob(pygame.sprite.DirtySprite): def __init__(self, image, (x, y)): super(Mob, self).__init__() self.image = image self.rect = self.image.get_rect() - self.rect.topleft = x * 48 - 24, y * 32 - 32 + self.rect.topleft = x * 48 - 24, y * 32 - 33 self.x, self.y = x, y - def _walk_anim(self, d): for frame in xrange(8): self.rect.move_ip(DX[d] * 6, DY[d] * 4) @@ -146,30 +205,24 @@ self.width = 480 self.height = 480 self.margin = 64 - self.x = 0 - self.y = 0 + self.x, self.y = 0, 0 self.screen = pygame.display.set_mode((self.width, self.height)) self.clock = pygame.time.Clock() - self.walls = load_atlas('walls.png', 48, 32) - self.floor = load_atlas('rocks.png', 48, 32) - self.mobs = load_atlas('mobs2.png', 48, 48) - self.level = Level((32, 32)) - self.sprites = SortedUpdates() + self.resources = Resources() + self.level = Level((32, 32), self.resources) self.background = pygame.Surface( (self.level.width * 48 - 48, self.level.height * 32 - 32) ) - w, h = self.background.get_size() - for y in xrange(0, h, 32): - for x in xrange(0, w, 48): - self.background.blit(self.floor[0], (x, y)) - self.level.render(self.background, self.walls) - self.level.hero = Hero(self.mobs[0], (1, 1)) - self.level.monsters = [ - Mob(self.mobs[1], (2, 2)) - ] + self.level.render(self.background) + self.init_sprites() + + def init_sprites(self): + self.sprites = SortedUpdates() self.sprites.add(self.level.hero) for m in self.level.monsters: self.sprites.add(m) + for i in self.level.items: + self.sprites.add(i) def _scroll_anim(self, dx, dy): frame = 0 @@ -188,11 +241,17 @@ yield self.update_all() - def scroll_by(self, dx, dy): + def scroll_by(self, dx, dy, instant=False): w, h = self.background.get_size() dx = min(max(self.x, dx), self.x+w-self.width) dy = min(max(self.y, dy), self.y+h-self.height) - self.animations.append(self._scroll_anim(dx, dy)) + if instant: + self.x -= dx + self.y -= dy + for s in self.sprites: + s.rect.move_ip(-dx, -dy) + else: + self.animations.append(self._scroll_anim(dx, dy)) def _sprite_clear(self, screen, rect): source = rect.move(-self.x, -self.y) @@ -212,6 +271,11 @@ pygame.display.flip() def run(self): + self.scroll_by( + self.level.hero.x * 48 - self.width // 2, + self.level.hero.y * 32 - self.height // 2, + True + ) self.update_all() while True: self.animations = [] @@ -244,4 +308,5 @@ self.animations = cont self.update() +pygame.display.init() Game().run()
