且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

如何为基于文本的 python rpg 制作保存/加载游戏?

更新时间:2023-02-02 22:20:00

你可以使用 jsonpickle 将您的对象图序列化为 JSON.jsonpickle 不是标准库的一部分,因此您必须先安装它,例如通过执行 easy_install jsonpickle.

You can use jsonpickle to serialize your object graph to JSON. jsonpickle is not part of the standard library, so you'll have to install it first, for example by doing easy_install jsonpickle.

您也可以使用标准库 json 模块,但是你必须实现自己的 JSONEncoder 来处理您的自定义对象.这并不难,但不像让 jsonpickle 为你做这件事那么容易.

You could also achieve the same using the standard library json module, but then you'd have to implement your own JSONEncoder to deal with your custom objects. Which isn't hard, but not as easy as just letting jsonpickle do it for you.

我使用播放器类的简化示例来演示如何为构成游戏状态的对象实现加载和保存功能(完全忽略任何故事情节):

I used simplified examples of your player classes to demonstrate how you could implement load and save functionality for the objects that constitute your game state (completely ignoring any story line):

import jsonpickle
import os
import sys


SAVEGAME_FILENAME = 'savegame.json'

game_state = dict()


class Human(object):
    """The human player
    """
    def __init__(self, name, health, gold):
        self.name = name
        self.health = health
        self.gold = gold


class Monster(object):
    """A hostile NPC.
    """
    def __init__(self, name, health):
        self.name = name
        self.health = health


def load_game():
    """Load game state from a predefined savegame location and return the
    game state contained in that savegame.
    """
    with open(SAVEGAME_FILENAME, 'r') as savegame:
        state = jsonpickle.decode(savegame.read())
    return state


def save_game():
    """Save the current game state to a savegame in a predefined location.
    """
    global game_state
    with open(SAVEGAME_FILENAME, 'w') as savegame:
        savegame.write(jsonpickle.encode(game_state))


def initialize_game():
    """If no savegame exists, initialize the game state with some
    default values.
    """
    player = Human('Fred', 100, 10)
    imp = Monster('Imp', 50)

    state = dict()
    state['players'] = [player]
    state['npcs'] = [imp]
    return state


def attack():
    """Toy function to demonstrate attacking an NPC.
    """
    global game_state
    imp = game_state['npcs'][0]
    imp.health -= 3
    print "You attacked the imp for 3 dmg. The imp is now at %s HP." % imp.health


def spend_money(amount):
    """Toy function to demonstrate spending money.
    """
    global game_state
    player = game_state['players'][0]
    player.gold -= amount
    print "You just spent %s gold. You now have %s gold." % (amount, player.gold)


def game_loop():
    """Main game loop.
    This loop will run until the player exits the game.
    """
    global game_state

    while True:
        print "What do you want to do?"
        choice = int(raw_input("[1] Save game [2] Spend money "
                               "[3] Attack that Imp! [4] Load game "
                               "[5] Exit game
"))
        if choice == 1:
            save_game()
        elif choice == 2:
            spend_money(5)
        elif choice == 3:
            attack()
        elif choice == 4:
            game_state = load_game()
        else:
            print "Goodbye!"
            sys.exit(0)


def main():
    """Main function. Check if a savegame exists, and if so, load it. Otherwise
    initialize the game state with defaults. Finally, start the game.
    """
    global game_state

    if not os.path.isfile(SAVEGAME_FILENAME):
        game_state = initialize_game()
    else:
        game_state = load_game()
    game_loop()


if __name__ == '__main__':
    main()

注意全局 game_state 变量.您需要这样的东西来跟踪定义游戏状态的所有对象并将它们放在一起以便于序列化/反序列化.(它不一定必须是全局的,但它肯定更容易,像这样的游戏状态是使用全局变量真正有意义的少数情况之一.

Note the global game_state variable. You need something like that to keep track of all the objects that define your game state and keep them together for easy serialization / deserialization. (It doesn't necessarily have to be global, but it's definitely easier, and a game state like this is one of the few cases where it actually makes sense to use globals).

使用此代码保存游戏将生成如下所示的 savegame.json:

Saving the game using this code will result in a savegame.json that looks like this:

{
    "npcs": [
        {
            "health": 41,
            "name": "Imp",
            "py/object": "__main__.Monster"
        }
    ],
    "players": [
        {
            "gold": 5,
            "health": 100,
            "name": "Fred",
            "py/object": "__main__.Human"
        }
    ]
}