dos界面实现贪吃蛇

windows可视化程序设计——贪吃蛇




#include<iostream>
#include<windows.h>
#include<conio.h>
#include<color.h>
#include<cstdlib>
#include<mmsystem.h>
#pragma comment(lib, "WINMM.LIB")
#include<ctime>
using namespace std;
/*定义蛇结构体,direction存放1、2、3、4分别表示蛇头移动的方向是上下左右;
length存放当前蛇的长度,headx、heady、nailx、naily存放蛇的头尾的位置*/
typedef struct Snake{
    int headx;
    int heady;
    int nailx;
    int naily;
    int direction;
    int length;
}Snake;
const int M = 25;
const int N = 40;
const int XCenter = 12;//画板中心1~23
const int YCenter = 20;//1~39
const int aveLevelFoods = 10 ;//每一个级别食物个数
const int aveFoodScores = 100 ;//每一个食物分数
const int aveLevelScores = aveLevelFoods * aveFoodScores;//每一个级别分数
const int maxLevel = 5;//最高级别
int board[M][N];//board[headx][heady]中存放值1、2、3、4分别蛇身位于当前位置的表示上下左右;5表示有食物
int level, speed[maxLevel] = {400, 200, 100, 50, 25}; //等级越高,速度越快
Snake snake;

//初始化函数
void init();
//控制光标移动
void gotoxy(int x, int y);
//绘制蛇形函数
void printSnake();
//定时移动蛇形,返回值为-1表示死亡
int moveSnake(char& key);
//产生食物
void popFood();
//积分打印
void printScore();

int main()
{
    char key, isAgain = 'y', &referKey = key;
    init();
    printSnake();
    while(1){
        if(kbhit())//有键按下
            key = getch();
        if(moveSnake(referKey) == -1){
            gotoxy(XCenter, YCenter - 3);
            cout<<"Game Over!";
            gotoxy(XCenter+2, YCenter - 5);
            cout<<"是否开始下一局(y/n)?";
            isAgain = getch();
            if(isAgain != 'n' && isAgain != 'N'){
                init();
                printSnake();
            }
            else
                break;
        }
        if(level > maxLevel){
            gotoxy(XCenter, YCenter - 5);
            cout<<"恭喜你,你已经通关了!";
            gotoxy(XCenter+2, YCenter - 5);
            cout<<"是否开始下一局(y/n)?";
            isAgain = getch();
            if(isAgain != 'n' && isAgain != 'N'){
                init();
                printSnake();
            }
            else
                break;
        }
        Sleep(speed[level-1]);
    }
    return 0;
}

//积分打印
void printScore()
{
    int score = (snake.length - 3) * 100;
    BLACK_WHITE;
    gotoxy(M, 0);
    printf("\n");
    if(score >= level * aveLevelScores){
        ++level;
        if(level > maxLevel){    
            return;
        }
    }
    int foods = (level * aveLevelScores - score) / aveFoodScores;
    if(foods == 10)
        printf("                                      星星:%d\n\n", -foods);
    else
        printf("                                      星星:%d \n\n", -foods);//把十位上0置为空
    printf("                  得分:%-4d                              等级:%d\n", score, level);
    BLACK_RED;
}

//产生食物
void popFood()
{
    int x, y;
    srand(time(NULL));
    do{
        x = rand() % 23 + 1;//1~23
        y = rand() % 38 + 1;
    }while(board[x][y] > 0);
    gotoxy(x, y);
    BLACK_RED;
    cout<<"★";
    board[x][y] = 5;//表示该地点有食物
}

//定时移动蛇形
int moveSnake(char& key)
{
    int hasfood = 0, eatself = 0;
    //根据键值改变方向
    if(key == 'w' || key == 'W'){
        if(snake.direction > 2)//当前方向为水平方向
            snake.direction = 1;
    }else if(key == 's' || key == 'S'){
        if(snake.direction > 2)
            snake.direction = 2;    
    }else if(key == 'a' || key == 'A'){
        if(snake.direction < 3)//当前方向为垂直方向
            snake.direction = 3;
    }else if(key == 'd' || key == 'D'){
        if(snake.direction < 3)//当前方向为水平方向
            snake.direction = 4;
    }else if(key == 'p' || key == 'P'){//暂停
        while(1){
            if(kbhit())//有键按下
                key = getch();
            if(key == 'w' || key == 'W' || key == 'a' || key == 'A' || key == 's' || key == 'S' ||key == 'd' || key == 'D')
                break;
        }
    }else;
    //求解新的蛇头
    int next = board[snake.headx][snake.heady];
    if(snake.direction == 1 && next != 1){//next蛇身方向不能与前进方向相同
        --snake.headx;
        if(board[snake.headx][snake.heady] == 5){
            hasfood = 1;
        }
        if(board[snake.headx][snake.heady] > 0 && board[snake.headx][snake.heady] < 5){
            eatself = 1;
        }
        board[snake.headx][snake.heady] = 2;
    }
    else if(snake.direction == 2 && next != 2){
        ++snake.headx;
        if(board[snake.headx][snake.heady] == 5){
            hasfood = 1;
        }
        if(board[snake.headx][snake.heady] > 0 && board[snake.headx][snake.heady] < 5){
            eatself = 1;
        }
        board[snake.headx][snake.heady] = 1;
    }
    else if(snake.direction == 3 && next != 3){
        --snake.heady;
        if(board[snake.headx][snake.heady] == 5){
            hasfood = 1;
        }
        if(board[snake.headx][snake.heady] > 0 && board[snake.headx][snake.heady] < 5){
            eatself = 1;
        }
        board[snake.headx][snake.heady] = 4;
    }
    else if(snake.direction == 4 && next != 4){
        ++snake.heady;
        if(board[snake.headx][snake.heady] == 5){
            hasfood = 1;
        }
        if(board[snake.headx][snake.heady] > 0 && board[snake.headx][snake.heady] < 5){
            eatself = 1;
        }
        board[snake.headx][snake.heady] = 3;
    }
    else;
    //出界死亡
    if(eatself == 1 || snake.headx == 0 || snake.headx == M - 1 || snake.heady == 0 || snake.heady== N - 1)
        return -1;
    //吃到食物
    if(hasfood){
        ++snake.length;
        popFood();
        printScore();    //打印积分
        //PlaySound(TEXT("newmail.wav"),0,SND_FILENAME|SND_ASYNC); //播放音乐
        //PlaySound(TEXT("a.wav"),0,SND_ASYNC | SND_LOOP); //播放背景音乐
        return 0;
    }
    //清除蛇尾并求解新的蛇尾
    gotoxy(snake.nailx, snake.naily);
    cout<<"  ";
    board[snake.nailx][snake.naily] = 0; //离开了此地
    int length = 0, x = snake.headx, y = snake.heady;
    while(1){
        ++length;
        if(length == snake.length)
            break;
        switch(board[x][y]){
        case 1:
            --x;
            break;
        case 2:
            ++x;
            break;
        case 3:
            --y;
            break;
        case 4:
            ++y;
        }
    }
    snake.nailx = x;
    snake.naily = y;
    printSnake();
    return 0;
}

//绘制蛇形函数
void printSnake()
{
    int x = snake.headx, y = snake.heady, length = 0;
    BLACK_BLUE;
    while(1){
        gotoxy(x, y);
        cout<<"⊙";//board[x][y];
        ++length;
        if(length == snake.length)
            break;
        switch(board[x][y]){
        case 1:
            --x;
            break;
        case 2:
            ++x;
            break;
        case 3:
            --y;
            break;
        case 4:
            ++y;
        }
        BLACK_RED;
    }
}

//控制光标移动
void gotoxy(int x, int y)
{
    COORD c;
    c.X = 2*y;//数组和屏幕坐标方向不同且横向每个图形占两个字符
    c.Y = x;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), c);
    CONSOLE_CURSOR_INFO cursor_info = {1, 0}; //隐藏光标
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

//初始化函数
void init()
{
    system("cls");
    system("mode con cols=81 lines=35");//窗口宽度高度
    memset(board, 0, sizeof(board));
    memset(&snake, 0, sizeof(&snake));
    level = 1;
    snake.headx = XCenter;
    snake.heady = YCenter;
    snake.direction = 3;                    //向左
    board[snake.headx][snake.heady] = 4;    //蛇身在右边
    board[snake.headx][snake.heady+1] = 4;
    board[snake.headx][snake.heady+2] = 4;
    snake.nailx = snake.headx;
    snake.naily = snake.heady + 2;
    snake.length = 3;
    PlaySound(TEXT("a.wav"),0,SND_ASYNC | SND_LOOP); //播放背景音乐
    for(int i = 0; i < M; ++i){
        for(int j = 0; j < N; ++j){
            BLACK_WHITE;
            if(i == 0 || i == M - 1 || j == 0 || j == N - 1)
                cout<<"█";
            else
                cout<<"  ";
        }
        cout<<endl;
    }
    popFood();        //弹出食物
    printScore();    //打印积分

    //打印提示
    gotoxy(M + 5, 0);
    BLACK_GREEN;
    cout<<"\tw(↑)\n\n";
    cout<<"a(←)\t\td(→)\tp(暂停)\n\n";
    cout<<"\ts(↓)";
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值