Mercurial > dw
view lib/display.py @ 59:6b9f9dcfabf1 default tip
Monster cleanup
| author | Radomir Dopieralski <moindev@sheep.art.pl> |
|---|---|
| date | Wed, 02 Jan 2008 03:54:40 +0100 |
| parents | 17b5a0cc33d9 |
| children |
line wrap: on
line source
#!/usr/bin/python # -*- coding: utf-8 -*- import pygame from pygame.locals import * import os from util import * pygame.init() screen = pygame.display.set_mode((320, 320)) def z_compare(a, b): return a.z-b.z class SortedUpdates(pygame.sprite.RenderUpdates): """Sprite group with a depth for controlling drawing order.""" def sprites(self): l = self.spritedict.keys() l.sort(z_compare) return l class Gauge(pygame.sprite.Sprite): def __init__(self, display): pygame.sprite.Sprite.__init__(self) self.base_image = pygame.image.load("data/image/gauge.png").convert() self.image = self.base_image.copy() self.image.set_alpha(200) self.rect = self.image.get_rect() self.rect.bottom = display.screen.get_rect().bottom self.image.fill((128, 200, 0), Rect(11, 3, 18, 2)) class Shadow(pygame.sprite.Sprite): """Transparent shadows""" image = read_frames(os.path.join("data", "image", "shadow.png"))[0][0] def __init__(self, sprite): pygame.sprite.Sprite.__init__(self) self.dh = 10 self.image.set_alpha(92) self.rect = Rect(0,0, 24, 24) self.sprite = sprite self.update() def update(self): x, y = self.sprite.rect.center self.rect.center = (x, y+4+self.sprite.h) class Display: """Display-related code""" def __init__(self): self.clock = pygame.time.Clock() self.screen = screen self.sprites = SortedUpdates() self.shadows = pygame.sprite.RenderUpdates() self.effects = pygame.sprite.RenderUpdates() self.hud = pygame.sprite.RenderUpdates() self.scrollpos = [0, 0] self.key_pressed = None self.hud.add(Gauge(self)) def get_image(self, filename, cache={}): """Read an image from disk, with caching.""" image_path = os.path.join('data', 'image') try: return cache[filename] except KeyError: file_path = os.path.join(image_path, filename) cache[filename] = pygame.image.load(file_path).convert() return cache[filename] def draw_map(self, m): """Draw the background based on the provided map.""" cache = {} background = pygame.Surface((m.w*24, m.h*16)) background.fill((0, 0, 0)) x, y = 0, 0 for line in m: for tile in line: urls = m.map_key[tile] if urls and urls[0]: image = self.get_image(urls[0], cache) background.blit(image , (x*24, y*16)) x += 1 x = 0 y += 1 self.background = background def add_sprite(self, sprite): """Place a sprite taking scrolling into account""" self.sprites.add(sprite) sprite.rect.move_ip(self.scrollpos[0], self.scrollpos[1]) def place_monsters(self, monsters): for monster in monsters.values(): sprite = monster.sprite self.add_sprite(sprite) self.shadows.add(Shadow(sprite)) def scroll_after(self, rect): """Scrolls to keep the sepcified rectangle visible.""" hscroll = 0 vscroll = 0 if rect.left<48: hscroll = 3 if rect.right>self.screen.get_width()-48: hscroll = -3 if rect.top<48: vscroll = 2 if rect.bottom>self.screen.get_height()-48: vscroll = -2 if hscroll or vscroll: self.scroll(hscroll, vscroll) self.refresh() def scroll(self, dx, dy): """Scroll the map by specified amount""" self.scrollpos[0] += dx self.scrollpos[1] += dy for sprite in self.sprites: sprite.rect.move_ip(dx, dy) for sprite in self.effects: sprite.rect.move_ip(dx, dy) for sprite in self.shadows: sprite.rect.move_ip(dx, dy) def clear_func(self, screen, rect): """ Clean up after sprites, taking scrolling into account and handling sprites that are out of map. """ source = rect.move(-self.scrollpos[0], -self.scrollpos[1]) if not self.background.get_rect().contains(source): screen.fill((0,0,0),rect) screen.blit(self.background, rect, source) def refresh(self): '''Redraw the whole level''' self.screen.fill((0,0,0)) self.screen.blit(self.background, self.scrollpos) self.hud.clear(self.screen, self.clear_func) self.effects.clear(self.screen, self.clear_func) self.sprites.clear(self.screen, self.clear_func) self.shadows.clear(self.screen, self.clear_func) self.shadows.draw(self.screen) self.sprites.draw(self.screen) self.effects.draw(self.screen) self.hud.draw(self.screen) pygame.display.update() def update(self): '''Redraw and update all the animated parts''' self.hud.clear(self.screen, self.clear_func) self.effects.clear(self.screen, self.clear_func) self.sprites.clear(self.screen, self.clear_func) self.shadows.clear(self.screen, self.clear_func) self.sprites.update() self.shadows.update() self.effects.update() self.hud.update() dirty = self.shadows.draw(self.screen) dirty += self.sprites.draw(self.screen) dirty += self.effects.draw(self.screen) dirty += self.hud.draw(self.screen) pygame.display.update(dirty) def show_frame(self): # Update the screen self.update() self.clock.tick(15) # Process input for event in pygame.event.get(): if event.type==QUIT: sys.exit(0) elif event.type==KEYDOWN: self.key_pressed = event.key
