首页 > 解决方案 > 如何通过按“q”使批处理文件随时提供菜单,而不必一遍又一遍地编写它?

问题描述

我有一个正在创建的 RPG 游戏屏幕:

:OBJ1
CLS
echo.
echo.   
echo The tiger rolls down the steep hill...
echo What do you do?
echo.
echo.
CHOICE /c abc /n /m ">"
IF %errorlevel%==1 (GOTO ATTACK)
IF %errorlevel%==2 (GOTO WALK)
IF %errorlevel%==3 (GOTO COLLECT)

如您所知,一旦您选择了一个选项,它就会转到另一个屏幕。在该屏幕之后,您选择另一个选项。还有一个。我有许多类似的代码,每个都有不同的情况。我想知道是否有一种方法可以全局检测何时按下字母“q”,而不是为每种情况添加一个选项“q”来暂停。

因此,无论屏幕如何,如果您按“q”,它会立即进入暂停菜单。

非常感谢 :)

标签: batch-file

解决方案


这是一个小演示:

@ECHO Off
SETLOCAL
SET Posx=15
SET Posy=15
SET Posz=0
CALL :choose awc "ATTACK:Attack" "WALK:Walk" "COLLECT:Collect"
ECHO Jump to %jumpto% as choice made was %choicemade%
CALL :choose eds "EAT:Eat Ration" "DRINK:Drink Potion" "SLEEP:Sleep"
ECHO Jump to %jumpto% as choice made was %choicemade%
CALL :choose news "NORTH:Go North" "EAST:Go East" "SOUTH:Go South" "WEST:Go West"
ECHO Jump to %jumpto% as choice made was %choicemade%
ECHO ---------------------------------------------------
CALL :choose news "GO 0 1:Go North" "GO 1 0:Go East" "GO -1 0:Go West" "GO 0 -1:Go South"
ECHO CALL :%jumpto% as choice made was %choicemade%
CALL :%jumpto%
CALL :choose news "GO 0 1:Go North" "GO 1 0:Go East" "GO -1 0:Go West" "GO 0 -1:Go South"
ECHO CALL :%jumpto% as choice made was %choicemade%
CALL :%jumpto%
CALL :choose newsd "GO 0 1:Go North" "GO 1 0:Go East" "GO -1 0:Go West" "GO 0 -1:Go South" "GO 0 0 1:Down Stairs"
ECHO CALL :%jumpto% as choice made was %choicemade%
CALL :%jumpto%

GOTO :EOF

:: Move in a direction
:GO
ECHO Current position: %posx% %posy% AT level %posz%
SET /a posx+=%1
SET /a posy+=%2
SET /a posz+=%3+0
ECHO Current position: %posx% %posy% AT level %posz%
:: set ERRORLEVEL to 0
CD .
CALL :enc_%posx%_%posy%_%posz% 2>nul

GOTO :eof

:: Encounter at 16,14,1
:enc_16_14_1
ECHO it's dark
GOTO :eof

:choose
SETLOCAL enabledelayedexpansion
SET "params=%*"
SET "choices=q%1qx"

:chooseloop
SET /a choicemade=0
FOR %%Z IN (%params% " :Pause" "ENDGAME:Exit Game") DO (
 FOR /f "tokens=1*delims=:" %%X IN ("%%~Z") DO (
  IF !choicemade! neq 0 (
   CALL ECHO %%choices:~!choicemade!,1%% %%Y
   SET "jumpto!choicemade!=%%X"
  )
  SET /a choicemade +=1
 )
)
choice /c %choices:~1% /n /m ">"
SET "jumpto=!jumpto%errorlevel%!"
SET "choicemade=!choices:~%errorlevel%,1!"
IF NOT "%choicemade%"=="q"  GOTO exitchoose
:: pause code

PAUSE

GOTO chooseloop

:exitchoose
endlocal&SET "jumpto=%jumpto%"&SET "choicemade=%choicemade%"
GOTO :eof

我不明白你为什么需要一个pause函数。在任何情况下,批处理都会暂停,直到您操作该键。

:choose子例程接受n参数。第一个是有效键的列表(q 和 x 由例程添加),其余"destination-data: prompt-text"的按指定有效键的顺序排列。

该变量choices设置为指定的选项,在末尾加上q和(因为这些总是操作)加上一个额外的开头。我把这个额外的字符放进去是因为批处理子串从“字符 0”开始计算,而建立的从.xqerrorlevelchoice1

:chooseloop回显一个 1 个字符的子字符串,choices具体取决于choicemade哪个只是一个计数器。我们不想在 中显示第一个参数params,因此从 开始choicemade=1,显示从第 th 个字符开始的单字符字符串choicemade和菜单文本,然后将jumpto1..设置jumpton为目标数据。

做出选择,设置errorlevel

用于errorlevel根据需要设置为..jumpto中的目标数据,并设置为实际的选择字母。jumpto1jumptonchoicemade

现在,如果选择字母不是q,我们需要返回给调用者,但如果是, q我们执行暂停,并返回:chooseloop以重复菜单生成和choice进入。

如果选择字符不是q,我们只需终止本地环境并为主例程设置jumptochoicemade准备。

如果您运行演示,您会发现jumpto包含目标数据。你可以直接使用它,或者你可以有点偷偷摸摸。

请注意,从第 4 次演示开始,CALL :%jumpto%执行。该:GO例程接受两个参数(可选 3)来在地图上移动 x,y[,z]。

:GO例程只是将第一个参数添加到posx,将第二个参数添加到posy. 第三个参数可能存在也可能不存在,因此0添加以便set /a满足 for 的语法。我已经在 x,y,z 位置之前和之后进行了报告。

现在已经移动,我们设置errorlevel0usingcd .然后尝试调用:enc_%posx%_%posy%_%posz%即一个名为 的内部子程序enc_thecubeyouarelocatedin。这可能存在也可能不存在。如果存在,它将被执行。如果不是,cmd将简单地发出一条错误消息,可以通过2>nul和 设置errorlevel为来抑制1。请注意,这goto nonexistenetlabel将退出程序并生成令人讨厌的消息。

这样,可以处理特定位置的特价,但最终它会全部返回执行的原始位置call :GO...

如果您正在寻找加载/保存游戏的方法,请在此处尝试:https ://stackoverflow.com/a/50639536/2128947


推荐阅读