changeset 75:798640df3874

really working savegames, seriously
author Radomir Dopieralski <sheep-devel@sheep.art.pl>
date Sat, 04 Jan 2014 13:40:05 +0100
parents 5b3421b7be82
children ee5acbf5df18
files fujo/display.py fujo/game.py fujo/level.py fujo/mobs.py fujo/player.py fujo/saves.py fujo/things.py fujo/title.py fujo/window.py
diffstat 9 files changed, 93 insertions(+), 14 deletions(-) [+]
line wrap: on
line diff
--- a/fujo/display.py	Sat Jan 04 13:15:50 2014 +0100
+++ b/fujo/display.py	Sat Jan 04 13:40:05 2014 +0100
@@ -56,13 +56,13 @@
         self.windows = Sprites()
         self.labels = Sprites()
         self.clock = pygame.time.Clock()
+        self.quit = False
 
     def tick(self):
         self.clock.tick(24)
         for event in pygame.event.get():
             if event.type == pygame.QUIT:
-                pygame.quit()
-                raise SystemExit()
+                self.quit = True
 
     def update(self):
         self.windows.clear(self.screen, self.windows_background)
--- a/fujo/game.py	Sat Jan 04 13:15:50 2014 +0100
+++ b/fujo/game.py	Sat Jan 04 13:40:05 2014 +0100
@@ -58,6 +58,10 @@
             if self.player.dead:
                 self.running = False
                 return
+            if self.display.quit:
+                saves.save(self.level.save())
+                pygame.quit()
+                raise SystemExit()
             if self.player.climb:
                 self.new_level()
                 return
--- a/fujo/level.py	Sat Jan 04 13:15:50 2014 +0100
+++ b/fujo/level.py	Sat Jan 04 13:40:05 2014 +0100
@@ -7,7 +7,6 @@
 from . import things
 from . import items
 from . import saves
-from . import player
 
 
 AREAS = [
@@ -202,7 +201,7 @@
         mob_list = [mobs.Mob.create(mob) for mob in data['mobs']]
         self.mobs = dict((mob.pos, mob) for mob in mob_list)
         for mob in mob_list:
-            if isinstance(mob, player.Player):
+            if mob.is_player:
                 self.player = mob
                 break
         things_list = [things.Thing.create(thing) for thing in data['things']]
--- a/fujo/mobs.py	Sat Jan 04 13:15:50 2014 +0100
+++ b/fujo/mobs.py	Sat Jan 04 13:40:05 2014 +0100
@@ -27,6 +27,7 @@
 
 
 class Mob(pygame.sprite.Sprite, saves.Saveable):
+    is_player = False
     max_health = 0
     kinds = {}
 
@@ -255,7 +256,7 @@
 class Bat(Monster):
     looks = 4
     damage = 1
-    defense = 4
+    defense = 0
     attack = 1
     max_health = 2
 
--- a/fujo/player.py	Sat Jan 04 13:15:50 2014 +0100
+++ b/fujo/player.py	Sat Jan 04 13:40:05 2014 +0100
@@ -16,6 +16,8 @@
 
 @Mob.register
 class Player(Mob):
+    is_player = True
+
     def __init__(self):
         self.max_health = 20
         super(Player, self).__init__(RES.player)
@@ -96,7 +98,7 @@
 
     def pick_item(self, level):
         thing = level.things.get(self.pos)
-        if thing and thing.item:
+        if thing and thing.is_item:
             item = level.pick_item(thing)
             self.label(item.get_name(), delay=2, place=thing.rect.midtop)
             self.items.append(item)
@@ -254,6 +256,7 @@
             'weapon': self.items.index(self.weapon) if self.weapon else None,
             'armor': self.items.index(self.armor) if self.armor else None,
             'items': [item.save() for item in self.items],
+            'face': self.face,
         })
         return data
 
@@ -268,3 +271,4 @@
         self.items = [items.Item.create(item) for item in data['items']]
         self.weapon = self.items[data['weapon']] if data['weapon'] else None
         self.armor = self.items[data['armor']] if data['armor'] else None
+        self.face = data['face']
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/fujo/saves.py	Sat Jan 04 13:40:05 2014 +0100
@@ -0,0 +1,68 @@
+#!/usr/bin/env python
+# -*- coding: utf-8 -*-
+
+import os
+
+import simplejson
+
+
+SAVE_FILE = '~/.fujo.sav'
+
+
+class Saveable(object):
+    # kinds = {}  # Each type of saveable needs its own dict of kinds
+
+    @classmethod
+    def register(cls, kind):
+        cls.kinds[kind.__name__] = kind
+        return kind
+
+    @classmethod
+    def create(cls, data):
+        kind = cls.kinds[data['kind']]
+        mob = kind()
+        mob.load(data)
+        return mob
+
+    def save(self):
+        return {
+            'kind': self.__class__.__name__,
+        }
+
+    def load(self, data):
+        pass
+
+
+def save(level_data):
+    filename = os.path.expanduser(SAVE_FILE)
+    data = {
+        'version': 3,
+        'level': level_data,
+    }
+    with open(filename, 'wb') as f:
+        simplejson.dump(data, f)
+
+
+def load():
+    filename = os.path.expanduser(SAVE_FILE)
+    with open(filename, 'rb') as f:
+        data = simplejson.load(f)
+    if data['version'] != 3:
+        raise ValueError('Bad save version %r' % data['version'])
+    return data['level']
+
+
+def valid():
+    try:
+        load()
+    except Exception:
+        return False
+    return True
+
+
+def delete():
+    filename = os.path.expanduser(SAVE_FILE)
+    try:
+        os.remove(filename)
+    except IOError:
+        pass
--- a/fujo/things.py	Sat Jan 04 13:15:50 2014 +0100
+++ b/fujo/things.py	Sat Jan 04 13:40:05 2014 +0100
@@ -30,8 +30,8 @@
 
 
 class Thing(pygame.sprite.Sprite, saves.Saveable):
-    exit = False
-    item = False
+    is_exit = False
+    is_item = False
     kinds = {}
 
     def __init__(self):
@@ -60,6 +60,7 @@
 @Thing.register
 class Item(Thing):
     frame = 1
+    is_item = True
 
     def __init__(self, item=None):
         if item is not None:
@@ -85,14 +86,16 @@
         return data
 
     def load(self, data):
-        super(Thing, self).load(data)
+        super(Item, self).load(data)
         self.item = items.Item.kinds[data['item']]
+        self.frame = self.item.looks
+        self.image = RES.things[self.frame]
 
 
 @Thing.register
 class Ladder(Thing):
     frame = 2
-    exit = True
+    is_exit = True
 
 @Thing.register
 class Hole(Thing):
--- a/fujo/title.py	Sat Jan 04 13:15:50 2014 +0100
+++ b/fujo/title.py	Sat Jan 04 13:40:05 2014 +0100
@@ -15,13 +15,13 @@
         self.screen = pygame.display.get_surface()
         self.windows = display.Sprites()
         self.clock = pygame.time.Clock()
+        self.quit = False
 
     def tick(self):
         self.clock.tick(20)
         for event in pygame.event.get():
             if event.type == pygame.QUIT:
-                pygame.quit()
-                raise SystemExit()
+                self.quit = True
 
     def update(self):
         self.windows.clear(self.screen, RES.title)
@@ -65,5 +65,5 @@
             elif choice == 'music on':
                 pygame.mixer.music.play(-1)
                 options[1] = ('music off', 'Turn music off')
-            elif choice == 'exit':
+            elif choice in ('exit', None):
                 return
--- a/fujo/window.py	Sat Jan 04 13:15:50 2014 +0100
+++ b/fujo/window.py	Sat Jan 04 13:40:05 2014 +0100
@@ -131,7 +131,7 @@
                 self.cursor.steps += 3
                 pos += 1
                 self.depress(display)
-            elif keys[pygame.K_ESCAPE]:
+            elif keys[pygame.K_ESCAPE] or display.quit:
                 break
             elif keys[pygame.K_RETURN]:
                 if self.items: