我怎么能接受来自用户的输入方向键presses? [英] How can I accept arrow key presses from user input?

查看:111
本文介绍了我怎么能接受来自用户的输入方向键presses?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在做一个RPG风格的游戏,我已经得到了,我正在做的HUD的地步。它会运行理想的方式是这样的:

DPS:18结果
甲:9结果
打开盘点结果
打开门地牢

如何注册箭头键presses选择是打开库存或打开地牢的门?这里是code我到目前为止有:

 :HUD集/ p伤害= DPS:集/ p =铠甲:设置/ P打开=打开地牢的门!设置/对库存=打开库存!


解决方案

下面是在一个批处理脚本涉及PowerShell来间preT箭头键presses一招。

关闭@echo
SETLOCAL集/ P=打一箭头键:< NUL:keyloop
拨打:getKey
如果错误级别37如果没有ERRORLEVEL 41跳转键%ERRORLEVEL%
转到keyloop:key37
左呼应
GOTO:EOF:key38
呼应起来
GOTO:EOF:key39
正确的回声
GOTO:EOF:key40
回响
GOTO:EOF:getKey
PowerShell的退出($ Host.UI.RawUI.ReadKey('NOECHO,IncludeKeyDown')。VirtualKey code)
退出/ B%ERRORLEVEL%


一旦反映下面Klitos Kyriacou的评论,它发生,我认为它会是最好有PowerShell的内部循环,直到钥匙code是一个有效的值。否则,PowerShell中的一个新实例将催生每个键preSS,这将导致延迟,如果一串钥匙无效是pressed。下面是这解决了这一变化:

关闭@echo
SETLOCAL设置getKeyMacro = PowerShell的-noprofile^
    而(-not(37..40)。载有($ X)){^
        $ X = $ Host.UI.RawUI.ReadKey('NOECHO,IncludeKeyDown')。VirtualKey code ^
    } ^
    退出($ X)^
集/ P=打一箭头键:< NUL
%getKeyMacro%
如果错误级别37转到关键%ERRORLEVEL%
REM //其他用户按Ctrl-C。退出优雅。
回声再见。 &安培; GOTO:EOF:key37
左呼应
GOTO:EOF:key38
呼应起来
GOTO:EOF:key39
正确的回声
GOTO:EOF:key40
回响
GOTO:EOF


和这里的有P​​owerShell的转换键code至左,上,右,或下一个可读的字符串的缩写版本。这也许不是一个批处理脚本触发条件逻辑是有用的,但是用它做什么,你会的。

关闭@echo
SETLOCAL设置getKeyMacro = PowerShell的-noprofile^
    而(-not(37..40)。载有($ X)){^
        $ X = $ Host.UI.RawUI.ReadKey('NOECHO,IncludeKeyDown')。VirtualKey code ^
    } ^
    (左,上,右,下)[$ X - 37] ^
集/ P=打一箭头键:< NUL
%getKeyMacro%


只是为了好玩,我写了一个菜单选择脚本,让你用方向键来进行选择。这也说明了一个整洁的方法,使一批次+ PowerShell的混合嵌合体。

<#:批部分
关闭@echo&放大器; SETLOCAL enabledelayedexpansion设置菜单中的[0] =格式C:
设置菜单中的[1] =发送垃圾邮件的老板
设置菜单中的[2] =截断数据库*
设置菜单中的[3] =随机化用户密码
设置菜单中的[4] =下载迪尔伯特
设置菜单中的[5] =哈克本地AD设置选择= 0
设置最大= 5:菜单
CLS
回声=== MENU ===
回声;
对/ L %%我在(0,1,5)做(
    如果%%我EQU!选择! (
        回声 - ^> !菜单中的[%% I]! ^< -
    )其他(
        回音!菜单中的[%% I]!
    )

回声;
回声使用箭头键和回车键来选择。PowerShell的-noprofile -ExecutionPolicy下RemoteSignedIEX((GC'%〜F0')-join \\,\\)
后藤:关键%ERRORLEVEL%:key13(进入)
回声你选择!菜单[%选择%]!
GOTO:EOF:key39(右)
:key40(下)
如果选用%LSS%%最大%设定/选择+ = 1
转到菜单:key37(左)
:key38(向上)
如果选用%GTR%0套/选择 - = 1
转到菜单:PowerShell的混合嵌合体#>
同时,( - 不是((37..40 + 13) - 包含$ X)){
    $ X = $ Host.UI.RawUI.ReadKey('NOECHO,IncludeKeyDown')。VirtualKey code
}
退出($ X)

下面是另一个版本,保持在PowerShell的菜单导航。对此的一个好处是,的PowerShell 不是每个菜单选择改变时重新生成,所以它会在速度较慢的电脑更响应运行。让PowerShell的输出菜单也允许更改选择的背景色。

<#:批部分
关闭@echo&放大器; SETLOCAL enabledelayedexpansion设置菜单中的[0] =格式C:
设置菜单中的[1] =发送垃圾邮件的老板
设置菜单中的[2] =截断数据库*
设置菜单中的[3] =随机化用户密码
设置菜单中的[4] =下载迪尔伯特
设置菜单中的[5] =哈克本地AD设置默认值= 0PowerShell的-noprofile -ExecutionPolicy下RemoteSignedIEX((GC'%〜F0')-join \\`ñ\\)
回声你选择!菜单[%ERRORLEVEL%]!GOTO:EOF
:年底批/开始PowerShell的混合嵌合体#>$菜单= GCI ENV:| ?{$ _名称-match^菜单\\ [\\ D + \\] $} | %{$ _。值}
[INT] $选择= $ ENV:默认
$ FG = $ Host.UI.RawUI.ForegroundColor
$ BG = $ Host.UI.RawUI.BackgroundColor功能getKey {
    同时,( - 不是((37..40 + 13 + 48..53) - 包含$ X)){
        $ X = $ Host.UI.RawUI.ReadKey('NOECHO,IncludeKeyDown')。VirtualKey code
    }
    $ X
}功能菜单{
    CLS
    写主机=== MENU ===`N-f $ FG -b $ BG    为($ I = 0; $项目= $菜单中的[$ i]; $ I ++){
        如果($ I $ -eq选择){
            写主机> $项目<-f $ BG -b黄色
        }其他{
            写主机$ i`:$项-f $ FG -b $ BG
        }
    }    写主机`n选择数字或使用箭头键和回车键来选择。 -f $ FG -b $ BG
    1
}而(菜单){    [INT] $键= getKey    开关($键){        {37}#向左或向上
        38 {如果($选择){$ selection--};破}        {39}#向右或向下
        40 {如果($选择-lt($ menu.length - 1)){$选择++};破}        #号或输入
        默认情况下,如果{(-gt $ 13键){$选择= $键 - 48}; [空](菜单);出口($选择)}
    }
}

I'm making an RPG style game and I've gotten to the point where I'm making the HUD. The ideal way it would run would be like this:

DPS: 18
Armour: 9
Open inventory
Open the Dungeon door

How can register arrow key presses to choose to either open the inventory or open the Dungeon door? Here is the code I have so far:

:HUD

set /p damage=DPS:

set /p armor= Armour:

set /p open=Open the Dungeon door! 

set /p inventory= Open Inventory!

解决方案

Here's a trick involving PowerShell to interpret arrow key presses in a batch script.

@echo off
setlocal

set /P "=Hit an arrow key: "<NUL

:keyloop
call :getKey
if errorlevel 37 if not errorlevel 41 goto key%errorlevel%
goto keyloop

:key37
echo left
goto :EOF

:key38
echo up
goto :EOF

:key39
echo right
goto :EOF

:key40
echo down
goto :EOF

:getKey
powershell "exit($Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown').VirtualKeyCode)"
exit /b %errorlevel%


Upon reflecting on Klitos Kyriacou's comment below, it occurs to me that it'd be better to have PowerShell loop internally until the key code is a valid value. Otherwise, a new instance of PowerShell would be spawned for each keypress, which would cause a delay if a bunch of invalid keys are pressed. Here's a variation which addresses this:

@echo off
setlocal

set "getKeyMacro=powershell -noprofile "^
    while (-not (37..40).contains($x)) {^
        $x = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown').VirtualKeyCode^
    }^
    exit($x)^
""

set /P "=Hit an arrow key: "<NUL
%getKeyMacro%
if errorlevel 37 goto key%ERRORLEVEL%
rem // else user hit Ctrl-C.  Exit gracefully.
echo Bye. & goto :EOF

:key37
echo left
goto :EOF

:key38
echo up
goto :EOF

:key39
echo right
goto :EOF

:key40
echo down
goto :EOF


And here's an abbreviated version which has PowerShell convert the keycode to a human-readable string of left, up, right, or down. It's perhaps not as useful for triggering conditional logic in a batch script, but do with it what you will.

@echo off
setlocal

set "getKeyMacro=powershell -noprofile "^
    while (-not (37..40).contains($x)) {^
        $x = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown').VirtualKeyCode^
    }^
    ('left','up','right','down')[$x - 37]^
""

set /P "=Hit an arrow key: "<NUL
%getKeyMacro%


Just for fun, I wrote a menu selection script letting you make a selection using your arrow keys. This also demonstrates a neat way to make a Batch + PowerShell hybrid chimera.

<# : Batch portion
@echo off & setlocal enabledelayedexpansion

set "menu[0]=Format C:"
set "menu[1]=Send spam to boss"
set "menu[2]=Truncate database *"
set "menu[3]=Randomize user password"
set "menu[4]=Download Dilbert"
set "menu[5]=Hack local AD"

set "selection=0"
set "max=5"

:menu
cls
echo     === MENU ===
echo;
for /L %%I in (0,1,5) do (
    if %%I equ !selection! (
        echo --^> !menu[%%I]! ^<--
    ) else (
        echo     !menu[%%I]!
    )
)
echo;
echo Use the arrow keys and Enter to select.

powershell -noprofile -executionpolicy remotesigned "iex ((gc '%~f0') -join \";\")"
goto :key%errorlevel%

:key13 (enter)
echo You chose !menu[%selection%]!.
goto :EOF

:key39 (right)
:key40 (down)
if %selection% lss %max% set /a selection += 1
goto menu

:key37 (left)
:key38 (up)
if %selection% gtr 0 set /a selection -= 1
goto menu

: PowerShell hybrid chimera #>
while (-not ((37..40 + 13) -contains $x)) {
    $x = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown').VirtualKeyCode
}
exit($x)

Here's another version that keeps the menu navigation within PowerShell. An advantage to this is that powershell isn't respawned each time the menu selection is changed, so it'll run more responsively on slower computers. Letting PowerShell output the menu also allows changing the background color of the selection.

<# : Batch portion
@echo off & setlocal enabledelayedexpansion

set "menu[0]=Format C:"
set "menu[1]=Send spam to boss"
set "menu[2]=Truncate database *"
set "menu[3]=Randomize user password"
set "menu[4]=Download Dilbert"
set "menu[5]=Hack local AD"

set "default=0"

powershell -noprofile -executionpolicy remotesigned "iex ((gc '%~f0') -join \"`n\")"
echo You chose !menu[%ERRORLEVEL%]!.

goto :EOF
: end batch / begin PowerShell hybrid chimera #>

$menu = gci env: | ?{ $_.Name -match "^menu\[\d+\]$" } | %{ $_.Value }
[int]$selection = $env:default
$fg = $Host.UI.RawUI.ForegroundColor
$bg = $Host.UI.RawUI.BackgroundColor

function getKey {
    while (-not ((37..40 + 13 + 48..53) -contains $x)) {
        $x = $Host.UI.RawUI.ReadKey('NoEcho,IncludeKeyDown').VirtualKeyCode
    }
    $x
}

function menu {
    cls
    write-host "   === MENU ===`n" -f $fg -b $bg

    for ($i=0; $item = $menu[$i]; $i++) {
        if ($i -eq $selection) {
            write-host "  > $item <  " -f $bg -b yellow
        } else {
            write-host " $i`: $item" -f $fg -b $bg
        }
    }

    write-host "`nChoose a number or use the arrow keys and Enter to select." -f $fg -b $bg
    1
}

while (menu) {

    [int]$key = getKey

    switch ($key) {

        37 {}   # left or up
        38 { if ($selection) { $selection-- }; break }

        39 {}   # right or down
        40 { if ($selection -lt ($menu.length - 1)) { $selection++ }; break }

        # number or enter
        default { if ($key -gt 13) {$selection = $key - 48}; [void](menu); exit($selection) }
    }
}

这篇关于我怎么能接受来自用户的输入方向键presses?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆