Python虚拟宠物项目时间流逝标记功能实现求助
解决Pymagochi虚拟宠物时间流逝功能的问题
嘿Julio!看了你这个Pymagochi的代码,立刻就明白你为啥时间流逝的功能没效果了——你写的manageHunger()用了while True加time.sleep(60),这会直接把整个程序的主线程卡死,用户根本没法输入任何命令,程序就一直停在那里,自然看不到饥饿度变化啦。
下面给你两种实用的解决方案,你可以根据自己的需求选:
方案一:多线程后台运行(实时更新)
这个方案能让时间流逝的逻辑和用户输入的逻辑同时跑,宠物状态会实时变化,哪怕用户不操作也会更新。
步骤:
- 先导入
threading模块,用来创建后台线程 - 给宠物状态的更新逻辑加一个停止标志,方便程序退出或宠物死亡时终止线程
- 在游戏初始化的时候启动这些后台线程
修改后的关键代码如下:
首先在导入部分添加:
import threading
然后定义控制线程的事件和状态更新函数:
# 创建一个事件,用来通知线程停止 stop_event = threading.Event() def manageHunger(): while not stop_event.is_set(): if not myPet.dead: # 每分钟饥饿度减1,防止低于0 myPet.hungerLevel = max(0, myPet.hungerLevel - 1) # 饥饿度到0宠物死亡 if myPet.hungerLevel == 0: myPet.dead = True print(f"Oh no! {myPet.petName} starved to death!") stop_event.set() time.sleep(60) def manageBoredom(): while not stop_event.is_set(): if not myPet.dead: # 每90秒无聊度减1,防止低于0 myPet.entratainiment_level = max(0, myPet.entratainiment_level - 1) # 无聊度到0增加悲伤度,满10就死亡 if myPet.entratainiment_level == 0: myPet.sadnessLevel = min(10, myPet.sadnessLevel + 1) if myPet.sadnessLevel == 10: myPet.dead = True print(f"{myPet.petName} got too sad and passed away!") stop_event.set() time.sleep(90)
然后在setupGame()函数里启动这两个线程:
def setupGame(): os.system('cls') print("What would you like to name your pet?") myPet.petName = input("> ") # 启动饥饿度管理线程,daemon=True表示主程序退出时自动停止线程 hunger_thread = threading.Thread(target=manageHunger, daemon=True) hunger_thread.start() # 启动无聊度管理线程 boredom_thread = threading.Thread(target=manageBoredom, daemon=True) boredom_thread.start() print(f"Great! {myPet.petName} is ready to play!") promptUser()
方案二:时间戳计算(非阻塞,适合新手)
如果觉得多线程有点复杂,这个方案更简单:每次用户输入命令前,计算上次操作到现在的时间差,一次性更新宠物状态。
步骤:
- 在
pet类里添加记录上次状态更新的时间戳属性 - 写一个更新状态的函数,每次用户操作前调用它
修改后的关键代码:
首先更新pet类的初始化:
class pet: def __init__(self): self.petName = '' self.hungerLevel = 10 self.happinesLevel = 10 self.sleepy = False self.sadnessLevel = 0 self.dead = False self.entratainiment_level = 15 # 记录上次更新的时间戳 self.last_hunger_update = time.time() self.last_boredom_update = time.time()
然后写状态更新函数:
def updatePetStatus(): if myPet.dead: return current_time = time.time() # 更新饥饿度:每分钟减1 time_since_hunger = current_time - myPet.last_hunger_update if time_since_hunger >= 60: minutes_passed = int(time_since_hunger // 60) myPet.hungerLevel = max(0, myPet.hungerLevel - minutes_passed) if myPet.hungerLevel == 0: myPet.dead = True print(f"Oh no! {myPet.petName} starved to death!") # 更新上次饥饿度时间 myPet.last_hunger_update = current_time # 更新无聊度:每90秒减1 time_since_boredom = current_time - myPet.last_boredom_update if time_since_boredom >= 90: intervals_passed = int(time_since_boredom // 90) myPet.entratainiment_level = max(0, myPet.entratainiment_level - intervals_passed) if myPet.entratainiment_level == 0: myPet.sadnessLevel = min(10, myPet.sadnessLevel + intervals_passed) if myPet.sadnessLevel == 10: myPet.dead = True print(f"{myPet.petName} got too sad and passed away!") # 更新上次无聊度时间 myPet.last_boredom_update = current_time
最后在promptUser()开头调用这个函数:
def promptUser(): updatePetStatus() # 如果宠物死了,回到标题界面 if myPet.dead: print("Game over! Your pet is gone.") titleScreen() print("#############################") print("what would you like to do?") # 剩下的代码不变
小提示:
- 多线程方案适合想要实时更新的场景,但要注意如果有多个线程同时修改宠物属性,复杂操作时可以用
threading.Lock()来保证线程安全(你的代码里都是简单加减,暂时不需要) - 时间戳方案更简单,没有线程问题,但只有用户操作时才会更新状态,长时间不操作的话,宠物状态不会变化
内容的提问来源于stack exchange,提问作者julio.c
相关产品推荐
相关产品推荐

