這篇文章給大家分享的是有關(guān)如何使用shell實現(xiàn)俄羅斯方塊腳本的內(nèi)容。小編覺得挺實用的,因此分享給大家做個參考,一起跟隨小編過來看看吧。
創(chuàng)新互聯(lián)基于成都重慶香港及美國等地區(qū)分布式IDC機(jī)房數(shù)據(jù)中心構(gòu)建的電信大帶寬,聯(lián)通大帶寬,移動大帶寬,多線BGP大帶寬租用,是為眾多客戶提供專業(yè)遂寧聯(lián)通機(jī)房報價,主機(jī)托管價格性價比高,為金融證券行業(yè)服務(wù)器托管,ai人工智能服務(wù)器托管提供bgp線路100M獨(dú)享,G口帶寬及機(jī)柜租用的專業(yè)成都idc公司。具體內(nèi)容如下
draw 是畫出圖形界面,keytest是獲取鍵盤,tetris是整個游戲
tetris.sh
#!/bin/bash APP_NAME="${0##*[\\/]}" APP_VERSION="1.0" #顏色定義 iSumColor=7 #顏色總數(shù) cRed=1 #紅色 cGreen=2 #綠色 cYellow=3 #黃色 cBlue=4 #藍(lán)色 cFuchsia=5 #紫紅色 cCyan=6 #青色(藍(lán)綠色) cWhite=7 #白色 #位置與大小 marginLeft=3 #邊框左邊距 marginTop=2 #邊框上邊距 ((mapLeft=marginLeft+2)) #棋盤左邊距 ((mapTop=$marginTop+1)) #棋盤上邊距 mapWidth=10 #棋盤寬度 mapHeight=15 #棋盤高度 #顏色設(shè)置 cBorder=$cGreen cScore=$cFuchsia cScoreValue=$cCyan #控制信號 #游戲使用兩個進(jìn)程,一個用于接收輸入,一個用于游戲流程和顯示界面; #當(dāng)前者接收到上下左右等按鍵時,通過向后者發(fā)送signal的方式通知后者。 sigRotate=25 #向上鍵 sigLeft=26 sigRight=27 sigDown=28 sigAllDown=29 #空格鍵 sigExit=30 #方塊定義,7大類19種樣式 #前8位為方塊坐標(biāo),后2位為方塊剛出現(xiàn)的時候的位置 box0_0=(0 0 0 1 1 0 1 1 0 4) box1_0=(0 1 1 1 2 1 3 1 0 3) box1_1=(1 0 1 1 1 2 1 3 -1 3) box2_0=(0 0 1 0 1 1 2 1 0 4) box2_1=(0 1 0 2 1 0 1 1 0 3) box3_0=(0 1 1 0 1 1 2 0 0 4) box3_1=(0 0 0 1 1 1 1 2 0 4) box4_0=(0 2 1 0 1 1 1 2 0 3) box4_1=(0 1 1 1 2 1 2 2 0 3) box4_2=(1 0 1 1 1 2 2 0 -1 3) box4_3=(0 0 0 1 1 1 2 1 0 4) box5_0=(0 0 1 0 1 1 1 2 0 3) box5_1=(0 1 0 2 1 1 2 1 0 3) box5_2=(1 0 1 1 1 2 2 2 -1 3) box5_3=(0 1 1 1 2 0 2 1 0 4) box6_0=(0 1 1 0 1 1 1 2 0 3) box6_1=(0 1 1 1 1 2 2 1 0 3) box6_2=(1 0 1 1 1 2 2 1 -1 3) box6_3=(0 1 1 0 1 1 2 1 0 4) iSumType=7 #方塊類型總數(shù) boxStyle=(1 2 2 2 4 4 4) #各種方塊旋轉(zhuǎn)后可能的樣式數(shù)目 iScoreEachLevel=50 #提升一個級別需要的分?jǐn)?shù) #運(yùn)行時數(shù)據(jù) sig=0 #接收到的signal iScore=0 #總分 iLevel=0 #速度級 boxNext=() #下一個方塊 iboxNextColor=0 #下一個方塊的顏色 iboxNextType=0 #下一個方塊的種類 iboxNextStyle=0 #下一個方塊的樣式 boxCur=() #當(dāng)前方塊的位置定義 iBoxCurColor=0 #當(dāng)前方塊的顏色 iBoxCurType=0 #當(dāng)前方塊的種類 iBoxCurStyle=0 #當(dāng)前方塊的樣式 boxCurX=-1 #當(dāng)前方塊的x坐標(biāo)位置 boxCurY=-1 #當(dāng)前方塊的y坐標(biāo)位置 map=() #棋盤圖表 #初始化所有背景方塊為-1, 表示沒有方塊 for ((i = 0; i < mapHeight * mapWidth; i++)) do map[$i]=-1 done #接收輸入的進(jìn)程的主函數(shù) function RunAsKeyReceiver() { local pidDisplayer key aKey sig cESC sTTY pidDisplayer=$1 aKey=(0 0 0) cESC=`echo -ne "\033"` cSpace=`echo -ne "\040"` #保存終端屬性。在read -s讀取終端鍵時,終端的屬性會被暫時改變。 #如果在read -s時程序被不幸殺掉,可能會導(dǎo)致終端混亂, #需要在程序退出時恢復(fù)終端屬性。 sTTY=`stty -g` #捕捉退出信號 trap "MyExit;" INT QUIT trap "MyExitNoSub;" $sigExit #隱藏光標(biāo) echo -ne "\033[?25l" while : do #讀取輸入。注-s不回顯,-n讀到一個字符立即返回 read -s -n 1 key aKey[0]=${aKey[1]} aKey[1]=${aKey[2]} aKey[2]=$key sig=0 #判斷輸入了何種鍵 if [[ $key == $cESC && ${aKey[1]} == $cESC ]] then #ESC鍵 MyExit elif [[ ${aKey[0]} == $cESC && ${aKey[1]} == "[" ]] then if [[ $key == "A" ]]; then sig=$sigRotate #<向上鍵> elif [[ $key == "B" ]]; then sig=$sigDown #<向下鍵> elif [[ $key == "D" ]]; then sig=$sigLeft #<向左鍵> elif [[ $key == "C" ]]; then sig=$sigRight #<向右鍵> fi elif [[ $key == "W" || $key == "w" ]]; then sig=$sigRotate #W, w elif [[ $key == "S" || $key == "s" ]]; then sig=$sigDown #S, s elif [[ $key == "A" || $key == "a" ]]; then sig=$sigLeft #A, a elif [[ $key == "D" || $key == "d" ]]; then sig=$sigRight #D, d elif [[ "[$key]" == "[]" ]]; then sig=$sigAllDown #空格鍵 elif [[ $key == "Q" || $key == "q" ]] #Q, q then MyExit fi if [[ $sig != 0 ]] then #向另一進(jìn)程發(fā)送消息 kill -$sig $pidDisplayer fi done } #退出前的恢復(fù) MyExitNoSub() { local y #恢復(fù)終端屬性 stty $sTTY ((y = marginTop + mapHeight + 4)) #顯示光標(biāo) echo -e "\033[?25h\033[${y};0H" exit } MyExit() { #通知顯示進(jìn)程需要退出 kill -$sigExit $pidDisplayer MyExitNoSub } #處理顯示和游戲流程的主函數(shù) RunAsDisplayer() { local sigThis InitDraw #掛載各種信號的處理函數(shù) trap "sig=$sigRotate;" $sigRotate trap "sig=$sigLeft;" $sigLeft trap "sig=$sigRight;" $sigRight trap "sig=$sigDown;" $sigDown trap "sig=$sigAllDown;" $sigAllDown trap "ShowExit;" $sigExit while : do #根據(jù)當(dāng)前的速度級iLevel不同,設(shè)定相應(yīng)的循環(huán)的次數(shù) for ((i = 0; i < 21 - iLevel; i++)) do sleep 0.02 sigThis=$sig sig=0 #根據(jù)sig變量判斷是否接受到相應(yīng)的信號 if ((sigThis == sigRotate)); then BoxRotate; #旋轉(zhuǎn) elif ((sigThis == sigLeft)); then BoxLeft; #左移一列 elif ((sigThis == sigRight)); then BoxRight; #右移一列 elif ((sigThis == sigDown)); then BoxDown; #下落一行 elif ((sigThis == sigAllDown)); then BoxAllDown; #下落到底 fi done #kill -$sigDown $$ BoxDown #下落一行 done } #繪制當(dāng)前方塊,傳第一個參數(shù),0表示擦除當(dāng)前方塊,1表示繪制當(dāng)前方塊 DrawCurBox() { local i x y bErase sBox bErase=$1 if (( bErase == 0 )) then sBox="\040\040" #用兩個空格擦除 else sBox="[]" echo -ne "\033[1m\033[3${iBoxCurColor}m\033[4${iBoxCurColor}m" fi for ((i = 0; i < 8; i += 2)) do ((y = mapTop + 1 + ${boxCur[$i]} + boxCurY)) ((x = mapLeft + 1 + 2 * (boxCurX + ${boxCur[$i + 1]}))) echo -ne "\033[${y};${x}H${sBox}" done echo -ne "\033[0m" } #移動方塊 #BoxMove(y, x), 測試是否可以把移動中的方塊移到(y, x)的位置, 返回0則可以, 1不可以 BoxMove() { local i x y xPos yPos yPos=$1 xPos=$2 for ((i = 0; i < 8; i += 2)) do #方塊相對于棋盤坐標(biāo) ((y = yPos + ${boxCur[$i]})) ((x = xPos + ${boxCur[$i + 1]})) if (( y < 0 || y >= mapHeight || x < 0 || x >= mapWidth)) then #撞到墻壁了 return 1 fi if (( ${map[y * mapWidth + x]} != -1 )) then #撞到其他已經(jīng)存在的方塊了 return 1 fi done return 0; } #將方塊貼到棋盤上 Box2Map() { local i j x y line #將當(dāng)前移動中的方塊貼到棋盤對應(yīng)的區(qū)域 for ((i = 0; i < 8; i += 2)) do #計算方塊相對于棋盤的坐標(biāo) ((y = ${boxCur[$i]} + boxCurY)) ((x = ${boxCur[$i + 1]} + boxCurX)) map[y*mapWidth+x]=$iBoxCurColor #將方塊顏色賦給地圖 done line=0 for ((i = 0; i < mapHeight; i++)) do for ((j = 0; j < mapWidth; j++)) do #如果棋盤上有空隙,跳出循環(huán) [[ ${map[i*mapWidth+j]} -eq -1 ]] && break done [ $j -lt $mapWidth ] && continue #說明當(dāng)前行可消去,可消去行數(shù)加一 (( line++ )) #第i行可被消除,將0行至第i-1行全部下移一行,從第i-1行開始移動 for ((j = i*mapWidth-1; j >= 0; j--)) do ((x = j + mapWidth)) map[$x]=${map[$j]} done #因為下移一行,第0行置空 for ((i = 0; i < mapWidth; i++)) do map[$i]=-1 done done [ $line -eq 0 ] && return #根據(jù)消去的行數(shù)line計算分?jǐn)?shù)和速度級 ((x = marginLeft + mapWidth * 2 + 7)) ((y = marginTop + 11)) ((iScore += line * 2 - 1)) #顯示新的分?jǐn)?shù) echo -ne "\033[1m\033[3${cScoreValue}m\033[${y};${x}H${iScore} " if ((iScore % iScoreEachLevel < line * 2 - 1)) then if ((iLevel < 20)) then ((iLevel++)) ((y = marginTop + 14)) #顯示新的速度級 echo -ne "\033[3${cScoreValue}m\033[${y};${x}H${iLevel} " fi fi echo -ne "\033[0m" #重新顯示背景方塊 for ((i = 0; i < mapHeight; i++)) do #棋盤相對于屏幕的坐標(biāo) ((y = i + mapTop + 1)) ((x = mapLeft + 1)) echo -ne "\033[${y};${x}H" for ((j = 0; j < mapWidth; j++)) do ((tmp = i * mapWidth + j)) if ((${map[$tmp]} == -1)) then echo -ne " " else echo -ne "\033[1m\033[3${map[$tmp]}m\033[4${map[$tmp]}m[]\033[0m" fi done done } #左移一格 BoxLeft() { local x ((x = boxCurX - 1)) if BoxMove $boxCurY $x then DrawCurBox 0 ((boxCurX = x)) DrawCurBox 1 fi } #右移一格 BoxRight() { local x ((x = boxCurX + 1)) if BoxMove $boxCurY $x then DrawCurBox 0 ((boxCurX = x)) DrawCurBox 1 fi } #向下移一格 BoxDown() { local y ((y = boxCurY + 1)) #新的y坐標(biāo) if BoxMove $y $boxCurX #測試是否可以下落一行 then DrawCurBox 0 #將舊的方塊抹去 ((boxCurY = y)) DrawCurBox 1 #顯示新的下落后方塊 else #走到這兒, 如果不能下落了 Box2Map #將當(dāng)前移動中的方塊貼到背景方塊中 CreateBox #產(chǎn)生新的方塊 fi } #下落到底 BoxAllDown() { local y iDown #計算能夠下落的行數(shù) iDown=0 (( y = boxCurY + 1 )) while BoxMove $y $boxCurX do (( y++ )) (( iDown++ )) done DrawCurBox 0 #將舊的方塊抹去 ((boxCurY += iDown)) DrawCurBox 1 #顯示新的下落后的方塊 Box2Map #將當(dāng)前移動中的方塊貼到背景方塊中 CreateBox #產(chǎn)生新的方塊 } #翻轉(zhuǎn) BoxRotate() { [ ${boxStyle[$iBoxCurType]} -eq 1 ] && return ((rotateStyle = (iBoxCurStyle + 1) % ${boxStyle[$iBoxCurType]})) #將當(dāng)前方塊保存到boxTmp boxTmp=( `eval 'echo ${boxCur[@]}'` ) boxCur=( `eval 'echo ${box'$iBoxCurType'_'$rotateStyle'[@]}'` ) if BoxMove $boxCurY $boxCurX #測試旋轉(zhuǎn)后是否有空間放的下 then #抹去舊的方塊 boxCur=( `eval 'echo ${boxTmp[@]}'` ) DrawCurBox 0 boxCur=( `eval 'echo ${box'$iBoxCurType'_'$rotateStyle'[@]}'` ) DrawCurBox 1 iBoxCurStyle=$rotateStyle else #不能旋轉(zhuǎn),還是繼續(xù)使用老的樣式 boxCur=( `eval 'echo ${boxTmp[@]}'` ) fi } #準(zhǔn)備下一個方塊 PrepareNextBox() { local i x y #清除右邊預(yù)顯示的方塊 if (( ${#boxNext[@]} != 0 )); then for ((i = 0; i < 8; i += 2)) do ((y = marginTop + 1 + ${boxNext[$i]})) ((x = marginLeft + 2 * mapWidth + 7 + 2 * ${boxNext[$i + 1]})) echo -ne "\033[${y};${x}H\040\040" done fi #隨機(jī)生成預(yù)顯式方塊 (( iBoxNextType = RANDOM % iSumType )) (( iBoxNextStyle = RANDOM % ${boxStyle[$iBoxNextType]} )) (( iBoxNextColor = RANDOM % $iSumColor + 1 )) boxNext=( `eval 'echo ${box'$iBoxNextType'_'$iBoxNextStyle'[@]}'` ) #顯示右邊預(yù)顯示的方塊 echo -ne "\033[1m\033[3${iBoxNextColor}m\033[4${iBoxNextColor}m" for ((i = 0; i < 8; i += 2)) do ((y = marginTop + 1 + ${boxNext[$i]})) ((x = marginLeft + 2 * mapWidth + 7 + 2 * ${boxNext[$i + 1]})) echo -ne "\033[${y};${x}H[]" done echo -ne "\033[0m" } #顯示新方塊 CreateBox() { if (( ${#boxCur[@]} == 0 )); then #當(dāng)前方塊不存在 (( iBoxCurType = RANDOM % iSumType )) (( iBoxCurStyle = RANDOM % ${boxStyle[$iBoxCurType]} )) (( iBoxCurColor = RANDOM % $iSumColor + 1 )) else #當(dāng)前方塊已存在, 將下一個方塊賦給當(dāng)前方塊 iBoxCurType=$iBoxNextType; iBoxCurStyle=$iBoxNextStyle; iBoxCurColor=$iBoxNextColor fi #當(dāng)前方塊數(shù)組 boxCur=( `eval 'echo ${box'$iBoxCurType'_'$iBoxCurStyle'[@]}'` ) #初始化方塊起始坐標(biāo) boxCurY=boxCur[8]; boxCurX=boxCur[9]; DrawCurBox 1 #繪制當(dāng)前方塊 if ! BoxMove $boxCurY $boxCurX then kill -$sigExit $PPID ShowExit fi PrepareNextBox } #繪制邊框 DrawBorder() { clear local i y x1 x2 #顯示邊框 echo -ne "\033[1m\033[3${cBorder}m\033[4${cBorder}m" ((x1 = marginLeft + 1)) #左邊框x坐標(biāo) ((x2 = x1 + 2 + mapWidth * 2)) #右邊框x坐標(biāo) for ((i = 0; i < mapHeight; i++)) do ((y = i + marginTop + 2)) echo -ne "\033[${y};${x1}H||" #繪制左邊框 echo -ne "\033[${y};${x2}H||" #繪制右邊框 done ((x1 = marginTop + mapHeight + 2)) for ((i = 0; i < mapWidth + 2; i++)) do ((y = i * 2 + marginLeft + 1)) echo -ne "\033[${mapTop};${y}H==" #繪制上邊框 echo -ne "\033[${x1};${y}H==" #繪制下邊框 done echo -ne "\033[0m" #顯示"Score"和"Level"字樣 echo -ne "\033[1m" ((y = marginLeft + mapWidth * 2 + 7)) ((x1 = marginTop + 10)) echo -ne "\033[3${cScore}m\033[${x1};${y}HScore" ((x1 = marginTop + 11)) echo -ne "\033[3${cScoreValue}m\033[${x1};${y}H${iScore}" ((x1 = marginTop + 13)) echo -ne "\033[3${cScore}m\033[${x1};${y}HLevel" ((x1 = marginTop + 14)) echo -ne "\033[3${cScoreValue}m\033[${x1};${y}H${iLevel}" echo -ne "\033[0m" } InitDraw() { clear #清屏 DrawBorder #繪制邊框 CreateBox #創(chuàng)建方塊 } #退出時顯示GameOVer! ShowExit() { local y ((y = mapHeight + mapTop + 3)) echo -e "\033[${y};1HGameOver!\033[0m" exit } #游戲主程序在這兒開始. if [[ "$1" == "--version" ]]; then echo "$APP_NAME $APP_VERSION" elif [[ "$1" == "--show" ]]; then #當(dāng)發(fā)現(xiàn)具有參數(shù)--show時,運(yùn)行顯示函數(shù) RunAsDisplayer else bash $0 --show& #以參數(shù)--show將本程序再運(yùn)行一遍 RunAsKeyReceiver $! #以上一行產(chǎn)生的進(jìn)程的進(jìn)程號作為參數(shù) fi
keytest.sh
#!/bin/bash GetKey() { aKey=(0 0 0) #定義一個數(shù)組來保存3個按鍵 cESC=`echo -ne "\033"` cSpace=`echo -ne "\040"` while : do read -s -n 1 key #讀取一個字符,將讀取到的字符保存在key中 #echo $key #echo XXX aKey[0]=${aKey[1]} #第一個按鍵 aKey[1]=${aKey[2]} #第二個按鍵 aKey[2]=$key #第三個按鍵 if [[ $key == $cESC && ${aKey[1]} == $cESC ]] then MyExit elif [[ ${aKey[0]} == $cESC && ${aKey[1]} == "[" ]] then if [[ $key == "A" ]]; then echo KEYUP elif [[ $key == "B" ]]; then echo KEYDOWN elif [[ $key == "D" ]]; then echo KEYLEFT elif [[ $key == "C" ]]; then echo KEYRIGHT fi fi done } GetKey
draw.sh
#!/bin/bash #位置與大小 marginLeft=8 #邊框左邊距 marginTop=6 #邊框上邊距 ((mapLeft=marginLeft+2)) #棋盤左邊距 ((mapTop=$marginTop+1)) #棋盤上邊距 mapWidth=10 #棋盤寬度 mapHeight=15 #棋盤高度 #方塊定義,7大類19種樣式 #前8位為方塊坐標(biāo),后2位為方塊剛出現(xiàn)的時候的位置 box0_0=(0 0 0 1 1 0 1 1 0 4) box1_0=(0 1 1 1 2 1 3 1 0 3) box1_1=(1 0 1 1 1 2 1 3 -1 3) box2_0=(0 0 1 0 1 1 2 1 0 4) box2_1=(0 1 0 2 1 0 1 1 0 3) box3_0=(0 1 1 0 1 1 2 0 0 4) box3_1=(0 0 0 1 1 1 1 2 0 4) box4_0=(0 2 1 0 1 1 1 2 0 3) box4_1=(0 1 1 1 2 1 2 2 0 3) box4_2=(1 0 1 1 1 2 2 0 -1 3) box4_3=(0 0 0 1 1 1 2 1 0 4) box5_0=(0 0 1 0 1 1 1 2 0 3) box5_1=(0 1 0 2 1 1 2 1 0 3) box5_2=(1 0 1 1 1 2 2 2 -1 3) box5_3=(0 1 1 1 2 0 2 1 0 4) box6_0=(0 1 1 0 1 1 1 2 0 3) box6_1=(0 1 1 1 1 2 2 1 0 3) box6_2=(1 0 1 1 1 2 2 1 -1 3) box6_3=(0 1 1 0 1 1 2 1 0 4) #繪制邊框 DrawBorder() { clear local i y x1 x2 #顯示邊框 echo -ne "\033[1m\033[32m\033[42m" ((x1 = marginLeft + 1)) #左邊框x坐標(biāo) ((x2 = x1 + 2 + mapWidth * 2)) #右邊框x坐標(biāo) for ((i = 0; i < mapHeight; i++)) do ((y = i + marginTop + 2)) echo -ne "\033[${y};${x1}H||" #繪制左邊框 echo -ne "\033[${y};${x2}H||" #繪制右邊框 done ((x1 = marginTop + mapHeight + 2)) for ((i = 0; i < mapWidth + 2; i++)) do ((y = i * 2 + marginLeft + 1)) echo -ne "\033[${mapTop};${y}H==" #繪制上邊框 echo -ne "\033[${x1};${y}H==" #繪制下邊框 done echo -ne "\033[0m" } DrawBox() { local i x y xPos yPos yPos=${box0_0[8]} xPos=${box0_0[9]} echo -ne "\033[1m\033[35m\033[45m" for ((i = 0; i < 8; i += 2)) do (( y = mapTop + 1 + ${box0_0[$i]} + yPos )) (( x = mapLeft + 1 + 2 * (${box0_0[$i + 1]} + xPos) )) echo -ne "\033[${y};${x}H[]" done echo -ne "\033[0m" } InitDraw() { clear #清屏 DrawBorder #繪制邊框 DrawBox while : do sleep 1 done } InitDraw
感謝各位的閱讀!關(guān)于“如何使用shell實現(xiàn)俄羅斯方塊腳本”這篇文章就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,讓大家可以學(xué)到更多知識,如果覺得文章不錯,可以把它分享出去讓更多的人看到吧!
名稱欄目:如何使用shell實現(xiàn)俄羅斯方塊腳本-創(chuàng)新互聯(lián)
新聞來源:http://jinyejixie.com/article18/dpeddp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、企業(yè)建站、定制開發(fā)、用戶體驗、品牌網(wǎng)站建設(shè)、手機(jī)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容