• 083_贪吃蛇Shell跑马灯版 2022最新代码


    效果图:

    代码:

    #!/bin/bash
    
    # 基础知识
    
    # 前景色(文字颜色): echo -e "\e[${num}m有颜色的文字"
    #   39默认前景色   30黑色  31红色         32绿色   33黄色     34蓝色          35品红   36青色   37浅灰
    #       90深灰色   91红灯  92浅绿色  93淡黄色   94浅蓝   95浅洋红色   96浅青色  97白色
    
    # 背景色: echo -e "\e[$(num)m有背景颜色的文字"
    #   49默认背景颜色     40黑色       41红色          42绿色   43黄色         44蓝色         45品红       46青色      47浅灰
    #        100深灰色    101红灯       102浅绿色       103淡黄色  104浅蓝    105浅洋红色     106浅青色      107白色
    
    # 属性:
    #   \e[0m             关闭所有属性
    #   \e[1m             设置高亮度
    #   \e[4m             下划线
    #   \e[5m             闪烁
    #   \e[7m             反显
    #   \e[8m             消隐
    #   \e[30m -- \e[37m 设置前景色
    #   \e[40m -- \e[47m 设置背景色
    #   \e[nA             光标上移n行
    #   \e[nB             光标下移n行
    #   \e[nC             光标右移n行
    #   \e[nD             光标左移n行
    #   \e[y;xH           设置光标位置
    #   \e[2J             清屏
    #   \e[K              清除从光标到行尾的内容
    #   \e[s              保存光标位置
    #   \e[u              恢复光标位置
    #   \e[?25l           隐藏光标
    #   \e[?25h           显示光标
    
    # 属性示例:
    #   1    粗体高亮                    echo -e "\e[1mBold"
    #   2    变暗                        echo -e "\e[2mDim"
    #   4    下划线                        echo -e "\e[4mUnderlined"
    #   5    闪烁                          echo -e "\e[5mBlink"
    #   7    反转 (反转前景色和背景色)      echo -e "\e[7minverted"
    #   8    隐藏(对密码有用)             echo -e "\e[8mHidden"
    
    # 结合:
    #   echo -e "\e[41;32m文字\e[0m"                      红色背景绿色字并清除属性
    #   echo -e "\e[1;3H*\e[0m"                           第一行第三列输出一个*
    #   echo -e "\e[3;3H\e[44;31m*\e[0m"                  第三行第三列输出一个蓝色背景红色字
    #   echo -e "\e[5;31;42m文字\e[0m"                    闪烁、红色背景、绿色的文字并清除属性
    #   echo -e "\e[3;3H\e[5;31;42m*************\e[0m"    第三行第三列输出一排闪烁的星
    
    # 键盘控制 w s a d
    # 退出游戏 q
    
    # 地图大小 长宽可以自由改动
    declare -i MAP_WIDTH=60 
    declare -i MAP_HIGHT=20
    
    # 地图起始位置(左上角的开始绘制的位置, 可以自由改动)
    declare -i MAP_X=20
    declare -i MAP_Y=5
    
    # 定义 蛇头的起始位置x,y 及 蛇初始化长度4
    declare -i X=30
    declare -i Y=30
    declare -i LENGTH=4
    # 舌头蛇身的坐标点
    declare -a X_ARR=()
    declare -a Y_ARR=()
    
    # 食物的坐标
    declare -i RANDOM_X=0
    declare -i RANDOM_Y=0
    
    # 跑马灯的开始颜色
    declare -i COLOR_INDEX=15
    
    # 初始化 蛇 出生移动方向
    DIR='d'
    score=0
    
    # 游戏结束恢复环境
    function end_of_game() {
      kill -9 $!
      echo -e "\e[0m"
      echo -e "\e[?25h"
      exit 1
    }
    
    # 生成边界
    function init_map() {
      # 两横
      for i in $(seq ${MAP_X} $((${MAP_X} + ${MAP_WIDTH}))); do
        echo -e "\e[${MAP_Y};${i}H@\e[0m"
        echo -e "\e[$((${MAP_Y} + ${MAP_HIGHT}));${i}H@\e[0m"
      done
      # 两竖
      for j in $(seq ${MAP_Y} $((${MAP_Y} + ${MAP_HIGHT}))); do
        echo -e "\e[${j};${MAP_X}H@\e[0m"
        echo -e "\e[${j};$((${MAP_X} + ${MAP_WIDTH}))H@\e[0m"
      done
    }
    
    # 跑马灯效果
    function init_map_lamp() {
      while true :; do
        let COLOR_INDEX=15
    
        for i in $(seq ${MAP_X} $((${MAP_X} + ${MAP_WIDTH}))); do
          let COLOR_INDEX++
          sleep 0.003
          echo -e "\e[38;5;${COLOR_INDEX}m\e[${MAP_Y};${i}H@\e[0m"
        done
    
        for j in $(seq ${MAP_Y} $((${MAP_Y} + ${MAP_HIGHT}))); do
          let COLOR_INDEX++
          sleep 0.003
          echo -e "\e[38;5;${COLOR_INDEX}m\e[${j};$((${MAP_X} + ${MAP_WIDTH}))H@\e[0m"
        done
    
        for ((k = $((${MAP_X} + ${MAP_WIDTH})); k >= ${MAP_X}; k--)); do
          let COLOR_INDEX--
          sleep 0.003
          echo -e "\e[38;5;${COLOR_INDEX}m\e[$((${MAP_Y} + ${MAP_HIGHT}));${k}H@\e[0m"
        done
    
        for ((m = $((${MAP_Y} + ${MAP_HIGHT})); m >= ${MAP_Y}; m--)); do
          let COLOR_INDEX--
          sleep 0.003
          echo -e "\e[38;5;${COLOR_INDEX}m\e[${m};${MAP_X}H@\e[0m"
        done
      done
    }
    
    # 初始化蛇
    function draw_snake() {
      clear
    
      # 生成蛇身
      for ((i = 1; i < ${LENGTH}; i++)); do
        echo -e "\e[${Y_ARR[$i]};${X_ARR[$i]}H*\e[0m"
      done
    
      # 生成蛇头
      echo -e "\e[${Y_ARR[$i]};${X_ARR[$i]}H$\e[0m"
    
      # 随机生成食物
      echo -e "\e[5;32m\e[${RANDOM_Y};${RANDOM_X}H#\e[0m"
    
      # 生成地图
      init_map
    
      # 输出蛇头、食物的起位置 打印分数
      echo -e "\e[$(($MAP_Y + $MAP_HIGHT + 2));${MAP_X}H\e[32mSnake:${X},${Y}\e[0m\e[0m"
      echo -e "\e[$(($MAP_Y + $MAP_HIGHT + 3));${MAP_X}H\e[32mFood :${RANDOM_X},${RANDOM_Y}\e[0m\e[0m"
      echo -e "\e[$(($MAP_Y + $MAP_HIGHT + 4));${MAP_X}H\e[33mScore:${score}\e[0m\e[0m"
    }
    
    # 生成食物
    function gen_food() {
      let flag=1
      while [ $flag -eq 1 ]; do
        # 0-58 + 21
        let RANDOM_X=$(($RANDOM % $((${MAP_WIDTH} - 1)) + $((${MAP_X} + 1))))
        # 0-18 + 6
        let RANDOM_Y=$(($RANDOM % $((${MAP_HIGHT} - 1)) + $((${MAP_Y} + 1))))
        # 生成与蛇身+蛇头 坐标不相等的 食物坐标
        for ((i = 0; i < ${LENGTH}; i++)); do
          # 如果相等 退出当前循环,重新 while循环,i又从1开始
          if [[ ${X_ARR[$i]} -eq ${RANDOM_X} && ${Y_ARR[$i]} -eq ${RANDOM_Y} ]]; then
            break
          fi
        done
        # 只有生成的食物坐标与蛇头+蛇身坐标完全不相等时
        if [ $i -eq ${LENGTH} ]; then
          flag=0
        fi
      done
    }
    
    function init() {
      clear
      # 清除所有属性
      echo -e "\e[0m"
      # 隐藏光标
      echo -e "\e[?25l"
    
      # 生成蛇的初始化坐标
      for i in $(seq 5); do
        # 在地图的中点取五个点初始化蛇的位置
        let pos_x=$((${MAP_WIDTH} / 2 - 2 + ${i}))+${MAP_X}
        let pos_y=$(((${MAP_Y} + ${MAP_HIGHT}) / 2))+${MAP_Y}
        X_ARR+=($pos_x)
        Y_ARR+=($pos_y)
      done
      X=$pos_x
      Y=$pos_y
    
      # 生成食物
      gen_food
    }
    
    function move() {
      case $DIR in
      "w") Y=$Y-1 ;; # 往上移动
      "s") Y=$Y+1 ;; # 往下移动
      "a") X=$X-1 ;; # 往左移动
      "q") end_of_game ;;
      *) X=$X+1 ;; # 默认右移
      esac
    
      # 如果蛇头碰到食物,长度+1,并重新生成食物
      if [[ $X -eq ${RANDOM_X} && $Y -eq ${RANDOM_Y} ]]; then
        ((LENGTH++))
        let score+=10
        X_ARR[${LENGTH}]=$X
        Y_ARR[${LENGTH}]=$Y
        gen_food
        return
      fi
    
      # 越界退出
      if [[ $X -le $MAP_X || $Y -le $MAP_Y || $X -ge $(($MAP_X + $MAP_WIDTH)) || $Y -ge $(($MAP_Y + $MAP_HIGHT)) ]]; then
        end_of_game
      fi
    
      # 蛇头碰到蛇身
      for ((i = 2; i <= ${LENGTH}; i++)); do
        if [[ $X -eq ${X_ARR[$i]} && $Y -eq ${Y_ARR[$i]} ]]; then
          end_of_game
        fi
      done
    
      # 向前蠕动一下
      for ((i = 0; i <= ${LENGTH}; i++)); do
        X_ARR[$i]=${X_ARR[$i + 1]}
        Y_ARR[$i]=${Y_ARR[$i + 1]}
      done
    
      # 更新蛇头到数组
      X_ARR[${LENGTH}]=$X
      Y_ARR[${LENGTH}]=$Y
    }
    
    function main() {
      init
      draw_snake
    
      # 以子进程的方式开启跑马灯效果
      {
        init_map_lamp
      } &
    
      while :; do
        OLD_DIR=$DIR
        # 如果没有wasd输入,则保持原方向不变,否则调转方向
        if ! read -n 1 -t 0.5 -s DIR; then
          DIR=$OLD_DIR
        fi
        sleep 0.0001
        move
        draw_snake
      done
    }
    
    main
  • 相关阅读:
    使用Sed抽取MySQL安装文档的目录及行号
    [MySQL]关于Com_状态
    [译]理解对象存储如何工作
    [译]OpenStack Object Storage Monitoring
    通过设置swift中container的ACL提供匿名访问及用户授权读取服务
    使用swift命令遭遇503错误
    swift-get-nodes简单使用
    修改虚拟硬盘的大小
    php-fpm重启
    Windows学习"Network Analysis in Python"
  • 原文地址:https://www.cnblogs.com/luwei0915/p/16416171.html
Copyright © 2020-2023  润新知