📄 tetris.bash
字号:
((COUNT+=1))done}#----------------------------------------------------------------------------------------## Clear the cache##----------------------------------------------------------------------------------------function Clear_Cache{typeset -i COUNT=0until [[ $COUNT -eq 250 ]]do let CACHE[$COUNT]=-1 ((COUNT+=1))done}#----------------------------------------------------------------------------------------## Draw BOARD array on canvas##----------------------------------------------------------------------------------------function Draw_Board{typeset -i X=0 Y=0 POS=0# Set canvas to drawu_draw $CANVAS# Check each positionuntil [[ $Y -gt 500 ]]do # Calculate position in array let POS=$X/20+$Y/2+10 # If position is occupied, draw if [[ ${BOARD[$POS]} -ne ${CACHE[$POS]} ]] then # If position is occupied, draw case ${BOARD[$POS]} in 0) u_square "#FFFFFF" $X $Y 20 20 1;; 1) u_square "#22CCCC" $X $Y 19 19 1;; 2) u_square "#FF2222" $X $Y 19 19 1;; 3) u_square "#22FF22" $X $Y 19 19 1;; 4) u_square "#DDDD00" $X $Y 19 19 1;; 5) u_square "#FF22FF" $X $Y 19 19 1;; 6) u_square "#FFA500" $X $Y 19 19 1;; 7) u_square "#2222FF" $X $Y 19 19 1;; esac # Copy to cache board CACHE[$POS]=${BOARD[$POS]} fi # Go to next position in array ((X+=20)) if [[ $X -gt 180 ]] then X=0 ((Y+=20)) fidone# Draw text on canvas if pausedif [[ $CONDITION -eq 1 ]]then u_out "\"'Game paused'\"" "#0000FF" "#FFFFFF" 60 200 u_out "\"'Press <p> to continue'\"" "#4444FF" "#FFFFFF" 35 240# Game overelif [[ $CONDITION -eq 2 ]]then POS=200 u_out "\"'Game over!'\"" "#0000FF" "#FFFFFF" 60 $POS # Check score define HIGH u_label_grab $HLABEL if [[ $HIGH -lt $SCORE ]] then ((POS+=40)) u_out "\"'New highscore: $SCORE'\"" "#4444FF" "#FFFFFF" 40 $POS # Save score echo $SCORE > $HOME/.tetris.sh fi ((POS+=40)) u_out "\"'Press refresh to start again'\"" "#0000FF" "#FFFFFF" 20 $POSfi}#----------------------------------------------------------------------------------------## Generate new piece, $1 contains piece##----------------------------------------------------------------------------------------function Draw_New{# Set canvas to drawu_draw $EXAMPLE# Wipe the preview canvasu_square "#FFFFFF" 0 0 100 60 1# Select piececase $1 in 1) u_square "#22CCCC" 10 20 19 19 1 u_square "#22CCCC" 30 20 19 19 1 u_square "#22CCCC" 50 20 19 19 1 u_square "#22CCCC" 70 20 19 19 1;; 2) u_square "#FF2222" 20 10 19 19 1 u_square "#FF2222" 40 10 19 19 1 u_square "#FF2222" 40 30 19 19 1 u_square "#FF2222" 60 30 19 19 1;; 3) u_square "#22FF22" 20 30 19 19 1 u_square "#22FF22" 40 30 19 19 1 u_square "#22FF22" 40 10 19 19 1 u_square "#22FF22" 60 10 19 19 1;; 4) u_square "#DDDD00" 30 10 19 19 1 u_square "#DDDD00" 50 10 19 19 1 u_square "#DDDD00" 30 30 19 19 1 u_square "#DDDD00" 50 30 19 19 1;; 5) u_square "#FF22FF" 20 10 19 19 1 u_square "#FF22FF" 40 10 19 19 1 u_square "#FF22FF" 60 10 19 19 1 u_square "#FF22FF" 40 30 19 19 1;; 6) u_square "#FFA500" 20 10 19 19 1 u_square "#FFA500" 40 10 19 19 1 u_square "#FFA500" 60 10 19 19 1 u_square "#FFA500" 20 30 19 19 1;; 7) u_square "#2222FF" 20 10 19 19 1 u_square "#2222FF" 40 10 19 19 1 u_square "#2222FF" 60 10 19 19 1 u_square "#2222FF" 60 30 19 19 1;;esac}#----------------------------------------------------------------------------------------## Generate new piece##----------------------------------------------------------------------------------------function New_Piece{# Define rotation of current pieceCUR_ROTATION=0; NEW_ROTATION=0; RAND=0# Get random numberuntil [[ $RAND -ne 0 ]]do ((RAND=${RANDOM}&7))done# Put current piece on BOARD arraycase $RAND in 1) FX=60; FY=0 Draw_New 1;; 2) FX=80; FY=0 Draw_New 2;; 3) FX=80; FY=20 Draw_New 3;; 4) FX=80; FY=0 Draw_New 4;; 5) FX=80; FY=0 Draw_New 5;; 6) FX=80; FY=0 Draw_New 6;; 7) FX=80; FY=0 Draw_New 7;;esac# Put back original timeout (if drop was active)u_timeout $WINDOW ${LEVELS[$CURLEVEL]}}#----------------------------------------------------------------------------------------## Check if there is a full row##----------------------------------------------------------------------------------------function Check_Row{typeset -i ROW X Z Y=1 POS=0 INC=10# Go through all the rowsuntil [[ $Y -eq 25 ]]do X=0; ROW=0 until [[ $X -eq 10 ]] do let POS=$X+$Y*10 if [[ ${BOARD[$POS]} -ne 0 ]] then ((ROW+=1)) fi ((X+=1)) done if [[ $ROW -eq 10 ]] then # More rows, higher level, more score! ((SCORE+=$INC*$CURLEVEL)) ((INC+=$INC)) ((GAMELINES-=1)) u_label_text $TLABEL $GAMELINES # Scroll field Z=$Y until [[ $Z -eq 0 ]] do X=0 until [[ $X -eq 10 ]] do let POS=$X+$Z*10 BOARD[$POS]=${BOARD[$POS-10]} ((X+=1)) done ((Z-=1)) done fi ((Y+=1))done# Check if next level is reachedif [[ $GAMELINES -le 0 ]]then GAMELINES=10 u_label_text $TLABEL $GAMELINES ((CURLEVEL+=1)) u_label_text $LLABEL $CURLEVEL # Setup timeout on the wait-event u_timeout $WINDOW ${LEVELS[$CURLEVEL]}fi}#--------------------------------------------------------------------- Main program# Save my directoryMYDIR=${0%/*}# Include the generated file to use embedded HUG functions. ${HOME}/.hug4bash# Check if we can play musicTIMIDITY=`which timidity 2>/dev/null`if [[ -z $TIMIDITY ]]then echo "Timidity not found, no music!"else # We can play music in the background $TIMIDITY -idl -A200 $MYDIR/tetris.mid >/dev/null & # Trap exitsignals to stop music trap 'kill -9 $!' QUIT EXIT TERMfi# Define the board array globallydeclare -a BOARDInit_Board# Define the board cachedeclare -a CACHEClear_Cache# Define levelsLEVELS=(0 500 400 320 256 204 164 132 116 93 75 60 48)# Define some variables globallytypeset -i CURX CURY NEWX NEWY FX FY RANDtypeset -i GAMELINES=10 PIECE=0 CONDITION=1 SCORE=0 CURLEVEL=1 CUR_ROTATION=0 NEW_ROTATION=0# Define GUI - mainwindowdefine WINDOW u_window "\"'Bash-Tris using H.U.G.'\"" 335 500u_bgcolor $WINDOW "#BBBBFF"define FRAME1 u_frame 210 490u_bgcolor $FRAME1 "#BBBBFF"u_attach $WINDOW $FRAME1 5 5define CANVAS u_canvas 200 480u_attach $WINDOW $CANVAS 10 10define FRAME2 u_frame 110 70u_bgcolor $FRAME2 "#BBBBFF"u_attach $WINDOW $FRAME2 220 5define EXAMPLE u_canvas 100 60u_attach $WINDOW $EXAMPLE 225 10define FRAME7 u_frame 110 50u_frame_text $FRAME7 "\"' Lines next level '\""u_fgcolor $FRAME7 "#0000FF"u_bgcolor $FRAME7 "#BBBBFF"u_attach $WINDOW $FRAME7 220 80define TLABEL u_label "10" 100 20 "0.5" "0.5"u_fgcolor $TLABEL "#4444FF"u_attach $WINDOW $TLABEL 225 105define FRAME6 u_frame 110 50u_frame_text $FRAME6 "\"' Level '\""u_fgcolor $FRAME6 "#0000FF"u_bgcolor $FRAME6 "#BBBBFF"u_attach $WINDOW $FRAME6 220 140define LLABEL u_label "1" 100 20 "0.5" "0.5"u_fgcolor $LLABEL "#4444FF"u_attach $WINDOW $LLABEL 225 165define FRAME4 u_frame 110 50u_frame_text $FRAME4 "\"' Score '\""u_fgcolor $FRAME4 "#0000FF"u_bgcolor $FRAME4 "#BBBBFF"u_attach $WINDOW $FRAME4 220 200define SLABEL u_label "0" 100 20 "0.5" "0.5"u_fgcolor $SLABEL "#4444FF"u_attach $WINDOW $SLABEL 225 225define FRAME5 u_frame 110 50u_frame_text $FRAME5 "\"' Highscore '\""u_fgcolor $FRAME5 "#0000FF"u_bgcolor $FRAME5 "#BBBBFF"u_attach $WINDOW $FRAME5 220 260define HLABEL u_label "0" 100 20 "0.5" "0.5"u_fgcolor $HLABEL "#4444FF"u_attach $WINDOW $HLABEL 225 285define RESTART u_stock "gtk-refresh" 110 35u_bgcolor $RESTART "#8888FF" "#8888FF" "#AAAAFF"u_attach $WINDOW $RESTART 220 320u_unfocus $RESTARTdefine FRAME3 u_frame 110 90u_frame_text $FRAME3 "\"' Keys '\""u_fgcolor $FRAME3 "#0000FF"u_bgcolor $FRAME3 "#BBBBFF"u_attach $WINDOW $FRAME3 220 360define LABEL1 u_label "\"'cursor: move'\"" 100 20 "0.1" "0.5"u_fgcolor $LABEL1 "#4444FF"u_attach $WINDOW $LABEL1 225 385define LABEL2 u_label "\"'space: drop'\"" 100 20 "0.1" "0.5"u_fgcolor $LABEL2 "#4444FF"u_attach $WINDOW $LABEL2 225 405define LABEL3 u_label "\"'p key: pause'\"" 100 20 "0.1" "0.5"u_fgcolor $LABEL3 "#4444FF"u_attach $WINDOW $LABEL3 225 425define EXIT u_stock "gtk-quit" 110 35u_bgcolor $EXIT "#8888FF" "#8888FF" "#AAAAFF"u_attach $WINDOW $EXIT 220 460u_unfocus $EXIT# Set highscoreif [[ -f $HOME/.tetris.sh ]]then read VAL < $HOME/.tetris.sh u_label_text $HLABEL $VALfi# Setup timeout on the wait-eventu_timeout $WINDOW ${LEVELS[$CURLEVEL]}# Mainloopuntil [[ $EVENT = $EXIT || $KEY = 65307 ]]do define EVENT u_event # Determine event case $EVENT in "key-press-event") define KEY u_key # Determine action for a pressed key case $KEY in "65362") ((NEW_ROTATION=(${NEW_ROTATION}+1)&3));; "65364") ((NEW_ROTATION=(${NEW_ROTATION}-1)&3));; "65363") ((NEWX=$CURX+20));; "65361") if [[ $CURX -ge 20 ]] then ((NEWX=$CURX-20)) fi;; # Toggle PAUSE condition "112") if [[ $CONDITION -eq 1 ]] then CONDITION=0 Clear_Cache elif [[ $CONDITION -eq 0 ]] then CONDITION=1 fi;; # Drop the piece "32") u_timeout $WINDOW 30;; esac;; $WINDOW) if [[ $CONDITION -eq 0 ]] then ((NEWX=$CURX)) ((NEWY=$CURY+20)) fi;; $RESTART) PIECE=0 CONDITION=1 SCORE=0 CURLEVEL=1 u_label_text $LLABEL $CURLEVEL GAMELINES=10 u_label_text $TLABEL $GAMELINES if [[ -f $HOME/.tetris.sh ]] then read VAL < $HOME/.tetris.sh else VAL=0 fi u_label_text $HLABEL $VAL u_timeout $WINDOW ${LEVELS[$CURLEVEL]} Init_Board Clear_Cache;; esac # Put current piece on BOARD array case $PIECE in 1) Action_One;; 2) Action_Two;; 3) Action_Three;; 4) Action_Four;; 5) Action_Five;; 6) Action_Six;; 7) Action_Seven;; esac # Assign the new coordinates if [[ $PIECE -gt 0 ]] then CURX=$NEWX CURY=$NEWY CUR_ROTATION=$NEW_ROTATION ((ABLETOMOVE+=1)) # Check end game, check row and we need a new piece else if [[ $ABLETOMOVE -eq 0 && $CONDITION -eq 0 ]] then CONDITION=2 fi Check_Row PIECE=$RAND CURX=$FX; CURY=$FY; NEWX=$CURX; NEWY=$CURY New_Piece if [[ $CONDITION -eq 1 ]] then ((NEWY+=20)) fi ABLETOMOVE=0 fi # Finally, draw the array on the screen Draw_Board # Update score u_label_text $SLABEL $SCOREdone# Release graphical resourcesu_end
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -