免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12
最近访问板块 发新帖
楼主: drowsyboy
打印 上一主题 下一主题

脚本进程的通信 [复制链接]

论坛徽章:
1
荣誉会员
日期:2011-11-23 16:44:17
11 [报告]
发表于 2008-05-29 17:52 |只看该作者

回复 #10 drowsyboy 的帖子

不成熟的想法:可以写入命名管道后用kill向读取进程发信号,通知有数据到达。写端的进程标识可以写到管道中,读取后提取出来。

论坛徽章:
0
12 [报告]
发表于 2008-05-30 18:02 |只看该作者

回复 #11 woodie 的帖子

多谢!

已经搞定了,哈哈,现在我的俄罗斯方块,可以单机两人对站了。

谢谢你和waker的帮助:)

论坛徽章:
0
13 [报告]
发表于 2008-06-02 12:33 |只看该作者
贴出来看看啊。

论坛徽章:
0
14 [报告]
发表于 2008-06-03 10:46 |只看该作者

回复 #13 sgm277 的帖子

呵呵,我只是在前辈的大作上做了一点点小的修改


  1. #!/bin/bash

  2. # Tetris Game
  3. # 10.21.2003 xhchen<[email]xhchen@winbond.com.tw[/email]>

  4. #APP declaration
  5. APP_NAME="${0##*[\\/]}"
  6. APP_VERSION="1.0"

  7. #颜色定义
  8. cRed=1
  9. cGreen=2
  10. cYellow=3
  11. cBlue=4
  12. cFuchsia=5
  13. cCyan=6
  14. cWhite=7

  15. colorTable=($cRed $cGreen $cYellow $cBlue $cFuchsia $cCyan $cWhite)

  16. #位置和大小
  17. iLeft=3
  18. iTop=2
  19. #((iTrayLeft = iLeft + 2))
  20. #((iTrayTop = iTop + 1))
  21. ((iTrayWidth = 10))
  22. ((iTrayHeight = 15))

  23. #颜色设置
  24. cBorder=$cGreen
  25. cScore=$cFuchsia
  26. cScoreValue=$cCyan

  27. #控制信号
  28. #改游戏使用两个进程,一个用于接收输入,一个用于游戏流程和显示界面;
  29. #当前者接收到上下左右等按键时,通过向后者发送signal的方式通知后者。
  30. sigRotate=25
  31. sigLeft=26
  32. sigRight=27
  33. sigDown=28
  34. sigAllDown=29
  35. sigExit=30
  36. sigConsume=31

  37. #七中不同的方块的定义
  38. #通过旋转,每种方块的显示的样式可能有几种
  39. box0=(0 0 0 1 1 0 1 1)
  40. box1=(0 2 1 2 2 2 3 2 1 0 1 1 1 2 1 3)
  41. box2=(0 0 0 1 1 1 1 2 0 1 1 0 1 1 2 0)
  42. box3=(0 1 0 2 1 0 1 1 0 0 1 0 1 1 2 1)
  43. box4=(0 1 0 2 1 1 2 1 1 0 1 1 1 2 2 2 0 1 1 1 2 0 2 1 0 0 1 0 1 1 1 2)
  44. box5=(0 1 1 1 2 1 2 2 1 0 1 1 1 2 2 0 0 0 0 1 1 1 2 1 0 2 1 0 1 1 1 2)
  45. box6=(0 1 1 1 1 2 2 1 1 0 1 1 1 2 2 1 0 1 1 0 1 1 2 1 0 1 1 0 1 1 1 2)
  46. #所有其中方块的定义都放到box变量中
  47. box=(${box0[@]} ${box1[@]} ${box2[@]} ${box3[@]} ${box4[@]} ${box5[@]} ${box6[@]})
  48. #各种方块旋转后可能的样式数目
  49. countBox=(1 2 2 2 4 4 4)
  50. #各种方块再box数组中的偏移
  51. offsetBox=(0 1 3 5 7 11 15)

  52. #每提高一个速度级需要积累的分数
  53. iScoreEachLevel=50                #be greater than 7

  54. #运行时数据
  55. sig=0                                #接收到的signal
  56. iScore=0                               #总分
  57. iLevel=0                                  #速度级
  58. boxNew=()                        #新下落的方块的位置定义
  59. cBoxNew=0                        #新下落的方块的颜色
  60. iBoxNewType=0                        #新下落的方块的种类
  61. iBoxNewRotate=0                        #新下落的方块的旋转角度
  62. boxCur=()                        #当前方块的位置定义
  63. cBoxCur=0                        #当前方块的颜色
  64. iBoxCurType=0                        #当前方块的种类
  65. iBoxCurRotate=0                        #当前方块的旋转角度
  66. boxCurX=-1                        #当前方块的x坐标位置
  67. boxCurY=-1                        #当前方块的y坐标位置
  68. iMap=()                                #背景方块图表

  69. iNeedAddRandLine=0

  70. #初始化所有背景方块为-1, 表示没有方块
  71. for ((i = 0; i < iTrayHeight * iTrayWidth; i++)); do iMap[$i]=-1; done

  72. function CreateNamedPipe()
  73. {
  74.         local pid

  75.         pid=${1}

  76.         if ! [ -p /tmp/pipe${pid} ] ; then
  77.                 mkfifo /tmp/pipe${pid}
  78.         fi
  79. }

  80. function DoConsumeLine() {
  81.         local line_content pid linenum

  82.         read line_content <&7
  83.        
  84.         if ! [ "${line_content}" = "" ] ; then
  85.                 pid=`echo ${line_content} | cut -d' ' -f1`
  86.                 linenum=`echo ${line_content} | cut -d' ' -f2`

  87.                 if [ "${pid}" = "${pidDisplayer1}" ] ; then
  88.                         kill -${sigConsume} ${pidDisplayer2} && echo "${linenum}" >&9
  89.                 else
  90.                         kill -${sigConsume} ${pidDisplayer1} && echo "${linenum}" >&8
  91.                 fi
  92.         fi
  93. }

  94. #接收输入的进程的主函数
  95. function RunAsKeyReceiver()
  96. {
  97.         local pidDisplayer1 pidDisplayer2 key aKey sig cESC sTTY pid

  98.         pidDisplayer1=$1
  99.         pidDisplayer2=$2
  100.         aKey=(0 0 0)

  101.         cESC=`echo -ne "\033"`
  102.         cSpace=`echo -ne "\040"`

  103.         #保存终端属性。在read -s读取终端键时,终端的属性会被暂时改变。
  104.         #如果在read -s时程序被不幸杀掉,可能会导致终端混乱,
  105.         #需要在程序退出时恢复终端属性。
  106.         sTTY=`stty -g`

  107.         #捕捉退出信号
  108.         trap "MyExit;" INT TERM
  109.         trap "MyExitNoSub;" $sigExit
  110.         trap "DoConsumeLine;" $sigConsume

  111.         #隐藏光标
  112.         echo -ne "\033[?25l"


  113.         while :
  114.         do
  115.         #读取输入。注-s不回显,-n读到一个字符立即返回
  116.                 read -s -n 1 key
  117.        
  118.                 aKey[0]=${aKey[1]}
  119.                 aKey[1]=${aKey[2]}
  120.                 aKey[2]=$key
  121.                
  122.                 sig=0

  123.                 #判断输入了何种键
  124.                 if [[ $key == $cESC && ${aKey[1]} == $cESC ]]
  125.                 then
  126.                         #ESC键
  127.                         MyExit
  128.                 elif [[ ${aKey[0]} == $cESC && ${aKey[1]} == "[" ]]
  129.                 then
  130.                         if [[ $key == "A" ]]; then sig=$sigDown ; pid=${pidDisplayer2}               #<向上键>
  131.                         elif [[ $key == "B" ]]; then sig=$sigAllDown ; pid=${pidDisplayer2}     #<向下键>
  132.                         elif [[ $key == "D" ]]; then sig=$sigLeft ; pid=${pidDisplayer2}              #<向左键>
  133.                         elif [[ $key == "C" ]]; then sig=$sigRight; pid=${pidDisplayer2}               #<向右键>
  134.                         fi
  135.                 elif [[ $key == "P" || $key == "p" ]]; then sig=$sigRotate ;  pid=${pidDisplayer2}            #W, w
  136.                 elif [[ $key == "W" || $key == "w" ]]; then sig=$sigRotate ;  pid=${pidDisplayer1}            #W, w
  137.                 elif [[ $key == "S" || $key == "s" ]]; then sig=$sigAllDown ; pid=${pidDisplayer1}      #S, s
  138.                 elif [[ $key == "A" || $key == "a" ]]; then sig=$sigLeft ;  pid=${pidDisplayer1}        #A, a
  139.                 elif [[ $key == "D" || $key == "d" ]]; then sig=$sigRight ; pid=${pidDisplayer1}            #D, d
  140.                 elif [[ "[$key]" == "[]" ]]; then sig=$sigRotate ; pid=${pidDisplayer1}                       #空格键
  141.                 elif [[ $key == "Q" || $key == "q" ]]                                                         #Q, q
  142.                 then
  143.                         MyExit
  144.                 fi

  145.                 if [[ $sig != 0 ]]
  146.                 then
  147.                         #向另一进程发送消息
  148.                         kill -$sig ${pid}
  149.                 fi
  150.         done
  151. }

  152. #退出前的恢复
  153. function MyExitNoSub()
  154. {
  155.         local y

  156.         #kill another child
  157.         kill -$sigExit $pidDisplayer1 $pidDisplayer2 > /dev/null 2>&1
  158.         #恢复终端属性
  159.         stty $sTTY
  160.         ((y = iTop + iTrayHeight + 4))

  161.         #显示光标
  162.         echo -e "\033[?25h\033[${y};0H"

  163.         rm -rf /tmp/pipe*

  164.         exit
  165. }


  166. function MyExit()
  167. {
  168.         #通知显示进程需要退出
  169.         kill -$sigExit $pidDisplayer1
  170.         kill -$sigExit $pidDisplayer2

  171.         MyExitNoSub
  172. }

  173. function AddRandomLine()
  174. {
  175.         local iLineNum

  176.         read iLineNum <&8
  177.        
  178.         echo ${iLineNum} >> ./log.txt

  179.         (( iNeedAddRandLine = iNeedAddRandLine + iLineNum ))
  180. }

  181. function ProduceRandomLine()
  182. {
  183.         local iLineNum x y t1 t2 iMovLine

  184.         iLineNum=${iNeedAddRandLine}

  185.         (( iMovLine = iTrayHeight - iLineNum ))

  186.         #Move current map up
  187.         for ((y = 0; y < iTrayWidth * iMovLine ; y += iTrayWidth))
  188.         do
  189.                 for (( x = 0; x < iTrayWidth; x++ ))
  190.                 do
  191.                         (( t1 = x + y ))
  192.                         (( t2 = x + y + iLineNum * iTrayWidth ))
  193.                         iMap[${t1}]=${iMap[${t2}]}
  194.                 done
  195.         done

  196.         #And iLineNum random line
  197.         for (( x = 0 ; y < iTrayHeight * iTrayWidth ; y++))
  198.         do
  199.                 (( x = RANDOM % 2 ))
  200.                 if [ ${x} -eq 1 ] ; then
  201.                         iMap[${y}]=${colorTable[RANDOM % ${#colorTable[@]}]}
  202.                 else
  203.                         iMap[${y}]=-1
  204.                 fi
  205.         done

  206.         iNeedAddRandLine=0
  207. }

  208. function OpenNamedPipe()
  209. {
  210.         local pid

  211.         pid=${1}
  212.         while :
  213.         do
  214.                 if [ -p /tmp/pipe${pid} ] ; then
  215.                         break
  216.                 fi
  217.                 sleep 1
  218.         done
  219. }

  220. #处理显示和游戏流程的主函数
  221. function RunAsDisplayer()
  222. {
  223.         local sigThis iAddLine
  224.         InitDraw

  225.         OpenNamedPipe ${PPID}
  226.         exec 7<>/tmp/pipe${PPID}
  227.         OpenNamedPipe $$
  228.         exec 8<>/tmp/pipe$$

  229.         #挂载各种信号的处理函数
  230.         trap "sig=$sigRotate;" $sigRotate
  231.         trap "sig=$sigLeft;" $sigLeft
  232.         trap "sig=$sigRight;" $sigRight
  233.         trap "sig=$sigDown;" $sigDown
  234.         trap "sig=$sigAllDown;" $sigAllDown
  235.         trap "ShowExit;" $sigExit
  236.         trap "AddRandomLine;" $sigConsume

  237.         while :
  238.         do
  239.                 #根据当前的速度级iLevel不同,设定相应的循环的次数
  240.                 for ((i = 0; i < 21 - iLevel; i++))
  241.                 do
  242.                         sleep 0.02
  243.                         sigThis=$sig
  244.                         sig=0

  245.                         #根据sig变量判断是否接受到相应的信号
  246.                         if ((sigThis == sigRotate)); then BoxRotate;                #旋转
  247.                         elif ((sigThis == sigLeft)); then BoxLeft;                #左移一列
  248.                         elif ((sigThis == sigRight)); then BoxRight;                #右移一列
  249.                         elif ((sigThis == sigDown)); then BoxDown;                #下落一行
  250.                         elif ((sigThis == sigAllDown)); then BoxAllDown;        #下落到底
  251.                         fi
  252.                 done

  253.                 #kill -$sigDown $$
  254.                 BoxDown        #下落一行
  255.         done
  256. }


  257. #BoxMove(y, x), 测试是否可以把移动中的方块移到(x, y)的位置, 返回0则可以, 1不可以
  258. function BoxMove()
  259. {
  260.         local j i x y xTest yTest
  261.         yTest=$1
  262.         xTest=$2
  263.         for ((j = 0; j < 8; j += 2))
  264.         do
  265.                 ((i = j + 1))
  266.                 ((y = ${boxCur[$j]} + yTest))
  267.                 ((x = ${boxCur[$i]} + xTest))
  268.                 if (( y < 0 || y >= iTrayHeight || x < 0 || x >= iTrayWidth))
  269.                 then
  270.                         #撞到墙壁了
  271.                         return 1
  272.                 fi

  273.                 if ((${iMap[y * iTrayWidth + x]} != -1 ))
  274.                 then
  275.                         #撞到其他已经存在的方块了
  276.                         return 1
  277.                 fi
  278.         done
  279.        
  280.         return 0;
  281. }


  282. #将当前移动中的方块放到背景方块中去,
  283. #并计算新的分数和速度级。(即一次方块落到底部)
  284. function Box2Map()
  285. {
  286.         local j i x y xp yp line

  287.         #将当前移动中的方块放到背景方块中去
  288.         for ((j = 0; j < 8; j += 2))
  289.         do
  290.                 ((i = j + 1))
  291.                 ((y = ${boxCur[$j]} + boxCurY))
  292.                 ((x = ${boxCur[$i]} + boxCurX))
  293.                 ((i = y * iTrayWidth + x))
  294.                 iMap[$i]=$cBoxCur
  295.         done

  296.         #消去可被消去的行
  297.         line=0
  298.         for ((j = 0; j < iTrayWidth * iTrayHeight; j += iTrayWidth))
  299.         do
  300.                 for ((i = j + iTrayWidth - 1; i >= j; i--))
  301.                 do
  302.                         if ((${iMap[$i]} == -1)); then break; fi
  303.                 done
  304.                
  305.                 if ((i >= j)); then continue; fi

  306.                 ((line++))
  307.                 for ((i = j - 1; i >= 0; i--))
  308.                 do
  309.                         ((x = i + iTrayWidth))
  310.                         iMap[$x]=${iMap[$i]}
  311.                 done

  312.                 for ((i = 0; i < iTrayWidth; i++))
  313.                 do
  314.                         iMap[$i]=-1
  315.                 done
  316.         done
  317.        
  318.         if (( line == 0 && iNeedAddRandLine == 0 )); then return; fi

  319.         if (( line > 0 )) ; then
  320.                 kill -${sigConsume} ${PPID} && echo "$$ ${line}" >&7
  321.         else
  322.                 ProduceRandomLine
  323.         fi

  324.         #根据消去的行数line计算分数和速度级
  325.         ((x = iLeft + iTrayWidth * 2 + 7))
  326.         ((y = iTop + 11))
  327.         ((iScore += line * 2 - 1))
  328.        
  329.         #显示新的分数
  330.         echo -ne "\033[1m\033[3${cScoreValue}m\033[${y};${x}H${iScore}         "
  331.         if ((iScore % iScoreEachLevel < line * 2 - 1))
  332.         then
  333.                 if ((iLevel < 20))
  334.                 then
  335.                         ((iLevel++))
  336.                         ((y = iTop + 14))
  337.                         #显示新的速度级
  338.                         echo -ne "\033[3${cScoreValue}m\033[${y};${x}H${iLevel}        "
  339.                 fi
  340.         fi

  341.         echo -ne "\033[0m"
  342.         #重新显示背景方块
  343.         for ((y = 0; y < iTrayHeight; y++))
  344.         do
  345.                 ((yp = y + iTrayTop + 1))
  346.                 ((xp = iTrayLeft + 1))
  347.                 ((i = y * iTrayWidth))
  348.                
  349.                 echo -ne "\033[${yp};${xp}H"
  350.                 for ((x = 0; x < iTrayWidth; x++))
  351.                 do
  352.                         ((j = i + x))
  353.                         if ((${iMap[$j]} == -1))
  354.                         then
  355.                                 echo -ne "  "
  356.                         else
  357.                                 echo -ne "\033[1m\033[7m\033[3${iMap[$j]}m\033[4${iMap[$j]}m[]\033[0m"
  358.                         fi
  359.                 done
  360.         done
  361. }


  362. #下落一行
  363. function BoxDown()
  364. {
  365.         local y s
  366.         ((y = boxCurY + 1))                        #新的y坐标

  367.         if BoxMove $y $boxCurX                        #测试是否可以下落一行
  368.         then
  369.                 s="`DrawCurBox 0`"                #将旧的方块抹去
  370.                 ((boxCurY = y))
  371.                 s="$s`DrawCurBox 1`"                #显示新的下落后方块
  372.                 echo -ne $s
  373.         else
  374.                 #走到这儿, 如果不能下落了
  375.                 Box2Map                                #将当前移动中的方块贴到背景方块中
  376.                 RandomBox                        #产生新的方块
  377.         fi
  378. }

  379. #左移一列
  380. function BoxLeft()
  381. {
  382.         local x s
  383.         ((x = boxCurX - 1))
  384.        
  385.         if BoxMove $boxCurY $x
  386.         then
  387.                 s=`DrawCurBox 0`
  388.                 ((boxCurX = x))
  389.                 s=$s`DrawCurBox 1`
  390.                 echo -ne $s
  391.         fi
  392. }

  393. #右移一列
  394. function BoxRight()
  395. {
  396.         local x s
  397.         ((x = boxCurX + 1))

  398.         if BoxMove $boxCurY $x
  399.         then
  400.                 s=`DrawCurBox 0`
  401.                 ((boxCurX = x))
  402.                 s=$s`DrawCurBox 1`
  403.                 echo -ne $s
  404.         fi
  405. }


  406. #下落到底
  407. function BoxAllDown()
  408. {
  409.         local k j i x y iDown s
  410.         iDown=$iTrayHeight

  411.         #计算一共需要下落多少行
  412.         for ((j = 0; j < 8; j += 2))
  413.         do
  414.                 ((i = j + 1))
  415.                 ((y = ${boxCur[$j]} + boxCurY))
  416.                 ((x = ${boxCur[$i]} + boxCurX))
  417.                
  418.                 for ((k = y + 1; k < iTrayHeight; k++))
  419.                 do
  420.                         ((i = k * iTrayWidth + x))
  421.                         if (( ${iMap[$i]} != -1)); then break; fi
  422.                 done

  423.                 ((k -= y + 1))
  424.                 if (( $iDown > $k )); then iDown=$k; fi
  425.         done

  426.         s=`DrawCurBox 0`        #将旧的方块抹去
  427.         ((boxCurY += iDown))
  428.         s=$s`DrawCurBox 1`        #显示新的下落后的方块
  429.         echo -ne $s
  430.         Box2Map                #将当前移动中的方块贴到背景方块中
  431.         RandomBox        #产生新的方块
  432. }


  433. #旋转方块
  434. function BoxRotate()
  435. {
  436.         local iCount iTestRotate boxTest j i s
  437.         iCount=${countBox[$iBoxCurType]}        #当前的方块经旋转可以产生的样式的数目

  438.         #计算旋转后的新的样式
  439.         ((iTestRotate = iBoxCurRotate + 1))
  440.         if ((iTestRotate >= iCount))
  441.         then
  442.                 ((iTestRotate = 0))
  443.         fi

  444.         #更新到新的样式, 保存老的样式(但不显示)
  445.         for ((j = 0, i = (${offsetBox[$iBoxCurType]} + $iTestRotate) * 8; j < 8; j++, i++))
  446.         do
  447.                 boxTest[$j]=${boxCur[$j]}
  448.                 boxCur[$j]=${box[$i]}
  449.         done

  450.         if BoxMove $boxCurY $boxCurX        #测试旋转后是否有空间放的下
  451.         then
  452.                 #抹去旧的方块
  453.                 for ((j = 0; j < 8; j++))
  454.                 do
  455.                         boxCur[$j]=${boxTest[$j]}
  456.                 done
  457.                 s=`DrawCurBox 0`

  458.                 #画上新的方块
  459.                 for ((j = 0, i = (${offsetBox[$iBoxCurType]} + $iTestRotate) * 8; j < 8; j++, i++))
  460.                 do
  461.                         boxCur[$j]=${box[$i]}
  462.                 done
  463.                 s=$s`DrawCurBox 1`
  464.                 echo -ne $s
  465.                 iBoxCurRotate=$iTestRotate
  466.         else
  467.                 #不能旋转,还是继续使用老的样式
  468.                 for ((j = 0; j < 8; j++))
  469.                 do
  470.                         boxCur[$j]=${boxTest[$j]}
  471.                 done
  472.         fi
  473. }


  474. #DrawCurBox(bDraw), 绘制当前移动中的方块, bDraw为1, 画上, bDraw为0, 抹去方块。
  475. function DrawCurBox()
  476. {
  477.         local i j t bDraw sBox s
  478.         bDraw=$1

  479.         s=""
  480.         if (( bDraw == 0 ))
  481.         then
  482.                 sBox="\040\040"
  483.         else
  484.                 sBox="[]"
  485.                 s=$s"\033[1m\033[7m\033[3${cBoxCur}m\033[4${cBoxCur}m"
  486.         fi

  487.         for ((j = 0; j < 8; j += 2))
  488.         do
  489.                 ((i = iTrayTop + 1 + ${boxCur[$j]} + boxCurY))
  490.                 ((t = iTrayLeft + 1 + 2 * (boxCurX + ${boxCur[$j + 1]})))
  491.                 #\033[y;xH, 光标到(x, y)处
  492.                 s=$s"\033[${i};${t}H${sBox}"
  493.         done
  494.        
  495.         s=$s"\033[0m"
  496.         echo -n $s
  497. }


  498. #更新新的方块
  499. function RandomBox()
  500. {
  501.         local i j t

  502.         #更新当前移动的方块
  503.         iBoxCurType=${iBoxNewType}
  504.         iBoxCurRotate=${iBoxNewRotate}
  505.         cBoxCur=${cBoxNew}

  506.         for ((j = 0; j < ${#boxNew[@]}; j++))
  507.         do
  508.                 boxCur[$j]=${boxNew[$j]}
  509.         done


  510.         #显示当前移动的方块
  511.         if (( ${#boxCur[@]} == 8 ))
  512.         then
  513.                 #计算当前方块该从顶端哪一行"冒"出来
  514.                 for ((j = 0, t = 4; j < 8; j += 2))
  515.                 do
  516.                         if ((${boxCur[$j]} < t)); then t=${boxCur[$j]}; fi
  517.                 done
  518.                
  519.                 ((boxCurY = -t))
  520.                 for ((j = 1, i = -4, t = 20; j < 8; j += 2))
  521.                 do
  522.                         if ((${boxCur[$j]} > i)); then i=${boxCur[$j]}; fi
  523.                         if ((${boxCur[$j]} < t)); then t=${boxCur[$j]}; fi
  524.                 done
  525.                
  526.                 ((boxCurX = (iTrayWidth - 1 - i - t) / 2))
  527.                 #显示当前移动的方块
  528.                 echo -ne `DrawCurBox 1`

  529.                 #如果方块一出来就没处放,Game over!
  530.                 if ! BoxMove $boxCurY $boxCurX
  531.                 then
  532.                         kill -$sigExit ${PPID}
  533.                         ShowExit
  534.                 fi
  535.         fi

  536.         #清除右边预显示的方块
  537.         for ((j = 0; j < 4; j++))
  538.         do
  539.                 ((i = iTop + 1 + j))
  540.                 ((t = iLeft + 2 * iTrayWidth + 7))
  541.                 echo -ne "\033[${i};${t}H        "
  542.         done

  543.         #随机产生新的方块
  544.         ((iBoxNewType = RANDOM % ${#offsetBox[@]}))
  545.         ((iBoxNewRotate = RANDOM % ${countBox[$iBoxNewType]}))
  546.         for ((j = 0, i = (${offsetBox[$iBoxNewType]} + $iBoxNewRotate) * 8; j < 8; j++, i++))
  547.         do
  548.                 boxNew[$j]=${box[$i]};
  549.         done

  550.         ((cBoxNew = ${colorTable[RANDOM % ${#colorTable[@]}]}))

  551.         #显示右边预显示的方块
  552.         echo -ne "\033[1m\033[7m\033[3${cBoxNew}m\033[4${cBoxNew}m"
  553.         for ((j = 0; j < 8; j += 2))
  554.         do
  555.                 ((i = iTop + 1 + ${boxNew[$j]}))
  556.                 ((t = iLeft + 2 * iTrayWidth + 7 + 2 * ${boxNew[$j + 1]}))
  557.                 echo -ne "\033[${i};${t}H[]"
  558.         done
  559.         echo -ne "\033[0m"
  560. }


  561. #初始绘制
  562. function InitDraw()
  563. {
  564.         #clear
  565.         RandomBox        #随机产生方块,这时右边预显示窗口中有方快了
  566.         RandomBox        #再随机产生方块,右边预显示窗口中的方块被更新,原先的方块将开始下落
  567.         local i t1 t2 t3

  568.         #显示边框
  569.         echo -ne "\033[1m"
  570.         echo -ne "\033[3${cBorder}m\033[4${cBorder}m"

  571.         ((t2 = iLeft + 1))
  572.         ((t3 = iLeft + iTrayWidth * 2 + 3))
  573.         for ((i = 0; i < iTrayHeight; i++))
  574.         do
  575.                 ((t1 = i + iTop + 2))
  576.                 echo -ne "\033[${t1};${t2}H||"
  577.                 echo -ne "\033[${t1};${t3}H||"
  578.         done

  579.         ((t2 = iTop + iTrayHeight + 2))
  580.         for ((i = 0; i < iTrayWidth + 2; i++))
  581.         do
  582.                 ((t1 = i * 2 + iLeft + 1))
  583.                 echo -ne "\033[${iTrayTop};${t1}H=="
  584.                 echo -ne "\033[${t2};${t1}H=="
  585.         done
  586.        
  587.         echo -ne "\033[0m"

  588.         #显示"Score"和"Level"字样
  589.         echo -ne "\033[1m"
  590.         ((t1 = iLeft + iTrayWidth * 2 + 7))
  591.         ((t2 = iTop + 10))
  592.         echo -ne "\033[3${cScore}m\033[${t2};${t1}HScore"
  593.         ((t2 = iTop + 11))
  594.         echo -ne "\033[3${cScoreValue}m\033[${t2};${t1}H${iScore}"
  595.         ((t2 = iTop + 13))
  596.         echo -ne "\033[3${cScore}m\033[${t2};${t1}HLevel"
  597.         ((t2 = iTop + 14))
  598.         echo -ne "\033[3${cScoreValue}m\033[${t2};${t1}H${iLevel}"
  599.         echo -ne "\033[0m"
  600. }


  601. #退出时显示GameOVer!
  602. function ShowExit()
  603. {
  604.         local y
  605.         ((y = iTrayHeight + iTrayTop + 3))
  606.         echo -e "\033[${y};0HGameOver!\033[0m"
  607.         exit
  608. }


  609. #显示用法.
  610. function Usage
  611. {
  612.         cat << EOF
  613.                 Usage: $APP_NAME
  614.                 Start tetris game.
  615.                 -h, --help              display this help and exit
  616.                 --version           output version information and exit
  617. EOF
  618. }

  619. #游戏主程序在这儿开始.
  620. if [[ "$1" == "-h" || "$1" == "--help" ]]; then
  621.         Usage
  622. elif [[ "$1" == "--version" ]]; then
  623.         echo "$APP_NAME $APP_VERSION"
  624. elif [[ "$1" == "--show" ]]; then
  625.         #当发现具有参数--show时,运行显示函数
  626.         iLeft=$2
  627.         iTop=$3
  628.         (( iTrayLeft = iLeft + 2 ))
  629.         (( iTrayTop = iTop + 1 ))
  630.         RunAsDisplayer
  631. else
  632.         clear
  633.         CreateNamedPipe $$
  634.         exec 7<> /tmp/pipe$$
  635.         bash $0 --show ${iLeft} ${iTop} &        #以参数--show将本程序再运行一遍
  636.         iPid1=$!

  637.         (( iLeft = iLeft + 50 ))
  638.         bash $0 --show ${iLeft} ${iTop} &        #以参数--show将本程序再运行一遍
  639.         iPid2=$!
  640.         CreateNamedPipe ${iPid1}
  641.         exec 8<> /tmp/pipe${iPid1}
  642.         CreateNamedPipe ${iPid2}
  643.         exec 9<> /tmp/pipe${iPid2}

  644.         RunAsKeyReceiver ${iPid1} ${iPid2}       #以上一行产生的进程的进程号作为参数
  645. fi
复制代码

论坛徽章:
0
15 [报告]
发表于 2008-06-03 10:57 |只看该作者
不错~~~

论坛徽章:
1
2015年迎新春徽章
日期:2015-03-04 09:48:31
16 [报告]
发表于 2008-06-03 14:16 |只看该作者
赞一下,不错
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP