TANK SHELL游戏编写之二:接收键盘按键输入,让坦克动起来

接收键盘录入的指令 read, 有几个参数如下,可以按情况组合使用:

 -p   在用户等待read输入时输出的提示信息
 -t    指定命令等待的时间,超过此时间还未收到用户输入,则终止命令
 -n   字符数  # read命令只接收指定的字符数就开始执行,限制用户输入
 -s    隐藏输入的数据,适用于密码等机密信息的输入情况

接收键盘常规键比较容易, 但如果是上、下、左、右的方向键可能会要费些周折, 因为它们的输出看上去会很怪,例如

[root@GipagodHost ~]# read
^[[A ^[[B ^[[D ^[[C
[root@GipagodHost ~]# 

如果过滤掉前边的“怪”字符,通过常规的A、B、C、D也很容判断,但每次按键到底产生了几个字符呢 ? 看上去是4个,实际上是3个,^[ 其实是一个字符,而且 ^[ 这个字符跟键盘录入的字符是不一样的, 它跟ESC键产生的字符是一样的,验证一下:

[root@GipagodHost ~]# read v_key_up   #读取上方向键的录入
^[[A
[root@GipagodHost ~]# echo ${#v_key_up}
3      #证明是每次按键是3个字符
[root@GipagodHost ~]# read v_key_esc  #读取ESC键的录入
^[
[root@GipagodHost ~]# echo ${#v_key_esc}
1     #证明^[是一个字符
[root@GipagodHost ~]# if [[ ${v_key_up:0:1} == '^[' ]]; then echo yes; fi  #说明^[不是我们键盘录入的普通字符
[root@GipagodHost ~]# if [[ ${v_key_up:0:1} == $v_key_esc ]]; then echo yes; fi  #说明^[是和ESC输出一样的字符
yes

过滤掉‘^[’ 和‘[’ 然后就可以根据字母进行按键的判断,但前者过于特殊,不能运行脚本时先让用户按一次ESC键来获取这个字符; 实际上有一个指令可以生成这个特殊字符,如下:

[root@GipagodHost ~]# v_char=`echo -e "\033"`
[root@GipagodHost ~]# echo $v_char     #该字符常规下不可见

[root@GipagodHost ~]# if [[ ${v_key_up:0:1} == '^[' ]]; then echo yes; fi
[root@GipagodHost ~]# if [[ ${v_key_up:0:1} == $v_char ]]; then echo yes; fi
yes                  #可见 echo -e "\033" 确实可以生成这个特殊字符

这样就可以根据用户的按键录入做出不同的操作了。

f_turn_up(){ echo "UP"; }
f_turn_down(){ echo  "DOWN"; }
f_turn_left(){ echo "LEFT"; }
f_turn_right(){ echo "RIGHT"; }

v_special_char=`echo -e "\033"`
while :
do
    read -s -n 1 v_pressed_key   # 每次只接受一个字符
    v_pressed_key=`echo $v_pressed_key | tr 'a-z' 'A-Z'`   # 将字母进行大小写转换,方便后续做判断处理
    if [[ $v_pressed_key == 'C' ]]       # 通过C键退出循环
    then 
        break
    fi

    if [[ $v_pressed_key == $v_special_char ]]; then   # 首先判断第一个获取的字符是不是^[这个特殊字符, 如果是,那么
        read -s -n 2 v_pressed_key             # 需要再次获取2个字符,因为每按一次方向键输出3个字符
        [[ ${v_pressed_key:1:1} == 'A' ]] && f_turn_up # 通过第二次获取的字符串的第二个字符,很容易就可以判断出用户的按键
        [[ ${v_pressed_key:1:1} == 'B' ]] && f_turn_down
        [[ ${v_pressed_key:1:1} == 'D' ]] && f_turn_left
        [[ ${v_pressed_key:1:1} == 'C' ]] && f_turn_right
    fi
done

 如果使用普通的W、S、A、D进行方向操作,判断起来就更简单了,见以下新增代码部分:

f_turn_up(){ echo "UP"; }
f_turn_down(){ echo  "DOWN"; }
f_turn_left(){ echo "LEFT"; }
f_turn_right(){ echo "RIGHT"; }

v_special_char=`echo -e "\033"`
while :
do
        read -s -n 1 v_pressed_key
        v_pressed_key=`echo $v_pressed_key | tr 'a-z' 'A-Z'`
        if [[ $v_pressed_key == 'C' ]]
        then
                break
        fi

        if [[ $v_pressed_key == $v_special_char ]]; then
                read -s -n 2 v_pressed_key
                [[ ${v_pressed_key:1:1} == 'A' ]] && f_turn_up
                [[ ${v_pressed_key:1:1} == 'B' ]] && f_turn_down
                [[ ${v_pressed_key:1:1} == 'D' ]] && f_turn_left
                [[ ${v_pressed_key:1:1} == 'C' ]] && f_turn_right
        fi
     #新增代码部分
        [[ $v_pressed_key = 'W' ]] && f_turn_up
        [[ $v_pressed_key = 'S' ]] && f_turn_down
        [[ $v_pressed_key = 'A' ]] && f_turn_left
        [[ $v_pressed_key = 'D' ]] && f_turn_right

done

效果:

接下来该移动坦克了~

猜你喜欢

转载自www.cnblogs.com/gipagod/p/9115906.html
今日推荐