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