#!/bin/bash
# Tetris Game
# 10.21.2003 Xhchen
#颜色定义
Cred=1
cgreen=2
Cyellow=3
Cblue=4
Cfuchsia=5
Ccyan=6
Cwhite=7
colortable= ($cRed $cGreen $cYellow $cBlue $cFuchsia $cCyan)
#位置和大小
Ileft=3
itop=2
((Itrayleft = ILeft + 2))
((itraytop = iTop + 1))
((Itraywidth = 10))
((itrayheight = 15))
#颜色设置
Cborder= $cGreen
Cscore= $cFuchsia
cscorevalue= $cCyan
#控制信号
#改游戏使用两个进程, one for receiving input, one for game flow and display interface;
#当前者接收到上下左右等按键时, inform the latter by sending signal to the latter.
Sigrotate=25
Sigleft=26
Sigright=27
Sigdown=28
sigalldown=29
Sigexit=30
#七中不同的方块的定义
#通过旋转, there may be several types of styles for each block's display
box0= (0 0 0 1 1 0 1 1)
box1= (0 2 1 2 2 2 3 2 1 0 1 1 1 2 1 3)
Box2= (0 0 0 1 1 1 1 2 0 1 1 0 1 1 2 0)
box3= (0 1 0 2 1 0 1 1 0 0 1 0 1 1 2 1)
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)
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)
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)
#所有其中方块的定义都放到box变量中
Box= ($ $ $ $ $ $ $ $)
#各种方块旋转后可能的样式数目
countbox= (1 2 2 2 4 4 4)
#各种方块再box数组中的偏移
offsetbox= (0 1 3 5 7 11 15)
#每提高一个速度级需要积累的分数
ISCOREEACHLEVEL=50 #be Greater than 7
#运行时数据
Sig=0 #接收到的signal
Iscore=0 #总分
Ilevel=0 #速度级
boxnew= () #新下落的方块的位置定义
Cboxnew=0 #新下落的方块的颜色
Iboxnewtype=0 #新下落的方块的种类
Iboxnewrotate=0 #新下落的方块的旋转角度
Boxcur= () #当前方块的位置定义
Cboxcur=0 #当前方块的颜色
Iboxcurtype=0 #当前方块的种类
Iboxcurrotate=0 #当前方块的旋转角度
Boxcurx=-1 #当前方块的x坐标位置
Boxcury=-1 #当前方块的y坐标位置
imap= () #背景方块图表
#初始化所有背景方块为-1, indicates no block
for ((i = 0; i < itrayheight * itraywidth; i++)); Do imap[$i]=-1; Done
#接收输入的进程的主函数
function Runaskeyreceiver ()
{
Local Piddisplayer key Akey Sig Cesc STTY
Piddisplayer=
akey= (0 0 0)
cesc= ' Echo-ne ' "'
Cspace= ' Echo-ne ' "'
#保存终端属性. When Read-s reads the terminal key, the terminal's properties are temporarily changed.
#如果在read-S program is unfortunately killed, may cause terminal confusion,
#需要在程序退出时恢复终端属性.
Stty= ' Stty-g '
#捕捉退出信号
Trap "MYEXIT;" INT term
Trap "MYEXITNOSUB;" $sigExit
#隐藏光标
Echo-ne "[? 25l"
while ((1))
Do
#读取输入. Note-S does not echo,-N reads to a character immediately returns
Read-s-N 1 key
akey[0]=$
akey[1]=$
akey[2]= $key
Sig=0
#判断输入了何种键
if [[$key = = $cESC && $ = = $cESC]]
Then
#ESC键
Myexit
elif [[$ = = $cESC && $ = = "["]]
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
#向另一进程发送消息
kill-$sig $pidDisplayer
Fi
Done
}
#退出前的恢复
function Myexitnosub ()
{
Local Y
#恢复终端属性
Stty $sTTY
(y = iTop + itrayheight + 4))
#显示光标
Echo-e "[? 25h[$;0h"
Exit
}
function Myexit ()
{
#通知显示进程需要退出
kill-$sigExit $pidDisplayer
Myexitnosub
}
#处理显示和游戏流程的主函数
function Runasdisplayer ()
{
Local Sigthis
Initdraw
#挂载各种信号的处理函数
Trap "sig= $sigRotate;" $sigRotate
Trap "sig= $sigLeft;" $sigLeft
Trap "sig= $sigRight;" $sigRight
Trap "sig= $sigDown;" $sigDown
Trap "sig= $sigAllDown;" $sigAllDown
Trap "SHOWEXIT;" $sigExit
while ((1))
Do
#根据当前的速度级iLevel不同, set the number of times for the corresponding loop
for ((i = 0; i < 21-ilevel; i++))
Do
Sleep 0.02
sigthis= $sig
Sig=0
#根据sig变量判断是否接受到相应的信号
if ((Sigthis = = sigrotate)); Then boxrotate; #旋转
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
}
#BoxMove (y, x), test whether the moving block can be moved to the position (x, y), return 0, 1 can not
function Boxmove ()
{
Local j I x y xTest ytest
ytest=
xtest=
for ((j = 0; J < 8; J + = 2))
Do
((i = j + 1))
((y = $ + ytest))
((x = $ + xTest))
if ((Y < 0 | | y >= itrayheight | | x < 0 | | x >= itraywidth))
Then
#撞到墙壁了
Return 1
Fi
if ((${imap[y * itraywidth + x]}! =-1))
Then
#撞到其他已经存在的方块了
Return 1
Fi
Done
return 0;
}
#将当前移动中的方块放到背
http://www.bkjia.com/PHPjc/508515.html www.bkjia.com true http://www.bkjia.com/PHPjc/508515.html techarticle #!/bin/bash # Tetris Game # 10.21.2003 xhchenxhchen@winbond.com.tw #颜色定义 cred=1 cgreen=2 cyellow=3 cblue=4 cfuchsia=5 Ccyan=6 cwhite=7 colortable= ($cRed $cGreen $cYellow $c ...