所以我决定学习批处理,我试图编写一个小型RPG /冒险游戏,该游戏是为办公室里的RPG鼻烟进行叙事驱动的。所以我遇到了一些问题并且有一些问题。
@echo off
color F0
title The Kingdom of Kovalor
type Titlescreen.txt
pause >nul
goto MainMenu
:MainMenu
cls
type mainmenu.txt
echo.
echo Type in option and press Enter.
Set /p menu=
if "%menu%" equ "new game" goto NewGame
if %menu% equ credits goto Credits
if "%menu%" equ "load game" goto LGame
echo Try again.
if %menu% neq new game goto MainMenu
if %menu% neq credits goto MainMenu
if %menu% neq load game goto MainMenu
pause >nul
:Credits
cls
echo Made by XXXXXXXXX
echo.
echo.
echo Press any key to return to Main Menu.
pause >nul
goto MainMenu
:NewGame
cls
echo What is your name, adventurer?
echo.
Set /p name=
echo.
echo %name%, are you a man or woman?
echo.
Set /p sex=
goto Stats
:SaveGame
@echo @ECHO OFF > save%name%.bat
@echo SET name=%name% >> save%name%.bat
@echo SET sex=%sex% >> save%name%.bat
@echo SET playerHP=%playerHP% >> save%name%.bat
@echo SET playerATK=%playerATK% >> save%name%.bat
@echo SET playerDEF=%playerDEF% >> save%name%.bat
@echo SET playerLVL=%playerLVL% >> save%name%.bat
echo.
echo Game saved correctly.
echo Press any key to continue.
pause >n
exit
:LGame
cls
echo.
echo What's your name?
echo.
Set /p name=
echo Load successful.
pause >nul
exit
:Stats
cls
set /a playerHP = 25
set /a playerATK = 5
set /a playerDEF = 0
set /a playerLVL = 1
echo These are your stats.
echo Health, when it depletes, you die. %playerHP%
echo Attack. The ammount of damage you deal. %playerATK%
echo Defense. Armor which reduces the damage you take. %playerDEF%
echo Level dictates the experience you have as an adventurer. %playerLVL%
echo You can improve these as you go.
echo For now you have no weapons nor armor.
pause >nul
if %sex% equ man goto StartAdventureMan
if %sex% equ woman goto StartAdventureWoman
:StartAdventureMan
cls
echo Kovalor wasn't always like this. There was a time where one could
echo walk around town without being disturbed. The so-called king has
echo placed himself on the throne with the help of twisted creatures.
echo.
echo TUTORIAL *Press Space Bar to continue narrative.*
pause >nul
echo.
echo There have been talks about a coup or silent assasinations but
echo nothing has been proven to be but a rumor.
echo Nonetheless, the King must fall.
pause >nul
echo.
echo %name% got out of bed that morning with a headache born from heavy
echo drinking the previous night. He got dressed and left for the tool
echo shed outside his house. The cold early-spring air snipping at his
echo bare arms. His best hoe laid on the floor.
pause >nul
goto PickUpHoe
:StartAdventureWoman
cls
echo Kovalor wasn't always like this. There was a time where one could
echo walk around town without being disturbed. The so-called king has
echo placed himself on the throne with the help of twisted creatures.
echo.
echo TUTORIAL *Press Space Bar to continue narrative.*
pause >nul
echo.
echo There have been talks about a coup or silent assasinations but
echo nothing has been proven to be but a rumor.
echo Nonetheless, the King must fall.
pause >nul
echo.
echo %name% got out of bed that morning with a headache born from heavy
echo drinking the previous night. She got dressed and left for the tool
echo shed outside her house. The cold early-spring air snipping at her
echo bare arms. Her best hoe laid on the floor.
pause >nul
goto PickUpHoe
:PickUpHoe
echo.
echo TUTORIAL *Type take followed by an object and press enter in order
echo to pick it up and add it to your inventory.*
set /p action1=
if "%action1%" neq "take hoe" echo TUTORIAL *Type take hoe followed by Enter.*
goto PickUpHoe
echo *Picked up hoe.*
pause >nul
goto SaveTutorial
:SaveTutorial
echo.
echo TUTORIAL *You can save progress whenever you can type by typing Save Game.*
echo *Try saving now.*
Set /p action2=
if "%action2%" equ "Save Game" goto SaveGame
if "%action2%" neq "Save Game" goto SaveTutorial
pause >nul
exit
正如您可能注意到的,这并不是太过分了。当我添加代码时,我正在测试它。 所以问题是我无法获得LGame方法(我不知道你是如何批量调用的,一般是编程的初学者,所以请耐心等待)。目前它只是打算打印消息,但如果我运行它只是崩溃。其他一切都正常。
现在提问。
并且,如果可能的话,库存系统上的一些指针和暂停菜单,您可以随时调出,然后返回之前的屏幕。一般都是指针吗?
答案 0 :(得分:0)
首先,我建议您在浏览器中添加书签:
您可以通过在命令提示符窗口中运行/?
作为参数的命令来获取每个Windows命令的帮助,例如if /?
,set /?
,...
其次,我建议避免使用echo.
并使用echo/
来输出空行。请查看DosTips论坛主题ECHO. FAILS to give text or blank line - Instead use ECHO/以获取解释。
第三,在Symbol equivalent to NEQ, LSS, GTR, etc. in Windows batch files上阅读我的答案。比较运算符EQU
用于整数比较,不用于字符串比较。如果Windows命令解释器识别出要比较的两个参数中的一个不是整数,它也可用于字符串比较作为后退。但更好的方法是使用==
来比较两个字符串。
第四,如果用户应该选择其中一个选项,请不要使用set /p
。在提示用户输入字符串并将其分配给环境变量时,必须考虑多个事实:
在使用set /P "MyVar=Your choice: "
时,如果用户有意或者错误地按下 RETURN 或 ENTER MyVar >。这意味着如果在用户提示之前尚未定义环境变量MyVar
,则在用户提示仅按 RETURN 键完成后仍未定义环境变量MyVar
。如果在用户提示之前已经定义了set /P
,那么在用户只按 RETURN 或 ENTER 的情况下,它会保持其值不被修改。
用户可以自由键入@echo on
:MainMenu
@set /P "menu=Your choice: "
if "%menu%" == "new game" goto NewGame
if %menu% == credits goto Credits
goto MainMenu
:NewGame
@echo Start a new game ...
goto :EOF
:Credits
@echo Made by XXXXXXXXX
提示的任何字符串。批处理文件编写器无法控制用户真正输入的内容。因此批处理文件编写者必须考虑到用户错误地输入或故意输入一个字符串,这可能导致批处理文件执行退出,因为语法错误或者它的定义完全不同。
一个简单的例子:
echo on
此顶部带有echo off
而不是if == credits goto Credits
的批处理文件是从命令提示符窗口中启动的,用于调试目的。
首次运行时,在用户提示符下按 RETURN 。 Windows命令解释程序退出批处理,因为在执行 IF 命令之前预处理了第二个 IF 条件:
cmd.exe
显然缺少第一个参数。 menu
遇到此语法错误并退出批处理并显示相应的错误消息。原因是环境变量credits
未在用户提示之前定义,并且在用户提示后仍未定义。
在命令提示符窗口menu
内第二次运行批处理文件时,批处理文件按预期工作。
在同一命令提示符窗口中第三次运行批处理文件时,在用户提示符下按 RETURN 。批处理文件再次打印信用。为什么?环境变量@echo on
:MainMenu
@set "menu=credits"
@set /P "menu=Your choice: "
if /I "%menu%" == "new game" goto NewGame
if /I "%menu%" == "credits" goto Credits
goto MainMenu
:NewGame
@echo Start a new game ...
goto :EOF
:Credits
@echo Made by XXXXXXXXX
仍然是使用该字符串从第二个批处理文件执行定义的,并且在按 RETURN 时未修改变量。
好的,我们将示例批处理文件修改为:
menu
这已经更好了,因为现在环境变量credits
始终预定义为值menu
。因此,如果用户什么都不输入,则显示积分。此外,先前运行的变量"
的值不再对批处理文件的执行产生影响。字符串比较现在不区分大小写。
但这真的是安全的,现在也不安全吗?
不,不是。用户仍然可以错误输入错误的字符串。
例如,用户输入错误2
而不是"
,这在德语键盘上很容易,因为 CapsLock + 2 或 Shift + 2 导致输入if /I """ == "new game" goto NewGame
。现在预处理后的第一个 IF 命令行是:
" == "" call dir "%USERPROFILE%\Desktop" & rem
这又是一个无效的命令行,由于语法错误导致批处理文件处理退出。
让我们假设用户在提示符下输入字符串:
if /I "" == "" call dir "%USERPROFILE%\Desktop" & rem " == "new game" goto NewGame
注意:最后有一个空格。
第一个 IF 条件由Windows命令解释程序预处理为:
@echo on
:MainMenu
@setlocal EnableDelayedExpansion
@set "menu=credits"
@set "Label=MainMenu"
@set /P "menu=Your choice: "
if /I "!menu!" == "new game" set "Label=NewGame"
if /I "!menu!" == "credits" set "Label=Credits"
endlocal & goto %Label%
:NewGame
@echo Start a new game ...
goto :EOF
:Credits
@echo Made by XXXXXXXXX
可以看出批处理文件现在在 IF 条件下执行完全没有在批处理文件中写入的命令。
如何让用户提示失败安全?
至少在评估用户输入字符串的代码周围使用延迟环境变量扩展。
set /P
现在,用户输入字符串不再修改Windows命令解释程序执行的命令行。因此,由于用户输入引起的语法错误,不再可能退出批处理文件处理。并且批处理文件永远不会执行未在批处理文件中写入的命令。
但对于简单的选择菜单choice,有一个比@echo off
:MainMenu
cls
echo/
echo 1 ... Start a new game
echo 2 ... Load a game
echo C ... Show credits
echo E ... Exit
echo/
%SystemRoot%\System32\choice.exe /C 12CE /N /M "Your choice: "
if errorlevel 4 goto :EOF
if errorlevel 3 goto Credits
if errorlevel 2 goto LoadGame
:NewGame
echo Start a new game ...
goto :EOF
:Credits
echo Made by XXXXXXXXX
echo/
pause
goto MainMenu
:LoadGame
echo Loading game ...
goto :EOF
更好的命令。
choice
用户不再有自由输入批处理文件编写器未定义的内容。用户按下 1 , 2 , c , Shift + C 后立即继续批处理文件,< kbd> e 或 Shift + E 。除{kbd> Ctrl + C 外,ERRORLEVEL
忽略其他所有内容。
环境变量choice
有四个选项,在cmd.exe
终止后返回1到4作为退出代码调用if errorlevel X
时,其值始终为1到4。
注意:choice
表示 IF GREATER OR EQUAL X 。因此,始终需要从命令ERRORLEVEL
的最高退出代码开始。
由于分配给@echo off
:MainMenu
cls
echo/
echo 1 ... Start a new game
echo 2 ... Load a game
echo C ... Show credits
echo E ... Exit
echo/
choice.exe /C 12CE /N /M "Your choice: "
goto Option%ERRORLEVEL%
:Option1
echo Start a new game ...
goto :EOF
:Option2
echo Loading game ...
goto :EOF
:Option3
echo Made by XXXXXXXXX
echo/
pause
goto MainMenu
:Option4
的退出代码众所周知,因此可以在较大的菜单上使用适当的标签进一步优化代码:
exit
使用命令 CHOICE 可以使选择菜单变得非常简单。
第五,不要在没有选项/B
的批处理文件中使用命令exit
。没有/B
的{{1}}总是立即退出整个命令流程,独立于cmd.exe
启动/K
到保持命令进程运行并且控制台窗口在运行后打开批处理文件,例如明确打开命令提示符窗口并运行批处理文件,或者在cmd.exe
以/C
启动关闭后执行批处理文件因任何原因完成比如双击批处理文件。
独立于启动选项/K
或/C
并独立于调用层次结构的命令进程退出不适合在命令提示符窗口中调试批处理文件。
另请参阅Where does GOTO :EOF return to?上的答案