Heim  >  Artikel  >  php教程  >  shell中俄罗斯方块

shell中俄罗斯方块

WBOY
WBOYOriginal
2016-06-13 10:33:051061Durchsuche

#!/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 $cWhite)

#位置和大小
iLeft=3
iTop=2
((iTrayLeft = iLeft + 2))
((iTrayTop = iTop + 1))
((iTrayWidth = 10))
((iTrayHeight = 15))

#颜色设置
cBorder=$cGreen
cScore=$cFuchsia
cScoreValue=$cCyan

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

#七中不同的方块的定义
#通过旋转,每种方块的显示的样式可能有几种
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, 表示没有方块
for ((i = 0; i

#接收输入的进程的主函数
function RunAsKeyReceiver()
{
  local pidDisplayer key aKey sig cESC sTTY

  pidDisplayer=
  aKey=(0 0 0)

  cESC=`echo -ne ""`
  cSpace=`echo -ne ""`

  #保存终端属性。在read -s读取终端键时,终端的属性会被暂时改变。
  #如果在read -s时程序被不幸杀掉,可能会导致终端混乱,
  #需要在程序退出时恢复终端属性。
  sTTY=`stty -g`
 
  #捕捉退出信号
  trap "MyExit;" INT TERM
  trap "MyExitNoSub;" $sigExit
 
  #隐藏光标
  echo -ne "[?25l"

 
  while (( 1 ))
  do
    #读取输入。注-s不回显,-n读到一个字符立即返回
    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不同,设定相应的循环的次数
    for ((i = 0; 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), 测试是否可以把移动中的方块移到(x, y)的位置, 返回0则可以, 1不可以
function BoxMove()
{
  local j i x y xTest yTest
  yTest=
  xTest=
  for ((j = 0; j   do
    ((i = j + 1))
    ((y = $ + yTest))
    ((x = $ + xTest))
    if (( y = iTrayHeight || x = iTrayWidth))
    then
      #撞到墙壁了
      return 1
    fi
    if ((${iMap[y * iTrayWidth + x]} != -1 ))
    then
      #撞到其他已经存在的方块了
      return 1
    fi
  done
  return 0;
}


#将当前移动中的方块放到背

Stellungnahme:
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn