Shell脚本小游戏(学习记录贴)

最近在学习脚本语言,没有章法,索性就想着使用脚本写一个命令行小游戏,连带着也可以学习脚本的用法,忙碌了一天的时间,将将写完了基础框架,不过对于脚本的用法精进岂止一点,还是收获良多!
以后闲下来的时间也会继续更新这个小游戏的,以下就是全部代码,关于脚本的一些使用可以看脚本内的注释

#!/bin/bash 

# @Auth     hcx
# @WeChat   GAME_SERVER_HCX
# @Tencent  305773778

# -----------------------------------------配置区-----------------------------------------
# config 就是懒不想读文件,就直接写在一起咯
# 事件描述
eventDesc=(
            # id:0
            "你遇到了一只可爱的小怪物,攻击还是逃跑?" 
            # id:1
            "你遇到了一个仙人,他说你骨骼清奇,十分适合修仙."
          )
# 事件选择
eventChoice=(
              # id:0
              "1.当然是打啊?!\n2.小命要紧!快跑!" 
              # id:1
              "1.仙人收我为徒\n2.修什么仙,要相信科学"
            )
# 触发事件
touchEvent=(
             # id:0
             "fight:moster:player-level;none" 
             # id:1
             "attrChange:exp:1000;none"
           )
# 事件配置[描述id,选项id,触发事件id]
eventConfig=(
              # id:0
              "0,0,0" 
              # id:1
              "1,1,1"
            )

# -----------------------------------------配置区-----------------------------------------
# -----------------------------------------方法区-----------------------------------------
# 无事件
none(){
 echo "什么都没有发生~"
}

# 事件解析
doEvent(){
  # 切割字符串 (${event//oldStr/newStr}) 只是其中的一种方法,也可以用tr等等
  # 将分隔符替换为空格并加上圆括号本质就是拼接了一个数组的格式,但缺点显而易见,元素中不能含有空格
  index=$1
  eventParamIds=(${eventConfig[index]//,/ })
  eventDescId=${eventParamIds[0]}
  eventChoiceId=${eventParamIds[1]}
  touchEventId=${eventParamIds[2]}
  touchEventCommondArr=(${touchEvent[touchEventId]//;/ })
  echo "${eventDesc[eventDescId]}"
  echo -e "${eventChoice[eventChoiceId]}"
  read choice
  choice=`expr $choice - 1`
  while [ $choice -ge ${#touchEventCommondArr[*]} -o $choice -lt 0 ]
  do
    echo "请输入正确的选项"
    read choice
  done
  echo "世间种种奇遇~骚年切莫心急~让奇遇飞一会儿~"
  ${touchEventCommondArr[choice]//:/ }
}

# 参数为百分比值
updateBar(){
  num=`expr $1 / 2`
  str=$(seq -s '' ${num} | sed 's/[0-9]//g')
  blankStr=''
  if [ $1 = 100 ]
  then
    echo "正在加载[${str}${blankStr}]$1%"
  else
    blankStr=$(seq -s ' ' `expr 50 - ${num}` | sed 's/[0-9]//g')
    echo -ne "正在加载[${str}${blankStr}]$1%\r"
  fi
}

# 假进度条
loading(){
  for i in {1..100}
  do
    updateBar ${i}
    # 这里为了表现明显一些,休眠20ms
    # sleep 0.02
  done
}

workDir=$(cd `dirname $0`; pwd)
saveFilePath=${workDir}/save.data

# 读取存档
getAttr(){
  echo `cat ${saveFilePath} | grep -w $1 | awk -F '=' '{print $2}' | sed 's/\"//g' | tr -d '\r'`
}

# 更新存档
updateAttr(){
  if [ ! -n "$2" ]
  then
    return
  fi
  # 将函数运行结果赋予变量使用$()包裹即可,或者``包裹
  value=`getAttr $1`
  if [ -n "${value}" ]
  then
    sed -i "" "s/$1=.*/$1=$2/g" $saveFilePath
  else
    echo -e "$1=$2">>$saveFilePath
  fi 
}

# 属性改变
attrChange(){
  changeAttrName=$1
  beforeAttrValue=`eval echo '$'"$changeAttrName"`
  attrIsNone=true
  if [ -n "$beforeAttrValue" ]
  then
    attrIsNone=false
  fi
  changeValue=$2
  case $changeAttrName in
    "exp")
      if [ $attrIsNone = true ]
      then
        exp=0
      fi
      exp=`expr $exp + $changeValue`
      # -gt 大于号
      if [ 0 -gt $exp ]
      then
        exp=0
      fi
      # -lt 小于号
      needUpgradeLevelNum=0
      while [ `expr \( $level + $needUpgradeLevelNum \) \* 10` -lt $exp ]
      do
        needUpgradeLevelNum=`expr $needUpgradeLevelNum + 1`
        exp=`expr $exp - \( \( $level + $needUpgradeLevelNum \) \* 10 \)`
      done
      updateAttr exp $exp
      if [ ! $needUpgradeLevelNum -eq 0 ]
      then 
        attrChange level $needUpgradeLevelNum
        echo "实力突飞猛进,感觉自己更加强大!"
      else
        echo "感觉实力又有精进!"
      fi
    ;;
    "level")
      if [ $attrIsNone = true ]
      then
        level=1
      fi
      afterLevel=`expr $level + $changeValue`
      # 升级事件,增加属性值
      for i in $(seq $level $afterLevel)
      do
        attrChange hp `expr $i \* 100`
        attrChange atk `expr $i \* 3`
        attrChange def `expr $i \* 1`
      done
      level=$afterLevel
      updateAttr level $level
    ;;
    "atk")
      if [ $attrIsNone = true ]
      then
        atk=1
      fi
      atk=`expr $atk + $changeValue`
      updateAttr atk $atk
    ;;
    "def")
      if [ $attrIsNone = true ]
      then
        def=1
      fi
      def=`expr $def + $changeValue`
      updateAttr def $def
    ;;
    "hp")
      if [ $attrIsNone = true ]
      then
        hp=100
      fi
      hp=`expr $hp + $changeValue`
      updateAttr hp $hp
    ;;
    "killMosterNum")
      if [ $attrIsNone = true ]
      then
        killMosterNum=0
      fi
      killMosterNum=`expr $killMosterNum + $changeValue`
      updateAttr killMosterNum $killMosterNum
    ;;
  esac
}
# 展示玩家属性
showPlayerProp(){
  echo "昵称:${nickname}"
  echo "称号:${title}"
  echo "职业:${occupation}"
  echo "等级:${level}"
  echo "经验:${exp}/`expr $level \* 10`"
  echo "血量:${hp}"
  echo "攻击:${atk}"
  echo "防御:${def}"
  echo "技能:${skill}"
  echo "当前地图:${map}"
  echo "杀怪数:${killMosterNum}"
}
# -----------------------------------------方法区-----------------------------------------

# -----------------------------------------事件区-----------------------------------------
# 战场信息输出
echoFightDetail(){
  echo "怪物名称:我可爱么"
  echo "怪物等级:$mosterLevel"
  echo "[血量]HP: $tmpMosterHp/$mosterHp"
  echo "[攻击]ATK: $mosterAtk"
  echo "[防御]DEF: $mosterDef"
  echo "     ^^^     "
  echo "     ^^^     "
  echo "     |||     "
  echo "角色:$nickname"
  echo "等级:$level"
  echo "[血量]HP: $tmpHp/$hp"
  echo "[攻击]ATK: $atk"
  echo "[防御]DEF: $def"
}
# 战斗方法  参数1:目标类型    参数2:目标等级范围
fight(){
  # 清屏
  reset
  # 目标类型
  targetType=$1
  # 目标等级随机范围
  targetLevelRound=$2
  # 解析等级随机范围
  if [ -n "$targetLevelRound" -o "$targetLevelRound" = "player-level" ]
  then
    targetLevelRound="`expr $level - 1`-`expr $level + 1`"
  fi
  targetLevelMin=`echo -n $targetLevelRound | awk -F '-' '{print $1}'`
  targetLevelMax=`echo -n $targetLevelRound | awk -F '-' '{print $2}'`
  mosterLevel=`expr $[$RANDOM%$targetLevelMax] + $targetLevelMax - $targetLevelMin`
  mosterHp=`expr $mosterLevel \* 100`
  mosterAtk=`expr $mosterLevel \* 10`
  mosterDef=`expr $mosterLevel \* 10`
  tmpHp=$hp
  tmpMosterHp=$mosterHp
  echoFightDetail
  echo -n "回车以攻击 输入run逃跑 "
  read continue
  if [ "$continue" = "run" ]
  then
    echo "没事,修炼修炼,再来复仇!"
    return
  fi
  reset
  round=1
  while [ $tmpMosterHp -gt 0 -a $tmpHp -gt 0 ]
  do
    playerDmg=`expr $atk - $mosterDef`
    if [ $playerDmg -lt 0 ]
    then
      playerDmg=1
    fi
    tmpMosterHp=`expr $tmpMosterHp - $playerDmg`
    if [ $tmpMosterHp -lt 0 ]
    then
      tmpMosterHp=0
    fi
    mosterDmg=`expr $mosterAtk - $def`
    if [ $mosterDmg -lt 0 ]
    then
      mosterDmg=1
    fi
    tmpHp=`expr $tmpHp - $mosterDmg `
    if [ $tmpHp -lt 0 ]
    then
      tmpHp=0
    fi
    round=`expr $round + 1`
    echo "第${round}回合"
    echoFightDetail
    if [ $tmpHp = 0 -o $tmpMosterHp = 0 ]
    then
      break
    fi
    echo -n "回车以攻击 输入run逃跑 "
      read continue
    if [ "$continue" = "run" ]
    then
      echo "没事,修炼修炼,再来复仇!"
      return
    fi
    reset
  done
  if [ $tmpHp = 0 ]
  then
    echo "啊!你死了"
    echo "怪物不屑的对你说,小样儿回去修炼吧,打败我还早得很!"
  fi
  if [ $tmpMosterHp = 0 ]
  then
    echo "怪物被你一棒打死!"
    getExp=`expr $mosterLevel \* 100`
    echo "你挥一挥衣袖,带走了${getExp}经验"
    attrChange exp $getExp
    attrChange killMosterNum 1
  fi
}
# -----------------------------------------事件区-----------------------------------------

# --------------------------------------游戏主流程开始--------------------------------------
reset
echo "welcome to my little game"
sleep 0.618
echo "it's a beautiful and wonderful world of games"
sleep 0.618
echo -ne "so now,you should load save to continue game?(y/n) "
read needLoading
nickname='玩家'
level=1
exp=0
atk=1
def=1
hp=100
occupation=0
skill={"普通攻击"}
map=1
killMosterNum=0
title="一个普通玩家"
if [ "$needLoading" = "y" ] 
then
  echo "let me see what you have on data~"
  sleep 0.618
  # 这里才是真正的加载!没想到吧hhhhhhh
  if [ ! -f "${saveFilePath}" ] 
  then
    echo "oh~You're so naughty,nothing data to loading~"
    sleep 0.618
    echo "but don't worry about.just create one for you, my kitty"
    # 创建存档文件,赋予完全控制权限
    touch "${saveFilePath}"
    chmod 777 ${saveFilePath}
    sleep 0.618
    echo "now,enjoy self,enjoy play,let we run to the game world!"
  else
    source ${saveFilePath}
  fi
  loadThings=("sky" "flower" "meat" "no food no game!!!")
  # 你想看出点什么?看出什么了?你在做梦哈哈哈,这里只是假的加载而已,骗鬼的啦!
  for thing in "${loadThings[@]}"; do
    echo "just loading ${thing} now!";
    loading
  done
else
  # 读取昵称
  echo "but waaaaaaait a moment! let me get your nickname,so what?"
  echo -n "tell me your nickname:"
  read nickname
fi
echo "okk~ ${nickname}!let's start a wonderful journey~"
echo "gogogo!"
echo "into the game world now!"
# 没错还是假的加载,但是我就是要加~略略略
loading 
reset
eventNum=${#eventConfig[*]}
while true
do
  echo "这里是神奇的摸鱼世界,请输入你的选择"
  echo "1:探索事件"
  echo "2:查看属性"
  read choice
  while [ ! $choice = 1 -a ! $choice = 2 ]
  do
    echo "请输入正确的选择哦~"
  done
  reset
  case $choice in
    1)
      doEvent $[$RANDOM%$eventNum]
    ;;
    2)
      showPlayerProp
    ;;
  esac
  read tmpKey
  reset
done
# --------------------------------------游戏主流程结束--------------------------------------
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,525评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,203评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,862评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,728评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,743评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,590评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,330评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,244评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,693评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,885评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,001评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,723评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,343评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,919评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,042评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,191评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,955评论 2 355

推荐阅读更多精彩内容