设为首页 收藏本站
查看: 1224|回复: 0

脚本游戏之二: 贪吃蛇游戏新版

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2016-4-18 09:48:04 | 显示全部楼层 |阅读模式
最近看了一个shell写的游戏:俄罗斯方块(下方有下载),受其启发重写了之前的一个小游戏:贪吃蛇。
之前写的那个需要用到临时文件, 每个动作都需要多次读写,效率不行,看了别人的思路之后,很快就
重写一个。

以下变量定义了三部分内容:信号、边框属性和游戏本身PID,并对游戏等级做定义注释。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
#signal
upper=20
down=21
left=22
right=23
stop=24
stopI=25
pause=26
start=27
speedup=28
slowdown=29
quit=30

height=4
width=10
HEIGHT=20
WIDTH=30
upper_boundary=$((height+1))
down_boundary=$((height+HEIGHT+2))
left_boundary=$((width+1))
right_boundary=$((width+WIDTH+2))

MYPID=$$

#About the level and the score.
#time(s)  0.9 0.8 0.7 0.6 0.5 0.4 0.3 0.2 0.1 0.0
#level     1   2   3   4   5   6   7   8   9  10




display_random_point函数用来在特定区域得到并显示一随机块。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#get one random point in the border.
display_random_point(){
    local i succ=0
    while :; do
        while :; do
            point1=$((RANDOM%down_boundary))
            [[ $point1 -gt $upper_boundary ]] && [[ $point1 -lt $down_boundary ]] && break
        done
        while :; do
            point2=$((RANDOM%right_boundary))
            [[ $point2 -gt $left_boundary ]] && [[ $point1 -lt $right_boundary ]] && break
        done
        #for sure, not in the body points.
        for((i=0; i<${#snake_body[@]}; i++)); do
            [[ "$point1 $point2" == "${snake_body} ${snake_body[i+1]}" ]] && { succ=1; break; }
        done
        [[ $succ -eq 0 ]] && break
    done
    random_point=($point1 $point2)
    echo -ne "[${point1};${point2}H "
}



exit_game 退出游戏
1
2
3
4
5
6
7
exit_game(){
    kill -$stopI $MYPID
    tput cnorm
    echo -e "[$(((height+HEIGHT+2)/2));$(((width+WIDTH)/2))HSnake Dead !!"
    echo -e "[$((height+HEIGHT+3));$((width+WIDTH+3))H "
    exit
}



display_element  后台运行函数, 用来捕捉信号、显示游戏边框等信息以及移动蛇身
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
display_element(){
     
    #隐藏鼠标
    tput civis   #Hide cursor
     
    #捕捉信号
    trap 'DIRECTION=upper' $upper
    trap 'DIRECTION=down'  $down
    trap 'DIRECTION=left'  $left
    trap 'DIRECTION=right' $right
    trap 'STOP=1'          $stop
    trap 'IFPAUSE=1'       $pause
    trap 'IFPAUSE=0'       $start
    trap '((level++))'     $speedup
    trap '((level--))'     $slowdown
    trap 'exit_game'       $quit
         
    #定义部分局部变量
    score=0
    level=5
    STOP=0
    DIRECTION=right
    old_direction=$DIRECTION
    snake_body=( $((height+2)) $((width+2)) )
     
    #画边框
        local i
        for((i=height+1; i<=height+HEIGHT+2; i++))
        do
                echo -ne "[${i};$((width+1))H "
                echo -ne "[${i};$((width+WIDTH+2))H "
        done
        for((i=width+1; i<=width+WIDTH+2; i++))
        do
                echo -ne "[$((height+1));${i}H "
                echo -ne "[$((height+HEIGHT+2));${i}H "
        done
         
        #显示成绩、等级和运行状态
        echo -ne "[${snake_body[0]};${snake_body[1]}H "
        echo -ne "[$((height+2));$((width+WIDTH+3))H Score: $score"
        echo -ne "[$((height+4));$((width+WIDTH+3))H Level: $level"
        echo -ne "[$((height+6));$((width+WIDTH+3))H State: running"
    echo -ne "[${height};$((width+7))H[ Snake ] by LingYi"
    display_random_point
     
    #后台循环, 移动蛇身
    while [[ $STOP -ne 1 ]]
    do
        #不允许相反方向移动
        case $old_direction in
        'upper') [[ $DIRECTION == 'down'  ]] && DIRECTION=upper ;;
        'down' ) [[ $DIRECTION == 'upper' ]] && DIRECTION=down  ;;
        'left' ) [[ $DIRECTION == 'right' ]] && DIRECTION=left  ;;
        'right') [[ $DIRECTION == 'left'  ]] && DIRECTION=right ;;
        esac
         
        #得到新蛇头
        new_head[0]=${snake_body[$((${#snake_body[@]}-2))]}
        new_head[1]=${snake_body[$((${#snake_body[@]}-1))]}
        case $DIRECTION in
            'upper') ((new_head[0]-=1)) ;;
            'down' ) ((new_head[0]+=1)) ;;
            'left' ) ((new_head[1]-=1)) ;;
            'right') ((new_head[1]+=1)) ;;
        esac
     
        #判断边框碰撞
        case $DIRECTION in
        'upper') [[ ${new_head[0]} -eq $upper_boundary ]] && exit_game ;;
        'down' ) [[ ${new_head[0]} -eq $down_boundary  ]] && exit_game ;;
        'left' ) [[ ${new_head[1]} -eq $left_boundary  ]] && exit_game ;;
        'right') [[ ${new_head[1]} -eq $right_boundary ]] && exit_game ;;
        esac

        #判断蛇身碰撞
        local i
        for((i=0; i<${#snake_body[@]}; i++)); do
            [[ "${new_head[@]}" == "${snake_body} ${snake_body[i+1]}" ]] && exit_game
        done
         
        #暂停、继续
        while [[ $IFPAUSE -eq 1 ]]; do
            echo -ne "[$((height+6));$((width+WIDTH+3))H State: pause  "
        done
        echo -ne "[$((height+6));$((width+WIDTH+3))H State: running"

        #加速、减速
        if [[ $old_level != $level ]]; then
            echo -ne "[$((height+4));$((width+WIDTH+3))H Level: $level"
        fi
        old_level=$level

        #吃到随机块,显示成绩和级别信息
        if [[ ${new_head[@]} == ${random_point[@]} ]]; then
            snake_body=( ${snake_body[@]} ${new_head[@]} )
            display_random_point
            let score++
            [[ $((score%20)) -eq 0 ]] && let level++
            echo -ne "[$((height+2));$((width+WIDTH+3))H Score: $score"
            echo -ne "[$((height+4));$((width+WIDTH+3))H Level: $level"
        else
            echo -ne "[${snake_body[0]};${snake_body[1]}H "
                   snake_body=( $(echo ${snake_body[@]} | cut -d ' ' -f 3-) ${new_head[@]})
        fi
        echo -ne "[${new_head[0]};${new_head[1]}H "
        old_direction=$DIRECTION
        sleep 0.$((10-level))
    done
}



以下是运行主体代码, 主要是运行后台函数、捕捉按键和发送信号。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
clear
display_element &

back_pid=$!
trap 'EXIT=1' $stopI
trap 'kill -$stop $back_pid; stty echo; exit_game' 2

ESC=`echo -e ''`
while :; do
    read -s -n 1 key

    key=`echo $key | tr 'a-z' 'A-Z'`

    [[ $key == ''  ]] && sig=$pause    # 空格:暂停
    [[ $key == 'C' ]] && sig=$start     # C键:继续
    [[ $key == 'U' ]] && sig=$speedup    # U键:加速
    [[ $key == 'O' ]] && sig=$slowdown    # O键:减速
    [[ $key == 'Q' ]] && sig=$quit        #Q键:退出
         
    #改变移动方向
    [[ $key == 'W' ]] || [[ $key == 'I' ]] && sig=$upper
    [[ $key == 'S' ]] || [[ $key == 'K' ]] && sig=$down
    [[ $key == 'D' ]] || [[ $key == 'L' ]] && sig=$right
    [[ $key == 'A' ]] || [[ $key == 'J' ]] && sig=$left

    [[ $key == $ESC ]] && {
        for (( i=0; i<=1; i++ )); do read -s -n 1  KEY[$i]; done
        [[ ${KEY[0]} == $ESC  ]] && sig=$stop         
        [[ ${KEY[0]} == '['   ]] && {
            [[ ${KEY[1]} == 'A' ]] &&  sig=$upper
            [[ ${KEY[1]} == 'B' ]] &&  sig=$down
            [[ ${KEY[1]} == 'C' ]] &&  sig=$right
            [[ ${KEY[1]} == 'D' ]] &&  sig=$left
        }
      }
        #发送信号
    [[ $EXIT -ne 1 ]] && kill -$sig $back_pid || break
done




演示:
wKioL1bKvbHBC8raAAAUkIe_Ejs828.png

wKiom1bKvUagdUEnAAAYGs7dd_Y572.png


下载:

game_snake.rar (1.94 KB, 下载次数: 2)



运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-205470-1-1.html 上篇帖子: Powershell批量移除AD组成员 下篇帖子: 脚本游戏之三: 坦克大战 贪吃蛇 游戏
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表