You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何在Pygame窗口中实现文本游戏的输出日志功能?

解决Pygame窗口显示游戏日志(替换控制台print)的方案

嘿,我来帮你搞定这个把文本游戏输出从控制台转到Pygame窗口的问题!核心思路就是用一个文本缓冲区(其实就是个列表)来存最近5条消息,然后写个自定义的my_print函数替代系统的print,最后把缓冲区的内容实时更新到Pygame的标签里。下面一步步来改:

第一步:修改Display模块,初始化缓冲区和自定义打印函数

首先在Display模块里创建日志缓冲区,写好my_print函数,还要修正日志标签的初始化逻辑:

from pygame_functions import *
import random

# 初始化日志缓冲区,最多保存最近5条消息
game_log_buffer = []
MAX_LOG_LINES = 5

screenSize(800, 800)
wordBox = makeTextBox(50, 700, 700, 0, "Enter Command", 0, 24)
showTextBox(wordBox)

# 初始化日志标签,先显示空文本
gameLog = makeLabel("", 30, 50, 500, "white", "Agency FB", "black")
showLabel(gameLog)

def my_print(*message_parts):
    # 把多参数的消息拼接成一个字符串(兼容原来的print多参数写法)
    message = " ".join(str(part) for part in message_parts)
    # 加入缓冲区
    game_log_buffer.append(message)
    # 如果超过最大行数,删除最早的一条
    if len(game_log_buffer) > MAX_LOG_LINES:
        game_log_buffer.pop(0)
    # 把缓冲区内容拼接成带换行的字符串
    log_text = "\n".join(game_log_buffer)
    # 更新Pygame标签的显示内容
    changeLabel(gameLog, log_text)

第二步:替换所有系统print为自定义my_print

现在要把gamefilegameworld里所有的print()调用都换成my_print(),注意要确保能导入这个函数。

修改gamefile模块

在开头导入my_print,然后替换所有print

from pygame import *
from gameworld import *
from Display import *  # 已包含my_print函数

def main():
    player = Player("Jeff", 100)
    bag = Bag([])
    location = Location('introd')
    command = ' '
    while True:
        command = textBoxInput(wordBox)
        if command in location.room.exits:
            location.travel(command, bag)
        elif command == 'look':
            location.room_desc()
        elif command == '':
            my_print('You have to say what it is you want to do!')
            command = '#'
        elif command == 'search':
            location.search_room()
        elif command.split()[0] == 'Take':
            location.check_take(command.split()[1], bag, location)
        elif command == 'Inventory':
            bag.check_inv()
        else:
            my_print('Invalid command')
        if not command:
            break
if __name__ == '__main__':
    main()

修改gameworld模块

导入自定义my_print,然后替换所有print

from gameitems import *
from Display import my_print  # 导入自定义打印函数

class Room:
    def __init__(self, name, description, exits, actions, roominv, roomkey, lock):
        self.name = name
        self.description = description
        self.exits = exits
        self.actions = actions
        self.roominv = roominv
        self.roomkey = roomkey
        self.lock = lock

class Player:
    def __init__(self, name, health):
        self.name = name
        self.health = health

class Location:
    def __init__(self, room):
        self.room = world[room]

    def travel(self, direction, bag):
        if direction not in self.room.exits:
            self.no_exit()
        else:
            self.set_new_room_name(direction, bag)

    def set_new_room_name(self, direction, bag):
        new_room_name = self.room.exits[direction]
        my_print("moving to", new_room_name)
        self.key_check(new_room_name, bag)

    def key_check(self, new_room_name, bag):
        if world[new_room_name].lock and world[new_room_name].roomkey not in bag.inventory:
            self.no_key()
        else:
            world[new_room_name].lock = False
            self.set_room(new_room_name)
            self.room_desc()

    def set_room(self, new_room_name):
        self.room = world[new_room_name]

    def no_exit(self):
        my_print("You can't go that way!")

    def no_key(self):
        my_print('The door is locked! You need the right key!')

    def room_desc(self):
        my_print(self.room.description)
        my_print(self.room.actions)

    def search_room(self):
        if self.room.roominv:
            for item in list(self.room.roominv.keys()):
                my_print("you find a", item)
        else:
            my_print("You don't find anything")

    def none_here(self, key):
        my_print("You can't find a", key)

    def check_take(self, key, bag, location):
        if key in self.room.roominv:
            bag.add_to_inv(key, location)
            my_print('you take the', key)
        else:
            self.none_here(key)

class Bag():
    def __init__(self, inventory):
        self.inventory = inventory

    def add_to_inv(self, key, location):
        self.inventory.append(location.room.roominv[key])
        del location.room.roominv[key]

    def check_inv(self):
        for item in self.inventory:
            my_print("Your bag contains:", item.name)

world = {}
world['introd'] = Room('introd', "You are in a forest, you can hear wildlife all around you. There seems to be a clearing in the distance.", {'n': "clearing"}, {"Search the ground", "Go North"}, {'Sword': Sword}, None, False)
world['clearing'] = Room('clearing', "You are in a clearing surrounded by forest. Sunlight is streaming in, illuminating a bright white flower in the center of the clearing. To the South is the way you entered the forest. A well worn path goes to the East. In the distance a harp can be heard.", {'s': "introd", 'e': "forest path"}, {"Take flower", "Go south", "Go East"}, {'Flower': Flower}, None, False)
world['forest path'] = Room('forest path', "You begin walking down a well beaten path. The sounds of the forest surround you. Ahead you can see a fork in the road branching to the South and East. You can smell smoke coming from the South, and can hear a stream to the East", {'s': "cottage", 'e': "stream", 'w': "clearing"}, {"Go South", "Go East", "Go West"}, {'Stick': Stick})
# 注:你原代码中最后一行未完成,这里补充了Stick的定义,可根据实际游戏道具调整

第三步:验证效果

现在运行游戏,所有原本打印到控制台的消息都会被收集到缓冲区里,窗口会自动显示最近5条日志,并且每次有新消息时会实时更新!

内容的提问来源于stack exchange,提问作者SchrodingersStat

火山引擎 最新活动