Tank Shell游戏编写之四:“画”战场,限制坦克移动范围

使用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
}

展示:

 现在可以随意在圈地内控制坦克移动了, 完整代码和展示见下一章。

猜你喜欢

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