开发者

bat game. Adding a timer with set /p

开发者 https://www.devze.com 2023-04-11 13:07 出处:网络
Im making a .bat game, and currently when putting in a command the code is set /p command= What i want to know is 开发者_StackOverflow社区if you can somehow have a time limit for inputting the com

Im making a .bat game, and currently when putting in a command the code is

set /p command=

What i want to know is 开发者_StackOverflow社区if you can somehow have a time limit for inputting the commands. For example if your fighting a guard, and you haven't put a command in for say 5 seconds, the guard attacks.

This is not something of dire need, I am just wondering more about the limitations im bound to, and i think i know the anawer anyway (the answer being that you cant)

Thanks


It can also be done with batch only.

You can create a second thread (in the same window) with start /b.
If this thread wait with set /p for user input, the main thread is not affected.
This sample will wait for 5 seconds for userinput, if the user inputs text it is moved into a file, so the first thread can access it.

@echo off
setlocal EnableDelayedExpansion
if "%1" NEQ "" goto %1

del enter.tmp 2>nul >nul
start /b cmd /c %0 :secondThread

:FirstThread
set n=0
echo Enter Text (5 seconds timeout):

:loop
set /a n+=1
ping -n 2 localhost > nul
if !n! LSS 5 (
    if not exist entER.tmp goto :loop
    < Enter.tmp (
        set /p input=
    )
    echo !input!
) ELSE (
    echo Timeout for input
)

exit /b

:secondThread
set /p var=
> enter.tmp echo !var!
exit /b


It is possible to mix a batch file with something else, for example c#. As .net is installed on almost all windows pc nowadays, that should not be a big problem.

In the example below there is a 3 second delay where the user can enter some input. If nothing is entered, the program continues, but %result% will be empty.

/* 2>NUL
@echo off 
REM cls
set WinDirNet=%WinDir%\Microsoft.NET\Framework
IF EXIST "%WinDirNet%\v2.0.50727\csc.exe" set csc="%WinDirNet%\v2.0.50727\csc.exe"
IF EXIST "%WinDirNet%\v3.5\csc.exe" set csc="%WinDirNet%\v3.5\csc.exe"
IF EXIST "%WinDirNet%\v4.0.30319\csc.exe" set csc="%WinDirNet%\v4.0.30319\csc.exe"
%csc% /nologo /out:"%~0.exe" %0



echo enter some text:

set result=
for /F "tokens=*" %%a in ('"%~0.exe"') do set result=%%a

echo you have entered:%result%




del "%~0.exe"
goto :eof
*/
using System;
using System.Text;
using System.IO;
using System.Threading;

class Program
{
    static void Main (string[] args)
    {
        byte[] buffer=new byte[80];

        using (Stream s = Console.OpenStandardInput ()) {
            ManualResetEvent e=new ManualResetEvent(false);
            s.BeginRead (buffer, 0, buffer.Length, x => e.Set(), null);

            e.WaitOne (3000);
        }

        Console.WriteLine (Encoding.UTF8.GetString (buffer));
    }
}

This way you can program your batch file, and use c# for everything what is not possible in batch files. Note there are several improvements possible to this code.

See How to add a Timeout to Console.ReadLine()? for improvements of the c# code.

(Source of embedded c# code)


If commands have a unique starting letter, maybe you can consider using the CHOICE command? (Available again in Windows 7)


Batch file capabilities may be increased with the aid of auxiliary programs, some of wich may be very simple if they are written in assembly language:

@ECHO OFF
(
ECHO A100
ECHO MOV AH,B
ECHO INT 21
ECHO MOV AH,4C
ECHO INT 21
ECHO/
ECHO RCX
ECHO 8
ECHO W
ECHO Q
) | DEBUG CHKKEY.COM

Previous Batch file creates the 8-bytes long CHKKEY.COM auxiliary program that check if a key was pressed and return an ERRORLEVEL of 255 if so, or zero if not. For example:

:waitforkey
echo Waiting for a key to be pressed...
chkkey
if not errorlevel 1 goto waitforkey
echo A key was pressed!

If you have not the DEBUG.COM program, you may get it in the web. This way, to wait for a key for 5 seconds:

for /F "tokens=3 delims=:." %%a in ("%time%") do set /A second=%%c+5
if %second% geq 60 set /A second-=60
:waitforkey
for /F "tokens=3 delims=:." %%a in ("%time%") do if %%c == %second% goto timeexceeded
chkkey
if not errorlevel 1 goto waitforkey
set /P command=

If you change the B value by 1 in MOV AH,B instruction, a key is read and its ASCII code is returned in ERRORLEVEL; this feature allows to read a single keystroke and process it immediately. If the value is 8, the key read is not displayed in the screen; this allows to process any key of the keyboard even function and special keys that return two values: the first one is zero (that identify a special key) and the second one identify the key pressed. For example, F1 key returns 0 and 59.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号