作者:Just忽略我_559 | 来源:互联网 | 2017-06-27 08:06
把注释加进去了,可能不是很详尽,
只希望能把问题表现的清楚一点
感谢各位兄弟的捧场,
属于旧瓶装新酒了,呵呵
如果你的终端可以显示出颜色,效果会好点
运行于GNU bash, version 2.05a.0(1)-release (i686-pc-linux-gnu)
---------------------------------------------------
果然在新的ubuntu下不能运行了,需要将类似\33的地方改成\033,
感谢网友thinux和guotao_buaa帮忙修改,已经将新的代码补入。
1.#!/bin/bash
2.
3.# Tetris Game
4.# 10.21.2003 xhchen<[email]xhchen@winbond.com.tw[/email]>
5.
6.#APP declaration
7.APP_NAME="${0##*[\\/]}"
8.APP_VERSION="1.0"
9.
10.
11.#颜色定义
12.cRed=1
13.cGreen=2
14.cYellow=3
15.cBlue=4
16.cFuchsia=5
17.cCyan=6
18.cWhite=7
19.colorTable=($cRed $cGreen $cYellow $cBlue $cFuchsia $cCyan $cWhite)
20.
21.#位置和大小
22.iLeft=3
23.iTop=2
24.((iTrayLeft = iLeft + 2))
25.((iTrayTop = iTop + 1))
26.((iTrayWidth = 10))
27.((iTrayHeight = 15))
28.
29.#颜色设置
30.cBorder=$cGreen
31.cScore=$cFuchsia
32.cScoreValue=$cCyan
33.
34.#控制信号
35.#改游戏使用两个进程,一个用于接收输入,一个用于游戏流程和显示界面;
36.#当前者接收到上下左右等按键时,通过向后者发送signal的方式通知后者。
37.sigRotate=25
38.sigLeft=26
39.sigRight=27
40.sigDown=28
41.sigAllDown=29
42.sigExit=30
43.
44.#七中不同的方块的定义
45.#通过旋转,每种方块的显示的样式可能有几种
46.box0=(0 0 0 1 1 0 1 1)
47.box1=(0 2 1 2 2 2 3 2 1 0 1 1 1 2 1 3)
48.box2=(0 0 0 1 1 1 1 2 0 1 1 0 1 1 2 0)
49.box3=(0 1 0 2 1 0 1 1 0 0 1 0 1 1 2 1)
50.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)
51.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)
52.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)
53.#所有其中方块的定义都放到box变量中
54.box=(${box0[@]} ${box1[@]} ${box2[@]} ${box3[@]} ${box4[@]} ${box5[@]} ${box6[@]})
55.#各种方块旋转后可能的样式数目
56.countBox=(1 2 2 2 4 4 4)
57.#各种方块再box数组中的偏移
58.offsetBox=(0 1 3 5 7 11 15)
59.
60.#每提高一个速度级需要积累的分数
61.iScoreEachLevel=50 #be greater than 7
62.
63.#运行时数据
64.sig=0 #接收到的signal
65.iScore=0 #总分
66.iLevel=0 #速度级
67.boxNew=() #新下落的方块的位置定义
68.cBoxNew=0 #新下落的方块的颜色
69.iBoxNewType=0 #新下落的方块的种类
70.iBoxNewRotate=0 #新下落的方块的旋转角度
71.boxCur=() #当前方块的位置定义
72.cBoxCur=0 #当前方块的颜色
73.iBoxCurType=0 #当前方块的种类
74.iBoxCurRotate=0 #当前方块的旋转角度
75.boxCurX=-1 #当前方块的x坐标位置
76.boxCurY=-1 #当前方块的y坐标位置
77.iMap=() #背景方块图表
78.
79.#初始化所有背景方块为-1, 表示没有方块
80.for ((i = 0; i
81.
82.
83.#接收输入的进程的主函数
84.function RunAsKeyReceiver()
85.{
86. local pidDisplayer key aKey sig cESC sTTY
87.
88. pidDisplayer=$1
89. aKey=(0 0 0)
90.
91. cESC=`echo -ne "\033"`
92. cSpace=`echo -ne "\040"`
93.
94. #保存终端属性。在read -s读取终端键时,终端的属性会被暂时改变。
95. #如果在read -s时程序被不幸杀掉,可能会导致终端混乱,
96. #需要在程序退出时恢复终端属性。
97. sTTY=`stty -g`
98.
99. #捕捉退出信号
100. trap "MyExit;" INT TERM
101. trap "MyExitNoSub;" $sigExit
102.
103. #隐藏光标
104. echo -ne "\033[?25l"
105.
106.
107. while :
108. do
109. #读取输入。注-s不回显,-n读到一个字符立即返回
110. read -s -n 1 key
111.
112. aKey[0]=${aKey[1]}
113. aKey[1]=${aKey[2]}
114. aKey[2]=$key
115. sig=0
116.
117. #判断输入了何种键
118. if [[ $key == $cESC && ${aKey[1]} == $cESC ]]
119. then
120. #ESC键
121. MyExit
122. elif [[ ${aKey[0]} == $cESC && ${aKey[1]} == "[" ]]
123. then
124. if [[ $key == "A" ]]; then sig=$sigRotate #<向上键>
125. elif [[ $key == "B" ]]; then sig=$sigDown #<向下键>
126. elif [[ $key == "D" ]]; then sig=$sigLeft #<向左键>
127. elif [[ $key == "C" ]]; then sig=$sigRight #<向右键>
128. fi
129. elif [[ $key == "W" || $key == "w" ]]; then sig=$sigRotate #W, w
130. elif [[ $key == "S" || $key == "s" ]]; then sig=$sigDown #S, s
131. elif [[ $key == "A" || $key == "a" ]]; then sig=$sigLeft #A, a
132. elif [[ $key == "D" || $key == "d" ]]; then sig=$sigRight #D, d
133. elif [[ "[$key]" == "[]" ]]; then sig=$sigAllDown #空格键
134. elif [[ $key == "Q" || $key == "q" ]] #Q, q
135. then
136. MyExit
137. fi
138.
139. if [[ $sig != 0 ]]
140. then
141. #向另一进程发送消息
142. kill -$sig $pidDisplayer
143. fi
144. done
145.}
146.
147.#退出前的恢复
148.function MyExitNoSub()
149.{
150. local y
151.
152. #恢复终端属性
153. stty $sTTY
154. ((y = iTop + iTrayHeight + 4))
155.
156. #显示光标
157. echo -e "\033[?25h\033[${y};0H"
158. exit
159.}
160.
161.
162.function MyExit()
163.{
164. #通知显示进程需要退出
165. kill -$sigExit $pidDisplayer
166.
167. MyExitNoSub
168.}
169.
170.
171.#处理显示和游戏流程的主函数
172.function RunAsDisplayer()
173.{
174. local sigThis
175. InitDraw
176.
177. #挂载各种信号的处理函数
178. trap "sig=$sigRotate;" $sigRotate
179. trap "sig=$sigLeft;" $sigLeft
180. trap "sig=$sigRight;" $sigRight
181. trap "sig=$sigDown;" $sigDown
182. trap "sig=$sigAllDown;" $sigAllDown
183. trap "ShowExit;" $sigExit
184.
185. while :
186. do
187. #根据当前的速度级iLevel不同,设定相应的循环的次数
188. for ((i = 0; i <21 - iLevel; i++))
189. do
190. sleep 0.02
191. sigThis=$sig
192. sig=0
193.
[1] [2] [3] 下一页