我正在开发一个用PHP编写并在控制台中运行的游戏.回想旧的MUD和其他基于文本的游戏,甚至是一些ASCII艺术!
无论如何,我正在尝试做的事情是在接受用户输入的同时发生事情.
例如,假设这是一个双人游戏,而玩家1正在等待玩家2进行移动.只需收听消息即可轻松完成.
但是如果玩家1想要改变一些选择呢?如果他们想要查看有关游戏状态方面的详细信息怎么办?承认游戏怎么样?在等待对手进行移动时,玩家可能想做很多事情.
不幸的是,我现在最好的是Ctrl C完全杀死了程序.然后另一个玩家被挂起,直到连接断开.哦,游戏完全丢失了.
我用fgets(STDIN)获得用户输入.但这会阻止执行直到收到输入(这通常是一件好事).
这样的控制台程序是否可以同时处理输入和输出?或者我应该只看一些其他界面?
解决方法:
简而言之,PHP不是为此而构建的,但您可能会从these extensions之一获得一些帮助.我不确定它们有多彻底,但您可能真的想要使用文本UI库. (实际上你可能不想为此使用PHP.)
总而言之,您需要逐个字符地从STDIN获取非阻塞输入.不幸的是,大多数终端都是从PHP的角度来缓冲的,因此在按下enter之前你不会得到任何东西.
如果你在终端上运行stty -icanon(或你的操作系统等效)来禁用缓冲,那么下面的短程序基本上可行:
<?PHP
stream_set_blocking(STDIN, false);
$line = '';
$time = microtime(true);
$prompt = '> ';
echo $prompt;
while (true)
{
if (microtime(true) - $time > 5)
{
echo "\nTick...\n$prompt$line";
$time = microtime(true);
}
$c = fgetc(STDIN);
if ($c !== false)
{
if ($c != "\n")
$line .= $c;
else
{
if ($line == 'exit' || $line == 'quit')
break;
else if ($line == 'help')
echo "Type exit\n";
else
echo "Unrecognized command.\n";
echo $prompt;
$line = '';
}
}
}
(它依赖于本地回显,可以在键入字符时打印它们.)
如你所见,我们只是永远地循环.如果存在某个字符,请将其添加到$行.如果按下enter,则处理$line.与此同时,我们每5秒钟就会发出一声,只是为了表明我们在等待输入时可能会做其他事情. (这将消耗最大的cpu;你必须发出一个sleep()来解决这个问题.)
这本身并不是一个实际的例子,但也许会让你思考正确的方向.