shell游戏:贪吃蛇 修正版
发表于:2007-05-26来源:作者:点击数:
标签:
shell游戏:贪吃蛇 期待各位帮忙测试,如有BUG,请及时告知,谢谢 转载请保持版权声明完整,十分感谢 下载代码: [url]http://bitbull.cn/works/snake[/url] 六关卡屏幕截图: [url]http://bitbull.cn/pic/blog/2005072801.jpg[/url] [url]http://bitbull.cn/pic/bl
shell游戏:贪吃蛇
期待各位帮忙测试,如有BUG,请及时告知,谢谢
转载请保持版权声明完整,十分感谢
下载代码:
[url]http://bitbull.cn/works/snake[/url]
六关卡屏幕截图:
[url]http://bitbull.cn/pic/blog/2005072801.jpg[/url]
[url]http://bitbull.cn/pic/blog/2005072802.jpg[/url]
[url]http://bitbull.cn/pic/blog/2005072803.jpg[/url]
[url]http://bitbull.cn/pic/blog/2005072804.jpg[/url]
[url]http://bitbull.cn/pic/blog/2005072805.jpg[/url]
[url]http://bitbull.cn/pic/blog/2005072806.jpg[/url]
[color=red:14850b6c0a]由于程序运行过程中会产生己个临时文件,
请先确定/tmp目录可写可读..如果权限不够或无此目录,请把游戏
cpath="/tmp/snake_ctrl_pid.tmp"
dpath="/tmp/snake_disply_pid.tmp"
vartmp="/tmp/snake_var_tmpfile.tmp"
改到有权限读写的目录[/color:14850b6c0a]
测试环境:
RHEL4 AS
bash 3.0
80x24终端
usage:
w上 s下 a左 d右
p暂停
n新游戏
q退出
规则:
吃完屏幕上所有的红色果实即可过关,共有6个关卡.碰到任何障碍蛇都将死亡,玩家有4次生命.
代码:
[code:1:14850b6c0a]#!/bin/bash
#-------------CopyRight-------------
# Name:Snake
# Version Number:1.00
# Type:game
# Language:bash shell
# Date:2005-07-28
# Author:BitBull
# Email:wengjianyi@tom.com
#------------Environment------------
# Terminal: column 80 line 24
#
Linux 2.6.9 i686
# GNU Bash 3.00.15
#-----------------------------------
#--------------variable--------------
#game variable
level=1
score=0
life=3
length=8
runtime=0.15
fruitspare=8
#game kernel variable
x=2 #init snake x=2 y=2
y=2
direction=0
shead=1 #snake's head in snake[]
stail=1 #snake's tail in snake[]
mappoint=1 #point exactmap[] bottom
state=on #snake run or stop
run=off #if run=on,snake shadow is working
displaypid=""
controlpid=""
#game temp file;if your system's /tmp unwrite or unread, you can change to home
cpath="/tmp/snake_ctrl_pid.tmp"
dpath="/tmp/snake_disply_pid.tmp"
vartmp="/tmp/snake_var_tmpfile.tmp"
#rename kill sign
pause=23
newgame=24
gameover=25
gameexit=26
up=27
down=28
left=29
right=22
#---------------array---------------
#init exactmap
exactmap=()
#map format: y x HowLong "-- or |" ( 1=| 2=-- )
map1=("6 14 6 2" "6 50 6 2" "14 14 6 2" "14 50 6 2")
map2=("2 16 10 1" "2 48 10 1" "7 32 10 1" "7 64 10 1")
map3=("4 16 24 2" "10 16 24 2" "16 16 24 2" "4 16 11 1")
map4=("10 4 34 2" "4 20 12 1" "4 40 12 1" "4 60 12 1")
map5=("5 10 29 2" "15 10 29 2" "5 16 7 1" "7 60 6 1" )
map6=("8 4 35 2" "2 50 5 1" "10 4 36 2" "11 30 5 1" )
#where is fruit? format:y x
fruit1=("14 10" "13 56" "2 40" "3 8" "17 50" "18 76" "14 30" "6 66")
fruit2=("4 14" "2 40" "14 48" "12 68" "9 30" "18 6" "3 76" "18 78")
fruit3=("7 14" "18 4" "15 40" "11 24" "5 18" "9 56" "3 76" "17 64")
fruit4=("11 10" "11 62" "9 38" "9 72" "6 58" "14 26" "17 58" "3 6")
fruit5=("6 14" "16 14" "3 40" "6 22" "14 58" "12 34" "8 50" "9 62")
fruit6=("2 52" "7 40" "7 60" "4 70" "11 28" "11 32" "15 22" "17 78" )
#--------------function--------------
#draw screen
function Draw_line () {
local i=1
while [ "$i" -le "80" ]
do
echo -ne "\33[${1};${i}H*"
(( i++ ))
done
}
function Draw_row () {
local i=2
while [ "$i" -le "22" ]
do
echo -ne "\33[${i};${1}H*"
(( i++ ))
done
}
function Draw_help () {
echo -ne "\33[7;31m\33[24;1HPlay:w s a d Pause:p Newgame:n Quit:q -- CopyRight -- 2005-07-28 BitBull --\33[0m"
}
function Screen () {
echo -ne "\33[37;44m"
Draw_line 1
Draw_line 19
Draw_line 23
Draw_row 1
Draw_row 80
echo -ne "\33[0m"
Draw_help
}
#init
function Init () {
stty_save=$(stty -g) #backup stty
clear
trap "Game_exit;" 2 15
stty -echo
echo -ne "\33[?25l" #hidden cursor
}
#exit
function Game_exit () {
kill -9 $displaypid>/dev/null 2>&1 #kill display function
#restore
stty $stty_save
stty echo
clear
trap 2 15
echo -ne "\33[?25h\33[0;0H\33[0m"
rm -f $cpath $dpath >/dev/null 2>&1
exit 0
}
#draw level score life SnakeLong
function Draw_ls () {
echo -ne "\33[31m"
echo -ne "\33[21;10HLevel=$level Score=$score \
Life=$life Snake=$length"
echo -ne "\33[0m"
}
#output info to player
function Info () {
title="$1"
content="$2"
greeting="$3"
printf "\33[31m"
printf "\33[11;20H ------------------------------------------- "
printf "\33[12;20H| ======>$title<====== |"
printf "\33[13;20H| $content |"
printf "\33[14;20H| ======>$greeting<====== |"
printf "\33[15;20H ------------------------------------------- "
printf "\33[0m"
}
#square:draw square in screen.you can define X Y COLOR LETTER
function Square () {
local color=$1;line=$2;row=$3;pic=$4
echo -ne "\33[34444;${color}m\33[${line};${row}H${pic}\33[0m"
}
#show fruit
function Show_fruits () {
local red=45;fruitxy=""
for (( i = 0; i < 8; i++ ))
do
fruitxy="$(printf "\${fruit%s[$i]}" $level)"
eval Square $red $fruitxy '@@'
done
}
#exact map:calculate mapXY into exactmap[]
function Exact_map () {
local mapin xtmp ytmp long line_row
for (( i = 0; i < 4; i++ ))
do
mapin="$(printf "\${map%s[$i]}" $level)"
xtmp=$(eval echo $mapin|cut -d" " -f2)
ytmp=$(eval echo $mapin|cut -d" " -f1)
long=$(eval echo $mapin|cut -d" " -f3)
line_row=$(eval echo $mapin|cut -d" " -f4)
exactmap[$mappoint]="$ytmp $xtmp"
(( mappoint++ ))
#judge mapline | or --
if [[ "$line_row" == "1" ]]
then
for (( j = 0; j <= long; j++ ))
do
(( ytmp++ ))
exactmap[$mappoint]="$ytmp $xtmp"
(( mappoint++ ))
done
else
for (( k = 0; k <= long; k++ ))
do
(( xtmp += 2 ))
exactmap[$mappoint]="$ytmp $xtmp"
(( mappoint++ ))
done
fi
done
}
#show map
function Show_map () {
local mapxy="";blue=46
Exact_map
for (( i = 1; i < mappoint; i++ ))
do
eval Square $blue ${exactmap[$i]} '[]'
done
}
#test snake is ok ?
function Test_snake () {
#snake self
for (( i = 1; i <= length; i++ ))
do
if [[ "${snake[$i]}" == "$y $x" ]]
then Dead
fi
done
#borderline
if [[ $x -lt 2 || $x -gt 79 || $y -lt 2 || $y -gt 18 ]]
then Dead
fi
#map line
for (( i = 0; i < mappoint; i++ ))
do
if [[ "${exactmap[$i]}" == "$y $x" ]]
then Dead
fi
done
}
#eat
function Eat () {
local fruitxy="";xyvalue="";nowarray=""
for (( i = 0; i < 8; i++ ))
do
fruitxy="$(printf "\${fruit%s[$i]}" $level)"
xyvalue="$(eval echo $fruitxy)"
if [[ "$xyvalue" = "$y $x" ]]
then
nowarray="$(printf "fruit%s[$i]=" $level)"
eval $nowarray""
(( score++ ))
(( fruitspare-- ))
Draw_ls
fi
done
if [[ $fruitspare == 0 ]]
then Next_level
fi
}
#if snake dead
function Dead () {
state=off
if (( "$life" == "0" ))
then
kill -$gameover $controlpid
else
(( life-- ))
Info "SnakeDead" "OH!shit!You are a idiot!" "F**k You"
sleep 1
New_game
fi
}
#next level
function Next_level () {
(( level++ ))
(( length += 6 ))
if [[ $level -gt 6 ]]
then
Info "Well Done" " WOW!Congratulation! " "Thank You"
sleep 4
kill -$gameexit $controlpid
else
Info "Well Done" "Level Update! Go Level $level" ".Loading."
sleep 3
New_game
fi
}
#newgame
function New_game () {
kill -9 $displaypid >/dev/null 2>&1
if [[ "$1" == "over" ]]
then
exec $0
else
echo "$level $score $life $length $runtime" > $vartmp
exec $0 display
fi
}
#game over
function Game_over () {
local y_n
Info "Game Over" "Do you w
ant replay?<y/n>" "Thank You"
while read -s -n 1 y_n
do
case $y_n in
[yY] ) New_game over
;;
[nN] ) Game_exit
;;
* ) continue
;;
esac
done
}
#main
function Main () {
local green=42;count=0
case $direction in
"$up" ) (( y-- ))
;;
"$down" ) (( y++ ))
;;
"$left" ) (( x -= 2 ))
;;
"$right" ) (( x += 2 ))
;;
*):
;;
esac
Test_snake
Eat
#go go go
Square $green $y $x \#\#
snake[$shead]="$y $x"
(( shead++ ))
if [[ "$shead" == "$length" ]]
then
shead=1
run=on #snake shadow run
fi
#snake shadow,it can erase snake's tail,otherwise,snake will very long!
if [[ "$run" == "on" ]]
then
Square 0 ${snake[$stail]} " "
(( stail++ ))
if [[ "$stail" == "$length" ]]
then
stail=1
fi
fi
}
#state change:off=snake stop.on=snake run
function State_change () {
if [[ $state == "on" ]]
then state=off
else state=on
fi
}
#display
function Display () {
trap "State_change;" $pause
trap "direction=$up;" $up
trap "direction=$down;" $down
trap "direction=$left;" $left
trap "direction=$right;" $right
echo $$ > $dpath
read controlpid < $cpath
if [[ -e $vartmp ]]
then
read level score life length runtime< $vartmp
rm -f $vartmp
fi
#drow all
Init
Screen
Draw_ls
Show_fruits
Show_map
Main
#game main loop
while :
do
if [[ ( "$state" == "on" ) && ( "$direction" != "0" ) ]]
then
Main
sleep $runtime
fi
done
}
#control
function Control () {
local sign=""
echo $$ > $cpath
trap "Game_over;" $gameover
trap "Game_exit;" $gameexit
while read -s -n 1 key
do
case $key in
[wW]) sign="$up"
;;
[sS]) sign="$down"
;;
[aA]) sign="$left"
;;
[dD]) sign="$right"
;;
[pP]) sign="$pause"
;;
[nN]) New_game over
;;
[qQ]) Game_exit
;;
* ) continue 2
;;
esac
eval displaypid=$(cat $dpath)
kill -$sign $displaypid
done
}
#------------main----------------
if [[ "$1" == "display" ]]
then
Display
exit
else
bash $0 display&
Control
exit
fi
[/code:1:14850b6c0a]
寂寞烈火 回复于:2005-07-29 00:38:24
|
I 服了 U :mrgreen:
|
bitbull 回复于:2005-07-29 09:18:10
|
还是烈火兄好,亲一个,嘻嘻
好久没来了,现在很多人我都不认识了
|
秋池飞叶 回复于:2005-07-29 09:36:20
|
厉害~弄回去慢慢研究
|
jackylau 回复于:2005-07-29 12:29:30
|
我的bash是2.05.8,好像不能用哟! :cry:
|
bitbull 回复于:2005-07-29 12:59:19
|
啊~楼上的哥们,把bash 2.05的man导出一份给我看看好吗?我看看使用到了3.0的什么新特性,我测试环境是3.0
|
icesummit 回复于:2005-07-29 13:45:50
|
我的是bash2.03,man有5000多行,怎么给你?
PS,考哪里学校了?
|
bitbull 回复于:2005-07-29 15:22:30
|
发我邮箱?wengjianyi@tom.com
还是www.mofile.com开个空间,传上去给我地址
ice,考北京垃圾学校了,哎~~提这就不来精神
|
icesummit 回复于:2005-07-29 16:05:38
|
没什么,也就是点人事安排问题 :mrgreen:
主要就是不支持ksh那样的for循环。
|
bitbull 回复于:2005-07-29 17:55:49
|
我查了ice,bash2.05支持for (( )) 这种循环
我改了程序那些KILL信号的rename,你再试试
|
xwfang 回复于:2005-07-29 20:18:35
|
2.05版本的bash不支持sleep 小数的 0.15
|
herolyh 回复于:2005-08-01 14:33:10
|
我想问一下,在aix下怎么运行啊?
|
platinum 回复于:2005-08-01 14:51:24
|
[quote:6238698d38]
#if snake dead
function Dead () {
state=off
if (( "$life" == "0" ))
then
kill -$gameover $controlpid
else
(( life-- ))
[color=red:6238698d38]Info "SnakeDead" "OH!shit!You are a idiot!" [b:6238698d38]"F**k You"[/b:6238698d38][/color:6238698d38]
sleep 1
New_game
fi
}
[/quote:6238698d38]
汗。。。。。。。
另外,吃完东西不变长
每关要吃的东西位置都一样
这两点不好
|
dahai01 回复于:2005-08-01 17:01:07
|
强人.
不过对于象俺一样水平不怎么的的选手.希望作者能
画出这个程序的框架结构.便于理解和学习.
谢谢
|
likfan 回复于:2005-08-01 21:41:10
|
真厉害,学习中!
|
bitbull 回复于:2005-08-02 11:27:18
|
[quote:e4c1a3ad75="xwfang"]2.05版本的bash不支持sleep 小数的 0.15[/quote:e4c1a3ad75]
可以支持0.15
|
bitbull 回复于:2005-08-02 11:27:51
|
[quote:9d4229b2f8="herolyh"]我想问一下,在aix下怎么运行啊?[/quote:9d4229b2f8]
有bash和80X24的终端就行
|
bitbull 回复于:2005-08-02 11:33:54
|
[quote:a71213c320="platinum"]
汗。。。。。。。
另外,吃完东西不变长
每关要吃的东西位置都一样
这两点不好[/quote:a71213c320]
蛇是在每关过后才变长的,我考虑过一边走一边变长,这样实现了后会出现一些影响美观的东西,所以还是在关卡结束后加长
位置一样的,是fruit数组定义的,有空补充个随机生成果实位置的函数
:em18: 谢谢提醒~~
PS:那句话很不错吧,哈哈哈
|
< bitbull 回复于:2005-08-02 11:36:25
|
[quote:88511850b8="dahai01"]强人.
不过对于象俺一样水平不怎么的的选手.希望作者能
画出这个程序的框架结构.便于理解和学习.
谢谢[/quote:88511850b8]
分成2个进程,一个control,一个display
control用于接受输入,把输入的信号发送到display,display处理信号作出相应反应,其他没啥好讲的呀,跟着display读就对了
|
fzhye 回复于:2005-08-02 11:51:09
|
请教echo命令的终端显示问题,比如说如何隐藏光标 echo -ne "\33[?25l",?号代表什么意思,25代表什么?有没有详说文档呀(我现在只知道前景和背景如何显示)?希望楼主指点!谢谢!
|
我爱钓鱼 回复于:2005-08-02 12:06:54
|
强......学习.....
|
bitbull 回复于:2005-08-02 14:57:23
|
[quote:971d7a9e08="fzhye"]糯?硎裁匆馑?,25代表什么?有没有详说文档呀(我现在只知道前景和背景如何显示)?希望楼主指点!谢谢![/quote:971d7a9e08]
http://www.isthe.com/chongo/tech/comp/ansi_escapes.html
或者用"Ansi Escape Sequences"为key到google搜
|
xchen301 回复于:2005-08-02 15:13:47
|
顶~~~~~~~~~
实力又见长进了bitbull~呵呵:)
|
fzhye 回复于:2005-08-02 16:30:06
|
感谢楼主的指点!谢谢!
|
RainX 回复于:2005-08-05 15:32:30
|
刚才在freebsd下运行了一下,好像没什么文题
bash version : 2.05b
|
bitbull 回复于:2005-08-05 22:57:10
|
[quote:a666fd5c49="RainX"]刚才在freebsd下运行了一下,好像没什么文题
bash version : 2.05b[/quote:a666fd5c49]
是的,不是bash版本问题,是trap信号靠后,有的系统不支持的问题,前段时间已经解决,谢谢测试
|
sdclearcase/" target="_blank" >ccf 回复于:2005-08-08 10:43:05
|
SCO下bash 2.05出现以下错误,不能运行:
./snake: line 176: syntax error near unexpected token `(('
br>./snake: line 176: ` for (( i = 0; i < 8; i++ )) '
|
sdccf 回复于:2005-08-08 11:02:55
|
看来是操作系统的问题,SCO下即使使用bash3.0也运行不了。
|
惠繪洋 回复于:2005-08-08 11:08:29
|
好勁呀.. 要研究研究...thx
|
bitbull 回复于:2005-08-08 11:25:07
|
[quote:e3da57c1a1="sdccf"]SCO下bash 2.05出现以下错误,不能运行:
./snake: line 176: syntax error near unexpected token `(('
./snake: line 176: ` for (( i = 0; i < 8; i++ )) '[/quote:e3da57c1a1]
恩,应该是系统问题,BASH 2.05就能跑了
|
cqulzg 回复于:2005-08-08 15:45:54
|
嗯 ,不错 ,能够运行,RH9.0 ,bash version 2.05b,不过好象蛇运动不怎么流畅,不知道是不是我电脑问题
|
newcmd 回复于:2005-08-08 17:30:56
|
bash2.05b可以运行,佩服ing
|
原文转自:http://www.ltesting.net