使用tput lines 和tput cols 获取屏幕坐标分辨率, 我的分标率是(39 191),即我们的可移动范围是(1 39)、(1 191)
注: 我的横坐标在39时会超出屏幕范围,因此实际坐标可视情况设定
[root@GipagodHost ~]# tput lines; tput cols 39 191
如果将整个控制台作为“战场”范围,我们可以对控制函数f_turn_*的新坐标计算部分做修改, 以f_f_turn_up(){
v_hp1=${v_tank_head_points[0]} v_hp2=${v_tank_head_points[1]} v_direc=$v_tank_direction f_clean_tank $v_hp1 $v_hp2 $v_direc # 以下代码块为更新后的新坐标计算部分 [[ $v_direc == 'UP' ]] && [[ $v_hp1 -ge 2 ]] && v_hp1=$((v_hp1 - 1)) # 上朝向的坦克,要继续上移,只需要现横向坐标大于等于2即可,因为我们的最小横向坐标为1 [[ $v_direc == 'DOWN' ]] && v_hp1=$((v_hp1 - 2)) # 下朝向的坦克,要上移,横向坐标要减2,横坐标正好处在就坦克位置的尾部横坐标,因此不需要做判断 # 左朝向的坦克,要改变方向朝上,新坦克的头坐标所处的位置正好是就坦克的躯体位置,因此肯定是在活动范围内的,故不需要做任何的判断 [[ $v_direc == 'LEFT' ]] && v_hp1=$((v_hp1 - 1)) && v_hp2=$((v_hp2 + 1)) [[ $v_direc == 'RIGHT' ]] && v_hp1=$((v_hp1 - 1)) && v_hp2=$((v_hp2 - 1)) #同上 f_print_tank $v_hp1 $v_hp2 'UP' v_tank_head_points=($v_hp1 $v_hp2) v_tank_direction='UP' }
以上是我们见整个控制台,即所有坐标作为“战场”, 如果我们划定了一个范围,例如我们的横坐标范围v_range_lines=(10 30) v_range_cols=(40 150),则需要修改对应的判断,如下:
f_turn_up(){ v_hp1=${v_tank_head_points[0]} v_hp2=${v_tank_head_points[1]} v_direc=$v_tank_direction f_clean_tank $v_hp1 $v_hp2 $v_direc [[ $v_direc == 'UP' ]] && [[ $v_hp1 -ge $((v_range_lines[0]+1)) ]] && v_hp1=$((v_hp1 - 1)) #将v_range_lines加入了判断,这样会更通用 [[ $v_direc == 'DOWN' ]] && v_hp1=$((v_hp1 - 2)) [[ $v_direc == 'LEFT' ]] && v_hp1=$((v_hp1 - 1)) && v_hp2=$((v_hp2 + 1)) [[ $v_direc == 'RIGHT' ]] && v_hp1=$((v_hp1 - 1)) && v_hp2=$((v_hp2 - 1)) f_print_tank $v_hp1 $v_hp2 'UP' v_tank_head_points=($v_hp1 $v_hp2) v_tank_direction='UP' }
其他操作函数类似,不再详细赘述,只需要仔细推算即可,最新代码如下:
f_turn_down(){ v_hp1=${v_tank_head_points[0]} v_hp2=${v_tank_head_points[1]} v_direc=$v_tank_direction f_clean_tank $v_hp1 $v_hp2 $v_direc [[ $v_direc == 'UP' ]] && v_hp1=$((v_hp1 + 2)) [[ $v_direc == 'DOWN' ]] && [[ $v_hp1 -lt ${v_range_lines[1]} ]] && v_hp1=$((v_hp1 + 1)) [[ $v_direc == 'LEFT' ]] && v_hp1=$((v_hp1 + 1)) && v_hp2=$((v_hp2 + 1)) [[ $v_direc == 'RIGHT' ]] && v_hp1=$((v_hp1 + 1)) && v_hp2=$((v_hp2 - 1)) f_print_tank $v_hp1 $v_hp2 'DOWN' v_tank_head_points=($v_hp1 $v_hp2) v_tank_direction='DOWN' } f_turn_left(){ v_hp1=${v_tank_head_points[0]} v_hp2=${v_tank_head_points[1]} v_direc=$v_tank_direction f_clean_tank $v_hp1 $v_hp2 $v_direc [[ $v_direc == 'UP' ]] && v_hp1=$((v_hp1 + 1)) && v_hp2=$((v_hp2 - 1)) [[ $v_direc == 'DOWN' ]] && v_hp1=$((v_hp1 - 1)) && v_hp2=$((v_hp2 - 1)) [[ $v_direc == 'LEFT' ]] && [[ $v_hp2 -gt ${v_range_cols[0]} ]] &&v_hp2=$((v_hp2 - 1)) [[ $v_direc == 'RIGHT' ]] && v_hp2=$((v_hp2 - 2)) f_print_tank $v_hp1 $v_hp2 'LEFT' v_tank_head_points=($v_hp1 $v_hp2) v_tank_direction='LEFT' } f_turn_right(){ v_hp1=${v_tank_head_points[0]} v_hp2=${v_tank_head_points[1]} v_direc=$v_tank_direction f_clean_tank $v_hp1 $v_hp2 $v_direc [[ $v_direc == 'UP' ]] && v_hp1=$((v_hp1 + 1)) && v_hp2=$((v_hp2 + 1)) [[ $v_direc == 'DOWN' ]] && v_hp1=$((v_hp1 - 1)) && v_hp2=$((v_hp2 + 1)) [[ $v_direc == 'LEFT' ]] && v_hp2=$((v_hp2 + 2)) [[ $v_direc == 'RIGHT' ]] && [[ $v_hp2 -lt ${v_range_cols[1]} ]] &&v_hp2=$((v_hp2 + 1)) f_print_tank $v_hp1 $v_hp2 'RIGHT' v_tank_head_points=($v_hp1 $v_hp2) v_tank_direction='RIGHT' }
接下来用之前介绍的彩色定位输出圈一个场地作为战场,直接看代码:
f_print_field(){ v_wall_up=$((v_range_lines[0]-1)) #确定场地围墙的坐标范围 v_wall_down=$((v_range_lines[1]+1)) v_wall_left=$((v_range_cols[0]-1)) v_wall_right=$((v_range_cols[1]+1)) for ((i=v_wall_left; i<=v_wall_right; i++)) do echo -e "\033[$v_wall_up;${i}H\033[45m \033[0m" #画上墙 echo -e "\033[$v_wall_down;${i}H\033[45m \033[0m" #画下墙 done for ((i=v_wall_up; i<v_wall_down; i++)) do echo -e "\033[$i;${v_wall_left}H\033[45m \033[0m" #画左墙 echo -e "\033[$i;${v_wall_right}H\033[45m \033[0m" #画右墙 done }
展示:
现在可以随意在圈地内控制坦克移动了, 完整代码和展示见下一章。