在Python3x中创建一个始终可用的文本菜单

0 投票
1 回答
3396 浏览
提问于 2025-04-18 04:24

我刚开始学习Python,进步得很快。谢谢大家的帮助。

我想做一个文本菜单,这个菜单可以在一个讲故事的文字角色扮演游戏中一直运行在后台。我查了很多资料,但找不到关于如何创建一个“始终在线”菜单的解释,或者这样的菜单是怎么工作的。

我希望玩家在游戏中随时按下“m”键,就能看到菜单的提示。

到目前为止,我已经创建了一个“用户输入”的函数,还有一个“菜单”的函数,每次游戏需要玩家输入时就会调用这些函数。

def menu():
    print('Press "1" for map >>> "2" for stats >>> "3" for exit')
    choice = input()
    if choice == '1':
        print('map needs to be made and shown')
    elif choice == '2':
        print('stats need to be made and assinged to choice 2 in def menu')
    elif choice == '3':
        print('You are exiting the menu. Press "M" at any time to return to the menu')
        return
    else:
        print('I did not recognize your command')
        menu()

def userinput():
    print('Press 1 to attack an enemy >>> 2 to search a room >>> 3 to exit game')
    print('Press "M" for menu at any time')
    inputvalue = input()
    if inputvalue == 'm':
        menu()
    elif inputvalue == '1':
        print('attack function here')
    elif inputvalue == '2':
        print('search function here')
    elif inputvalue == '3':
        exit
    else:
        userinput()

但这样似乎不是一个理想的解决方案,因为用户不能随时选择查看地图或退出游戏。

有没有办法让菜单一直在后台运行呢?

我想过用一个永远不会结束的循环,把整个游戏都放在这个循环里,但这样做似乎不太经济。

任何想法或帮助都非常感谢。

1 个回答

0

我试着做了一下。这可能不是你想要的最佳结构,但我不想让我的回复变得太复杂。

对于任何有用户界面的东西,"标准"做法是将模型、视图和控制分开。你可以在网上查查MVC架构。虽然一开始这样做会增加一些复杂性,但从长远来看,对于任何不简单的用户界面,这样做会让生活变得简单很多。

还有一些需要注意的点:

  • 你没有去掉输入中的空格(比如“3 ”这样的输入可能会导致问题)
  • 你的输入是区分大小写的(你要求“M”,但检查的是“m”)……也许可以用choice = choice.strip().lower()来处理?
  • 在Python 2和Python 3中,raw_input和input的工作方式不同,这意味着你的代码在Python 2中无法运行。你可以查看这个链接了解更多raw_input()和input()在python3.x中的区别。我已经把我的例子改成使用raw_input。你可能想在代码的开头使用这个解决方案http://code.activestate.com/recipes/577836-raw_input-for-all-versions-of-python/,以便兼容不同版本。

一些代码

# flag we set when we're done
finished = False

def finish():
    # ask the user for confirmation?
    global finished
    finished = True
    return


def handle_menu_input(choice):
    handled = True

    if choice == '1':
        print('map needs to be made and shown')
    elif choice == '2':
        print('stats need to be made and assinged to choice 2 in def menu')
    else:
        handled = False

    return handled

def menu():

    finished_menu = False
    while not finished_menu:

        print('Press "1" for map >>> "2" for stats >>> "3" for exit')
        choice = raw_input() # NOTE: changes behaviour in Python 3!

        if handle_menu_input(choice):
            # done
            pass
        elif choice == '3':
            print('You are exiting the menu. Press "M" at any time to return to the menu')
            finished_menu = True
        else:
            print('I did not recognize your command')
            menu()
    return


def userinput():
    print('Press 1 to attack an enemy >>> 2 to search a room >>> 3 to exit game')
    print('Press "M" for menu at any time')
    choice = raw_input() # NOTE: changes behaviour in Python 3!

    if choice == 'm':
        menu()
    elif choice == '1':
        print('attack function here')
    elif choice == '2':
        print('search function here')
    elif choice == '3':
        finish()

    # elif handle_menu_input(choice):
    #     # delegate menu functions?? ..
    #     # do this if you want to see maps anytime without going through the menu?
    #     # otherwise comment this elif block out.
    #     # (Problem is 1, 2 etc are overloaded)
    #     pass
    else:
        print('I did not recognize your command')
    return


def main():
    # main loop
    while not finished:
        userinput()
    return

if __name__ == "__main__":
    main()

撰写回答