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()
Binary file fhrl/rocks.png has changed