Commits

Radomir Dopieralski committed 3eae443

Start screen with menu

  • Participants
  • Parent commits 03aeafa

Comments (0)

Files changed (8)

jelly/__init__.py

 #!/usr/bin/env python
 # -*- coding: utf-8 -*-
 
+import sys
 
 import pygame
 from pygame import locals as pg
 from jelly import mobs
 from jelly import rooms_level
 from jelly import message
+from jelly import util
 
 
 class Game(object):
 
     def start(self):
         self.display.render_image('jelly/title.png')
-        exit = False
-        self.display.sprites.add(message.Text('Press ESC'))
-        while not exit:
-            self.clock.tick(15)
-            self.display.update()
-            self.display.draw()
-            for event in pygame.event.get():
-                if event.type == pg.ACTIVEEVENT and event.gain:
-                    self.display.refresh()
-                if event.type == pg.QUIT or (
-                        event.type == pg.KEYDOWN and
-                        event.key == pg.K_ESCAPE):
-                    exit = True
+        menu = message.Menu((80, 380), ['Start new game', 'Exit'])
+        self.display.render_menu(menu)
+        choice = None
+        try:
+            while choice is None:
+                self.clock.tick(15)
+                self.display.update()
+                self.display.draw()
+                choice = menu.update()
+        except (util.QuitLevel, util.QuitGame):
+            sys.exit()
+        if choice == 1:
+            sys.exit()
+
+    def next_level(self):
+        self.level = rooms_level.Level(self.pc)
+        self.display.render_level(self.level)
 
     def main(self):
         self.game_over = False
         self.pc = mobs.Player()
-        self.level = rooms_level.Level(self.pc)
-        self.display.render_level(self.level)
-        while not self.game_over:
-            self.clock.tick(15)
-            self.display.update()
-            self.display.draw()
-            for event in pygame.event.get():
-                if event.type == pg.ACTIVEEVENT and event.gain:
-                    self.display.refresh()
-                if event.type == pg.QUIT or (
-                        event.type == pg.KEYDOWN and
-                        event.key == pg.K_ESCAPE):
-                    self.game_over = True
-            try:
-                pc_animation = self.display.mob_sprites[id(self.pc)].animations
-            except KeyError:
-                pc_animation = None
-                self.display.events(self.level.events)
-                self.level.events = []
-            if not pc_animation:
-                if self.pc.control(self.level):
-                    for mob in list(self.level.mobs):
-                        if mob == self.pc:
-                            continue
-                        mob.control(self.level)
-                self.display.events(self.level.events)
-                self.level.events = []
+        self.next_level()
+        try:
+            while not self.game_over:
+                self.clock.tick(15)
+                self.display.update()
+                self.display.draw()
+                for event in pygame.event.get():
+                    if event.type == pg.ACTIVEEVENT and event.gain:
+                        self.display.refresh()
+                    if event.type == pg.QUIT:
+                        raise util.QuitGame()
+                    elif event.type == pg.KEYDOWN and event.key == pg.K_n:
+                        self.next_level()
+                    elif event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE:
+                        raise util.QuitLevel()
+                try:
+                    pc_animation = self.display.mob_sprites[id(self.pc)].animations
+                except KeyError:
+                    pc_animation = None
+                    self.display.events(self.level.events)
+                    self.level.events = []
+                if not pc_animation:
+                    if self.pc.control(self.level):
+                        for mob in list(self.level.mobs):
+                            if mob == self.pc:
+                                continue
+                            mob.control(self.level)
+                    self.display.events(self.level.events)
+                    self.level.events = []
+        except util.QuitLevel:
+            return
+        except util.QuitGame:
+            sys.exit()
 
         self.shadows = pygame.sprite.RenderUpdates()
         self.lights = pygame.sprite.LayeredDirty()
 
+    def render_menu(self, menu):
+        for sprite in menu.sprites:
+            self.sprites.add(sprite)
+
     def render_level(self, level):
         self.first_draw = True
         self.fog = pygame.Surface(self.screen.get_size(), pg.SRCALPHA)

jelly/jelly.png

Old
Old image
New
New image
 # -*- coding: utf-8 -*-
 
 import pygame
+from pygame import locals as pg
 
 from jelly import resource
+from jelly import util
 
 
 class Text(pygame.sprite.Sprite):
         super(Text, self).__init__()
         if self.font is None:
             self.font = resource.load_font('pf_ronda_seven_bold.ttf')
-        self.image = self.outlined_text(text, (255, 255, 255), (0, 0, 0))
+        self.image = self.outlined_text(text, (250, 250, 250), (0, 0, 0))
         self.rect = self.image.get_rect()
+        self.depth = 1001
 
     def outlined_text(self, text, color, border_color):
         font = self.font
         image.set_colorkey(notcolor)
         return image
 
+
+class Window(pygame.sprite.Sprite):
+    tiles = None
+
+    def __init__(self, pos, (width, height)):
+        super(Window, self).__init__()
+        if self.tiles is None:
+            self.tiles = resource.load_tiles('jelly.png', 32, 32)
+        tile = self.tiles[80]
+        self.image = pygame.surface.Surface((width, height))
+        self.image.set_colorkey((0, 0, 0))
+        self.image.fill((25, 100, 252), (4, 4, width - 8, height - 8))
+        for y in xrange(8, height - 8, 8):
+            self.image.blit(tile, (0, y), (0, 8, 8, 8))
+            self.image.blit(tile, (width - 8, y), (24, 8, 8, 8))
+        for x in xrange(8, width - 8, 8):
+            self.image.blit(tile, (x, 0), (8, 0, 8, 8))
+            self.image.blit(tile, (x, height - 8), (8, 24, 8, 8))
+        self.image.blit(tile, (0, 0), (0, 0, 8, 8))
+        self.image.blit(tile, (width - 8, height - 8), (24, 24, 8, 8))
+        self.image.blit(tile, (width - 8, 0), (24, 0, 8, 8))
+        self.image.blit(tile, (0, height - 8), (0, 24, 8, 8))
+
+        self.rect = self.image.get_rect()
+        self.rect.topleft = pos
+        self.depth = 1000
+
+
+class Cursor(pygame.sprite.Sprite):
+    tiles = None
+
+    def __init__(self, pos):
+        super(Cursor, self).__init__()
+        if self.tiles is None:
+            self.tiles = resource.load_tiles('jelly.png', 32, 32)
+        self.image = self.tiles[81]
+        self.rect = self.image.get_rect()
+        self.rect.center = pos
+        self.pos = pos
+        self.item = 0
+        self.depth = 1002
+        self.x = 0
+        self.dx = 1
+
+    def update(self):
+        self.x += self.dx
+        if self.x > 4:
+            self.dx -= 2
+        elif self.x < -4:
+            self.dx += 1
+        self.rect.center = (self.pos[0]+self.x, self.pos[1] + 14 * self.item)
+
+
+class Menu(object):
+    def __init__(self, pos, items):
+        self.pos = pos
+        self.sprites = []
+        self.items = items
+        width = 0
+        for i, item in enumerate(items):
+            text = Text(item)
+            self.sprites.append(text)
+            text.rect.topleft = (pos[0] + 12, pos[1] + 14 * i + 6)
+            if width < text.rect.width:
+                width = text.rect.width
+        self.cursor = Cursor((pos[0] + 10, pos[1] + 14))
+        self.sprites.append(self.cursor)
+        self.window = Window(pos, (18 + width, 16 + 14 * len(items)))
+        self.sprites.append(self.window)
+
+    def move(self, di):
+        self.cursor.item = max(0, min(len(self.items)-1, self.cursor.item + di))
+
+    def update(self):
+        for event in pygame.event.get():
+            if event.type == pg.ACTIVEEVENT and event.gain:
+                self.display.refresh()
+            elif event.type == pg.KEYDOWN and event.key == pg.K_UP:
+                self.move(-1)
+            elif event.type == pg.KEYDOWN and event.key == pg.K_DOWN:
+                self.move(1)
+            elif event.type == pg.KEYDOWN and event.key == pg.K_z:
+                return self.cursor.item
+            elif event.type == pg.QUIT:
+                raise util.QuitGame()
+            elif event.type == pg.KEYDOWN and event.key == pg.K_ESCAPE:
+                raise util.QuitLevel()
+        return None
+

jelly/resource.py

 import pygame
 
 
+TILE_CACHE = {}
+FONT_CACHE = {}
+
+
 def load_tiles(filename, width, height):
-    image = load_image(filename)
-    image_width, image_height = image.get_size()
-    tiles = []
-    for x in range(image_width/width):
-        for y in range(image_height/height):
-            rect = (x * width, y * height, width, height)
-            tiles.append(image.subsurface(rect))
+    try:
+        return TILE_CACHE[filename, width, height]
+    except KeyError:
+        image = load_image(filename)
+        image_width, image_height = image.get_size()
+        tiles = []
+        for x in range(image_width/width):
+            for y in range(image_height/height):
+                rect = (x * width, y * height, width, height)
+                tiles.append(image.subsurface(rect))
+        TILE_CACHE[filename, width, height] = tiles
     return tiles
 
 
     return pygame.image.load(f, filename).convert()
 
 
-def load_font(filename):
-    # XXX the "right" way causes segmentation fault
-    # f = StringIO.StringIO(pkgutil.get_data('jelly', filename))
-    with tempfile.NamedTemporaryFile() as f:
-        data = pkgutil.get_data('jelly', filename)
-        f.write(data)
-        f.seek(0)
-        font = pygame.font.Font(f.name, 8)
+def load_font(filename, size=8):
+    try:
+        return FONT_CACHE[filename, size]
+    except KeyError:
+        # XXX the "right" way causes segmentation fault
+        # f = StringIO.StringIO(pkgutil.get_data('jelly', filename))
+        with tempfile.NamedTemporaryFile() as f:
+            data = pkgutil.get_data('jelly', filename)
+            f.write(data)
+            f.seek(0)
+            font = pygame.font.Font(f.name, size)
+        FONT_CACHE[filename, size] = font
     return font
 

jelly/rooms_level.py

                     mobs.Crate,
                 ])
                 self.spawn(MobClass((r(x, x + w), r(y, y + h))))
-        self[r(x, x+w), r(y, y+h)] = 5
 
         (x, y), (w, h) = random.choice(rooms)
         pc_pos = (r(x, x+w), r(y, y+h))

jelly/title.png

Old
Old image
New
New image
     return min(
             [0, 2, 4, 6, 1, 3, 5, 7],
             key=lambda d: dist(pos2, (x + DX[d], y + DY[d])))
+
+
+class QuitLevel(Exception):
+    pass
+
+
+class QuitGame(Exception):
+    pass