changeset 12:88cb0ac8e488

Randomly generate the level
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Mon, 27 Feb 2012 23:15:12 +0100
parents e7c684cfe063
children 7cab9923c732
files mhrok.png mhrok.py
diffstat 2 files changed, 93 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
Binary file mhrok.png has changed
--- a/mhrok.py	Sun Feb 26 16:40:41 2012 +0100
+++ b/mhrok.py	Mon Feb 27 23:15:12 2012 +0100
@@ -7,6 +7,7 @@
     import cStringIO as StringIO
 except ImportError:
     import StringIO
+import random
 
 import pygame
 from pygame import locals as pg
@@ -26,7 +27,7 @@
 
 class Mob(pygame.sprite.Sprite):
     animations = [[0]]
-    movements = [[(0, 0)]]
+    movements = [(0, 0)]
 
     def __init__(self, frames, (x, y)):
         super(Mob, self).__init__()
@@ -49,6 +50,7 @@
     animations = [
         [25, 26]
     ]
+    movements = [(0, 0), (0, 0)]
 
 
 class Chest(Mob):
@@ -96,6 +98,7 @@
 class Player(object):
     def control(self, level):
         mx, my = self.mob.rect.topleft
+        x, y = (mx+1)/20, (my+6)/12
         keys = pygame.key.get_pressed()
         if keys[pg.K_UP] and level[(mx - 4 + 5) / 20, (my + 6 - 3) / 12]:
             self.mob.animation = 2
@@ -118,33 +121,79 @@
 
 
 class Level(object):
-    def __init__(self, (width, height)):
+    def __init__(self):
         self.mobs = {}
-        self.width = width
-        self.height = height
+        self.width = 31
+        self.height = 38
+
+        self.map = [[0] * self.width for y in xrange(self.height)]
+
+
+        areas = [
+            ((0, 0), (9, 11)), ((11, 0), (9, 11)), ((22, 0), (9, 11)),
+            ((0, 13), (9, 11)), ((11, 13), (9, 11)), ((22, 13), (9, 11)),
+            ((0, 26), (9, 11)), ((11, 26), (9, 11)), ((22, 26), (9, 11)),
+        ]
+
+        rooms = []
+        r = random.randint
+        for (x, y), (w, h) in areas:
+            width = r(1, w/2) * 2
+            height = r(1, h/2) * 2
+            x_offset = r(0, (w - width)/2) * 2
+            y_offset = r(0, (h - height)/2) * 2
+            rooms.append(((x + x_offset, y + y_offset), (width, height)))
+
+        random.shuffle(rooms)
 
-        self.map = [[0] * width for y in xrange(height)]
-        for y in range(2, 10):
-            for x in range(2, 10):
-                self.map[y][x] = 1
-        self.map[2][1] = 2
-        self.map[1][1] = 2
-        self.map[0][0] = 2
-        self.map[0][1] = 2
-        self.map[5][5] = 3
-        self.map[6][7] = 4
-        self.map[-1][-1] = 1
+        for room, next_room in zip(rooms, rooms[1:]):
+            (x, y), (w, h) = room
+            (nx, ny), (nw, nh) = next_room
+            x1 = nx + r(0, nw/2) * 2
+            y1 = ny + r(0, nh/2) * 2
+            x2 = x + r(0, w/2) * 2
+            y2 = y + r(0, h/2) * 2
+            self.path((x1, y1), (x2, y2), 2)
+        for room in rooms:
+            (x, y), (w, h) = room
+            self.fill((x, y), (w + 1, h + 1), 1)
 
-        self.mobs[2, 3] = Bat
-        self.mobs[4, 2] = Chest
-        self.mobs[6, 3] = Skeleton
-        self.mobs[9, 7] = Teddybear
+        #self.map[2][1] = 2
+        #self.map[1][1] = 2
+        #self.map[0][0] = 2
+        #self.map[0][1] = 2
+        #self.map[5][5] = 3
+        #self.map[6][7] = 4
+        #self.map[-1][-1] = 1
+
+        #self.mobs[2, 3] = Bat
+        #self.mobs[4, 2] = Chest
+        #self.mobs[6, 3] = Skeleton
+        #self.mobs[9, 7] = Teddybear
 
     def __getitem__(self, (x, y)):
-        try:
+        if self.width > x >= 0 and self.height > y >= 0:
             return self.map[y][x]
-        except IndexError:
-            return None
+
+    def __setitem__(self, (x, y), value):
+        if self.width > x >= 0 and self.height > y >= 0:
+            self.map[y][x] = value
+
+    def fill(self, (sx, sy), (width, height), fill):
+        for y in xrange(sy, sy + height):
+            for x in xrange(sx, sx + width):
+                self[x, y] = fill
+
+    def path(self, (sx, sy), (ex, ey), fill):
+        for x in xrange(sx, ex, 1 if sx < ex else -1):
+            if self[x, sy]:
+                return
+            self[x, sy] = fill
+        for y in xrange(sy, ey, 1 if sy < ey else -1):
+            if self[ex, y]:
+                return
+            self[ex, y] = fill
+
 
     def render_background(self, tiles):
         background = pygame.Surface((self.width * 20 + 20, self.height * 12 + 20))
@@ -158,15 +207,6 @@
                 pos = x * 20 + 4, y * 12
                 if square == 1:
                     background.blit(tiles[23], pos)
-                elif square == 2:
-                    background.blit(tiles[33], pos)
-                elif square == 3:
-                    background.blit(tiles[23], pos)
-                    background.blit(blood, pos)
-                elif square == 4:
-                    background.blit(tiles[23], pos)
-                    background.blit(blood2, pos)
-                if square:
                     if not self[x - 1, y]:
                         background.blit(tiles[9], pos)
                     if not self[x + 1, y]:
@@ -175,6 +215,24 @@
                         background.blit(tiles[4], pos)
                     if not self[x, y + 1]:
                         background.blit(tiles[14], pos)
+                elif square == 2:
+                    background.blit(tiles[33], pos)
+                    if not self[x - 1, y]:
+                        background.blit(tiles[29], pos)
+                    if not self[x + 1, y]:
+                        background.blit(tiles[39], pos)
+                    if not self[x, y - 1]:
+                        background.blit(tiles[24], pos)
+                    if not self[x, y + 1]:
+                        background.blit(tiles[34], pos)
+                elif square == 3:
+                    background.blit(tiles[23], pos)
+                    background.blit(blood, pos)
+                elif square == 4:
+                    background.blit(tiles[23], pos)
+                    background.blit(blood2, pos)
+                elif square < 0:
+                    background.blit(tiles[39 - square], pos)
 
         return background
 
@@ -217,6 +275,8 @@
             self.shadows.draw(self.screen)
             dirty = self.sprites.draw(self.screen)
         pygame.display.update(dirty)
+
+    def update(self):
         self.sprites.update()
         self.shadows.update()
 
@@ -228,7 +288,7 @@
         self.game_over = False
 
         self.pc = Player()
-        self.level = Level((31, 38))
+        self.level = Level()
         self.display.render_level(self.level, self.pc)
 
     def main(self):
@@ -236,6 +296,7 @@
             self.pc.control(self.level)
             self.display.draw()
             self.clock.tick(15)
+            self.display.update()
             for event in pygame.event.get():
                 if event.type == pg.QUIT or (
                         event.type == pg.KEYDOWN and