Game Save with Shelve

From TRCCompSci - AQA Computer Science
Jump to: navigation, search

Shelve can be used to serialize data in pygame, pretty much anything can be Shelved (class objects, structures etc).

Example to Use

Have a look at this code:

import pygame
from pygame.locals import *

pygame.init()
screen=pygame.display.set_mode((640,480))

class Block(object):
    sprite = pygame.image.load("dirt.png").convert_alpha()
    def __init__(self, x, y):
        self.rect = self.sprite.get_rect(centery=y, centerx=x)

blocklist = []

while True:
    screen.fill((25,30,90))
    mse = pygame.mouse.get_pos()
    key = pygame.key.get_pressed()

    for event in pygame.event.get():
        if event.type == QUIT:
            exit()

        if event.type==MOUSEBUTTONDOWN:
            if not any(block.rect.collidepoint(mse) for block in blocklist):
                x=(int(mse[0]) / 32)*32
                y=(int(mse[1]) / 32)*32
                blocklist.append(Block(x+16,y+16))

    for b in blocklist:
        screen.blit(b.sprite, b.rect)

    pygame.display.flip()

It creates a class called Block, and a list called blocklist. Everytime you press the mouse button a block will be created at the mouse position and it will be added to the blocklist. The game loop cycles through each block in the blocklist and blits it to the screen.

Import Shelve

You will need to import Shelve into your code, so add this with the other import statements:

import Shelve

Open a Shelve file to Read

Add this code before the game loop. It creates a method to load in the save file, if the file doesn't exist it will use (None,[]):

def load():
    try:
        g = shelve.open("save.bin") 
        return g['blocks']
    except KeyError:
        return None
    finally:
        g.close()

blocklist = load() or (None, [])

Open a Shelve file to Write

We can open a Shelve file to write the saved data, we need to specify the filename and the writeback=True will update any changes to the Shelve file. The data will be written when we close the Shelve file, add this code directly after the load code above:

f = shelve.open("save.bin",writeback=True) 
f['blocks'] = blocklist

Close the file

Finally in the event loop, change the quit event code. f.close() will close the Shelve file and write the data:

    for event in pygame.event.get():
        if event.type == QUIT:
            f.close()
            exit()

What should you have

You should be able to add blocks to the screen, and when you quit it will save the blocks and when you re-run the program they will persist.

You could alternatively create a save method to save the data, and then call it whenever a save is needed:

def save():
    f = shelve.open("save.bin") 
    f['blocks'] = blocklist
    f.close()

Writeback isn't worth using in this case because only changes between the f['blocks']... line and the f.close() will be saved.