如何为基于文本的 python rpg 制作保存/加载游戏?
问题描述
我使用的是 python 3.2!下面的其余帖子...
I am using python 3.2! rest of post below...
我正在用 python 完成基于文本的 RPG,我需要一些帮助.我需要制作一个保存/加载游戏系统.我读到我可以使用 pickle 其他一些方法,但这并不完全是我想要的.基本上,我希望能够将变量保存到文本文件中.如果文件存在,则加载变量,然后跳过要求玩家输入名称的介绍.我将给出泡菜方法,其他人尝试看看它们是如何工作的.如果有人愿意向我展示如何使用 .txt 文件执行此操作,我将不胜感激!找到后我会继续挖掘并发布我的解决方案.
I am finishing my text based RPG in python, and I need some help. I need to make a save/load game system. I read that I can use pickle a few other methods but thats not entirely what I want. Basically, I want to be able to save my variables into a text file. If the file exists, load the variables, and skip over the introduction where it asks the player for a name. I will give the pickle method and others try and see how they work. If someone would be kind enough to show me how I would do this with .txt files, I would be very grateful! I will continue digging and post my solution once I have found it.
我已经删除了原始帖子中不相关的部分.以下代码是 WORKING game.py 文件.我不再使用单独的类模块.话题解决了,现在我可以处理故事情节了!:D
I have removed the irrelevant parts of my original post. The following code is the WORKING game.py file. I no longer use a separate class module. Topic solved, now I can work on a storyline! :D
#A text based RPG
#Import required modules
import jsonpickle
import os
import sys
import time
from random import randint
#main game
#Variables
go = True
IsShopLocked = False
IsDaggerEquipped = False
IsSwordEquipped = False
IsLeatherHideEquipped = False
SAVEGAME_FILENAME = 'savegame.json'
game_state = dict()
### Classes ###
class Human(object):
#Represents the human player in the game
def __init__(self, name, health, strength, gold):
self.name = name
self.health = health
self.strength = strength
self.gold = gold
class AI(object):
#Represents the enemy player in the game
def __init__(self, name, health, strength):
self.name = name
self.health = health
self.strength = strength
class Item(object):
#represents any item in the game
def __init__(self, name, hvalue, strvalue):
self.name = name
self.hvalue = hvalue
self.strvalue = strvalue
###end classess###
###functions for loading, saving, and initializing the game###
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.
"""
global game_state
player = Human('Fred', 100, 10, 1000)
enemy = AI('Imp', 50, 20)
state = dict()
state['players'] = [player]
state['npcs'] = [enemy]
return state
###End functions for loading, saving, and initalizing the game###
###Main game functions###
#Function for the shop
def Shop():
global game_state
player = game_state['players'][0]
dagger = Item('Dagger', 0, 5)
sword = Item('Sword', 0, 10)
leather_hide = Item('Leather Hide', 5, 0)
if IsShopLocked == True:
print("The shop is locked!
Please go back and continue your adventure!")
else:
print()
print("Welcome to the Larkville shop! What would you like to buy?
1. Weapons
2. armor
3. Go back")
selection = int(input("Enter a value: "))
if selection == 1:
if player.gold >= 50:
print("Weapons shop")
print("1. Bronze Dagger: $20
2. Bronze Sword: $50")
wpnselection = int(input("Enter a value: "))
if wpnselection == 1:
global IsDaggerEquipped
global IsSwordEquipped
if IsDaggerEquipped == True or IsSwordEquipped == True:
print("You already have this or another weapon equipped...")
Game_Loop()
else:
dagger = Item('Dagger', 0, 5)
IsDaggerEquipped = True
player.strength += dagger.strvalue
player.gold -= 20
print("strength increased to: {}".format(player.strength))
Game_Loop()
elif wpnselection == 2:
if IsDaggerEquipped == True or IsSwordEquipped == True:
print("You already have this or another weapon equipped...")
Game_Loop()
else:
sword = Item('Sword', 0, 10)
IsSwordEquipped = True
player.strength += sword.strvalue
player.gold -= 50
print("strength increased to: {}".format(player.strength))
Game_Loop()
elif wpnselection == 3:
Game_Loop()
elif selection == 2:
if player.gold >= 20:
print ("Armor Shop")
print ("1. Leather hide
2. Go back")
armselection = int(input("enter a value: "))
if armselection == 1:
global IsLeatherHideEquipped
if IsLeatherHideEquipped == True:
print("You are already wearing armor!")
Game_Loop()
else:
leather_hide = Item('Leather Hide', 5, 0)
IsLeatherHideEquipped = True
player.health += leather_hide.hvalue
player.gold -= 20
print("Health increased to: {}".format(player.health))
Game_Loop()
elif armselection == 2:
Game_Loop()
elif selection == 3:
Game_Loop()
#Function for combat
def Combat():
global game_state
player = game_state['players'][0]
enemy = game_state['npcs'][0]
global go
while go == True:
dmg = randint (0, player.strength)
edmg = randint (0, enemy.strength)
enemy.health -= dmg
if player.health <= 0:
os.system('cls')
print()
print("You have been slain by the enemy {}...".format(enemy.name))
go = False
leave = input("press enter to exit")
elif enemy.health <= 0:
os.system('cls')
print()
print("You have slain the enemy {}!".format(enemy.name))
go = False
leave = input("press any key to exit")
else:
os.system('cls')
with open("test.txt", "r") as in_file:
text = in_file.read()
print(text)
player.health -= edmg
print()
print("You attack the enemy {} for {} damage!".format(enemy.name, dmg))
print("The enemy has {} health left!".format(enemy.health))
print()
print("The enemy {} attacked you for {} damage!".format(enemy.name, edmg))
print("You have {} health left!".format(player.health))
time.sleep(3)
#The main game loop
def Game_Loop():
global game_state
while True:
print()
print("You are currently in your home town of Larkville!")
print("What would you like to do?")
print("1. Shop
2. Begin/continue your adventure
3. View player statistics
4. save game")
print()
try:
selection = int(input("Enter a value: "))
except ValueError:
print()
print("You can only use the numbers 1, 2, or 3.")
print()
Game_Loop()
if selection == 1:
Shop()
elif selection == 2:
Combat()
elif selection == 3:
player = game_state['players'][0]
print()
print("Your players stats:
Health: {}
Strength: {}
Gold: {}".format(player.health, player.strength, player.gold))
if IsDaggerEquipped == True:
print("You have a dagger equipped")
elif IsSwordEquipped == True:
print ("You have a sword equipped")
elif IsLeatherHideEquipped == True:
print("You are wearing a leather hide")
elif selection == 4:
game_state = save_game()
else:
print()
print("Oops! Not a valid input")
print()
###End main game functions###
###The "main" function, not to be confused with anything to do with main above it###
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()
###end main function###
解决方案
你可以使用 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"
}
]
}
相关文章