changeset 23:24ae69443e4b

Fix memory in fog of war, make the light radius bigger
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Tue, 06 Mar 2012 22:05:45 +0100
parents 22e298d6cbd4
children 039121bf8148
files mhrok.py
diffstat 1 files changed, 40 insertions(+), 18 deletions(-) [+]
line wrap: on
line diff
--- a/mhrok.py	Fri Mar 02 23:38:20 2012 +0100
+++ b/mhrok.py	Tue Mar 06 22:05:45 2012 +0100
@@ -24,6 +24,25 @@
     def update(self):
         self.rect.center = self.owner.rect.center
 
+class Vision(pygame.sprite.DirtySprite):
+    def __init__(self, owner, level):
+        super(Vision, self).__init__()
+        self.owner = owner
+        self.level = level
+        self.image = pygame.Surface((120, 90), pg.SRCALPHA)
+        self.rect = self.image.get_rect()
+        self.image.fill((255, 255, 255, 255))
+        for r in xrange(45, 19, -1):
+            pygame.draw.ellipse(
+                    self.image,
+                    (255, 255, 255, min(255, (r-19) * 10)),
+                    (60-r*5/4, 45-r, 2*r*5/4, 2*r), 0)
+        self.blendmode = pg.BLEND_RGBA_MIN
+        self.dirty = 2
+
+    def update(self):
+        self.rect.center = self.owner.rect.center
+
 
 class Mob(pygame.sprite.Sprite):
     animations = [[0]]
@@ -262,7 +281,7 @@
         mob = self.pc.make_mob(tiles)
         sprites.add(mob)
         shadows.add(Shadow(tiles, mob))
-        return sprites, shadows
+        return sprites, shadows, mob
 
 
 class Display(object):
@@ -275,40 +294,44 @@
         self.background = pygame.Surface(self.screen.get_size())
         self.fog = pygame.Surface(self.screen.get_size(), pg.SRCALPHA)
         self.fog.fill((0, 0, 0, 255))
-        self.fov = pygame.Surface((80, 64), pg.SRCALPHA)
-        self.fov.fill((0, 0, 0, 255))
-        for r in xrange(32, 16, -1):
-            pygame.draw.ellipse(self.fov, (0, 0, 0, (r-16)*16-1), (40-r*5/4, 32-r, 2*r*5/4, 2*r), 0)
+        self.memory = pygame.Surface(self.screen.get_size(), pg.SRCALPHA)
+        self.memory.fill((0, 0, 0, 255))
         self.dirty = []
 
     def render_level(self, level):
-        self.sprites, self.shadows = level.render_sprites(self.tiles)
+        self.sprites, self.shadows, pcmob = level.render_sprites(self.tiles)
         self.background.blit(level.render_background(self.tiles), (0, 0))
-
-    def light(self, (x, y)):
-        dirty = self.fog.blit(self.fov, (x-40, y-32),
-                              special_flags=pg.BLEND_RGBA_MIN)
-        self.screen.blit(self.background, dirty.topleft, area=dirty)
-        self.dirty.append(dirty)
+        self.vision = pygame.sprite.LayeredDirty()
+        self.vision.add(Vision(pcmob, level))
 
     def light_room(self, room):
         (rx, ry), (rw, rh) = room
-        for y in xrange(ry * 12+18, (ry + rh)* 12-4, 3):
-            for x in xrange(4 + rx * 20 + 10, 4 + (rx + rw)* 20 - 10, 5):
-                self.light((20+x, 16+y))
+        mx = rx * 20 + 6
+        my = ry * 12 + 12
+        mw = (rw+1) * 20 + 12
+        mh = (rh+1) * 12 + 12
+        darkroom = self.background.subsurface((mx, my, mw, mh))
+        darkroom.set_alpha(16)
+        rect=self.memory.blit(darkroom, (mx, my))
+        self.fog.blit(self.memory, (mx, my), rect)
+        self.dirty.append(rect)
 
     def draw(self):
         if self.first_draw:
             self.screen.blit(self.background, (0, 0))
             self.shadows.draw(self.screen)
             self.sprites.draw(self.screen)
-            self.first_draw = False
+            self.vision.draw(self.fog)
             self.screen.blit(self.fog, (0, 0))
             self.dirty = [self.background.get_rect()]
+            self.first_draw = False
         else:
+            self.screen.blit(self.background, (0, 0))
+            self.vision.clear(self.fog, self.memory)
             self.sprites.clear(self.screen, self.background)
             self.shadows.draw(self.screen)
             self.dirty.extend(self.sprites.draw(self.screen))
+            self.dirty.extend(self.vision.draw(self.fog))
             self.screen.blit(self.fog, (0, 0))
         pygame.display.update(self.dirty)
         self.dirty = []
@@ -316,6 +339,7 @@
     def update(self):
         self.sprites.update()
         self.shadows.update()
+        self.vision.update()
 
 
 class Game(object):
@@ -336,8 +360,6 @@
             if room and room not in self.level.lit_rooms:
                 self.level.lit_rooms.append(room)
                 self.display.light_room(room)
-            else:
-                self.display.light(self.pc.mob.rect.center)
             self.display.draw()
             self.clock.tick(15)
             self.display.update()