3

我正在用 Python 编写一个简单的基于文本的冒险游戏。无论用户做什么,我都希望某些进程定期发生,大约每 2 分钟一次。例如:让NPC在房间里走动,让人们饥渴难耐,让人们治愈,在战斗中,让战斗继续进行。现在,我正在使用“raw_input”从用户那里获取命令,但这实际上会暂停代码。即使用户只是坐在那里并且没有输入任何内容,我怎样才能让游戏继续进行?

4

5 回答 5

1

我认为通常在这种情况下,您不会有后台进程或线程进行计算。相反,当用户输入一些响应时,会执行时间增量,并根据输入之间的经过时间计算玩家将治愈多少以及战斗事件会发生什么等。也就是说,如果您不想要控制台更新而游戏正在等待用户响应。

编辑:或尝试这样的事情:

import time
import sys

win32 = True
try:
    from msvcrt import kbhit, getch
    print "[+] Running on windows, using msvcrt."
except ImportError:
    print "[+] Not running on windows, attempting unix-like."
    win32 = False

    import termios, fcntl, sys, os
    import select
    fd = sys.stdin.fileno()

    oldterm = termios.tcgetattr(fd)
    newattr = termios.tcgetattr(fd)
    newattr[3] = newattr[3] & ~termios.ICANON & ~termios.ECHO
    termios.tcsetattr(fd, termios.TCSANOW, newattr)

    oldflags = fcntl.fcntl(fd, fcntl.F_GETFL)
    fcntl.fcntl(fd, fcntl.F_SETFL, oldflags | os.O_NONBLOCK)


POLLTIME = 5
done = False
command = ""
while not done:

    sys.stdout.write("\r")
    print("Something happened (polling)%s" % (" " * command.__len__() ))
    sys.stdout.write("Enter command: %s" % command)
    sys.stdout.flush()

    t = time.time()
    if win32:
        while time.time() - t < POLLTIME:
            if kbhit():
                c = getch()
                if ord(c) < 127 and ord(c) > 31:
                    command += c
                    message = "\rEnter command: " + command
                    sys.stdout.write("\r%s" % message)
                if "\r" == c:
                    if "quit\r" == command:
                        done = True
                        break
                    sys.stdout.write("\rThe command was: %s\n" % command)
                    command = ""
                    sys.stdout.write("\rEnter command: %s \b" %command)
                elif "\b" == c:
                    command = command[:-1]
                    sys.stdout.write("\rEnter command: %s \b" %command)
                sys.stdout.flush()
    else:
        while time.time() - t < POLLTIME:
            try:
                c = '\0'                
                if sys.stdin in select.select([sys.stdin], [], [], 0)[0]:
                    c = sys.stdin.readline(1)
                    if ord(c) < 127 and ord(c) > 31:
                        command += c
                        message = "\rEnter command: " + command
                        sys.stdout.write("\r%s" % message)
                if c == "\n":
                    if "quit" == command:
                        done = True
                        break
                    print("\rThe command was: %s" % command)
                    command = ""
                    message = "\rEnter command: " + command
                    sys.stdout.write("\r%s" % message)
                if 127 == ord(c):
                    command = command[:-1]
                    sys.stdout.write("\rEnter command: %s \b" % command)
                sys.stdout.flush()

            except IOError:
                    pass
于 2013-03-29T01:04:09.183 回答
0

There are ways to read user input without pausing the code. It's called "asynchronous I/O" or "non-blocking I/O". One way to do it is to create a separate thread to listen to the user's requests and queue them to process inside your game loop.

This question and its answers explain how to do non-blocking I/O in Python: Non-blocking read on a subprocess.PIPE in python

于 2013-03-29T01:14:50.573 回答
0

我不确定如何在不使用单独线程的情况下做到这一点(并且很容易使用单独的线程)。

但我的观点是:看起来您的基于文本的函数是基于事件/命令的应用程序?即如果用户没有进一步的命令/事件,客户端状态不会改变?不确定您尝试使用定时功能监控什么,但如果您的应用程序尚未基于事件,即从用户执行/发送的事件集中聚合状态,那么您可能希望使您的应用程序成为事件-based,然后您可以摆脱定时功能。希望有所帮助。

于 2013-03-29T11:21:26.493 回答
0

答案是——不要为控制台写实时!如果你想做这个基于文本的,你可能希望切换到 Tkinter。这将允许您单独执行这些操作 - 并在这些周期性事件期间显示文本,使用简单的 .after() 调用来执行它们。

于 2013-03-29T01:00:06.877 回答
0
  1. 对每次输入后的时间进行采样(取决于您是仅对成功的命令执行此操作,还是可选地包括无效的命令)。

  2. 将此时间与之前的样本进行比较,然后除以某个世界刻度间隔。

  3. 遍历每个刻度发生的活动列表(for npc in npcs: npc.move_to_adjacent_posn()例如)。

于 2013-03-29T01:03:19.400 回答