| 网站首页 | 业界新闻 | 小组 | 威客 | 人才 | 下载频道 | 博客 | 代码贴 | 在线编程 | 编程论坛
欢迎加入我们,一同切磋技术
用户名:   
 
密 码:  
共有 1686 人关注过本帖
标题:贪吃蛇代码
只看楼主 加入收藏
love浪子
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2016-9-20
结帖率:0
收藏
已结贴  问题点数:20 回复次数:3 
贪吃蛇代码
贪吃蛇.zip (4.59 KB)

这是我的代码,在VS中运行没有错误,但是.exe文件执行不起来,有一点毛病,困扰了好几天,希望大家多多指教
搜索更多相关主题的帖子: 贪吃蛇 
2016-09-20 09:41
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
收藏
得分:20 
程序代码:
/*
    头文件的引入,除了标准输入输出(stdio.h)外,需要使用windows.h与控制台conio.h里面的函数
*/

#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <windows.h>
#include <time.h>

/*
    为了便于区分蛇的方向,食物的类型,用单词代替了数字,不易出错
*/

#define Up 1
#define Down 2
#define Left 3
#define Right 4

/*
    结构体的定义与声明,共三个,分别是 点、蛇的节点、蛇、食物,需要用到链表的知识
*/

struct Point
{
    int X;
    int Y;
};                                       //点结构体

struct SnakeNode
{

    Point pos;
    SnakeNode *next;
    int direction;
};                  //蛇的身子节点

struct Snake
{
    SnakeNode *SnakeHead;
    int statement;
};                  //蛇结构体

struct Food{
    Point pos;
    int type;
};

/*
    全局变量的声明,包括分数,游戏速度,蛇的长度,场景信息,与未始化的蛇,食物
*/

Snake mysnake;
int i=0;
int score = 0;
int speed = 200;
Point startPoint, endPoint,mapStart, lastPoint = {23,10};
SnakeNode *lastNode;
Food food;

/*
    自定义函数的声明
*/

void HideCursor();
void gotoxy(int x, int y);
void init();
void loading();
void game();
void start();
void help();
void setLevel();
void exit();
void InitMap();
void InitSnake();
void CreateFood();
void updateSnake(char);
void updateNode();
void addNode();
void judge();
void drawMap();
void drawSnake();

/*
    main()函数
*/

int main()
{
    mysnake.SnakeHead = (struct SnakeNode*)malloc(sizeof(struct SnakeNode));
    lastNode= (struct SnakeNode*)malloc(sizeof(struct SnakeNode));
    lastNode->next = (SnakeNode*)malloc(sizeof(SnakeNode));
    init();
    loading();
    game();
    return 0;

}

/*
    自定义函数的实现
*/

void HideCursor()              //光标隐藏函数
{
    CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };        //1表示是文本高度,0表示false,光标隐藏
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

void gotoxy(int x,int y)      //光标的定位函数
{
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);    // 获取标准输出设备(窗口)句柄
    COORD pos;
    pos.X = x;
    pos.Y = y;
    SetConsoleCursorPosition(hOut, pos);             // 设置光标的位置
}

void init()
{
    HANDLE hOut = GetStdHandle(STD_OUTPUT_HANDLE);         // 获取标准输出设备句柄
    CONSOLE_SCREEN_BUFFER_INFO bInfo;                      // 窗口缓冲区信息
    GetConsoleScreenBufferInfo(hOut, &bInfo);              // 获取窗口缓冲区信息
    SetConsoleTitle(L"贪吃蛇V1.0 By ^(-@-)^");              // 获取窗口标题
    COORD size = { 80, 25 };
    SetConsoleScreenBufferSize(hOut, size);                // 重新设置缓冲区大小
    SMALL_RECT rc = { 0, 0, 80 - 1, 25 - 1 };              // 重置窗口位置和大小
    SetConsoleWindowInfo(hOut, true, &rc);
    system("color F0");
    MessageBox(NULL, L"游戏作者:^(-@-)^\n版权归大家所有.....", L"温馨提示", MB_OK | MB_ICONWARNING);
    HideCursor();
}

void loading()
{
    gotoxy(30, 8);
    printf("欢迎来到贪吃蛇的世界!\n");
    gotoxy(30, 12);
    system("pause");        //让这个界面固定,如果没有它将会是一闪而过,不会停留的
}

void game()
{
    fflush(stdin);                //将输入缓冲区清空
    Point pos;
    char ans = NULL;
    system("cls");                         //清除上一个回车键时屏幕的内容
    gotoxy(36, 6); printf("贪吃蛇");
    gotoxy(35, 9); printf("开始游戏");
    gotoxy(35, 10); printf("难度设置");
    gotoxy(35, 11); printf("帮助信息");
    gotoxy(35, 12); printf("退出游戏");
    gotoxy(32, 9); printf("");
    gotoxy(43, 9);
    pos.X = 43, pos.Y = 9;
    while (1)                        //这个函数什么意思?
    {
        ans = _getch();
        switch (ans)  

        {
        case 'w':
            if (pos.Y == 9){
                gotoxy(32, pos.Y); printf(" ");
                pos.Y = 12;
                gotoxy(32, pos.Y); printf("");
                gotoxy(43, pos.Y);
                break;
            }
            else{
                gotoxy(32, pos.Y); printf(" ");
                gotoxy(32, --pos.Y); printf("");
                gotoxy(43, pos.Y);
            }
            break;
        case 's':
            if (pos.Y == 12){
                gotoxy(32, pos.Y); printf(" ");
                pos.Y = 9;
                gotoxy(32, pos.Y); printf("");
                gotoxy(43, pos.Y);
                break;
            }
            else{
                gotoxy(32, pos.Y); printf(" ");
                gotoxy(32, ++pos.Y); printf("");
                gotoxy(43, pos.Y);
            }
            break;
        case 13:
            switch (pos.Y)
            {
            case 9:start(); break;
            case 10:setLevel(); break;
            case 11:
                MessageBox(NULL, L"1.移动说明:键盘按键W、A、S、D。\n2.游戏目的:吃掉尽可能多的食物。", L"帮助文档", MB_OK | MB_ICONINFORMATION);
                break;
            case 12:
                int i = MessageBox(NULL, L"确定要退出贪吃蛇游戏吗?", L"再次询问", MB_OKCANCEL | MB_ICONQUESTION);
                if (i == IDOK)    exit(0);
                break;
            }
        default:
            break;
        }
    }
}

void start()
{
    system("cls");
    fflush(stdin);
    int last = Right;  //这个是宏定义last=4;
    char key=NULL;
    InitMap();
    InitSnake();
    drawMap();
    CreateFood();
    do                                        //游戏最重要的部分,核心
    {
        drawSnake();
        Sleep(speed);
        while (_kbhit() != 0) key = _getch();   //_kbhit() != 0检查键盘是否按键按下,若有则返回非0,否则返回0值
        updateSnake(key);
        if (mysnake.statement == 0)
        {
            MessageBox(NULL, L"下次注意点!", L"游戏结束", MB_OK | MB_ICONINFORMATION);
            Sleep(2000);
            system("cls");
        }
    } while (mysnake.statement == 1);
    game();
}

void help()
{
    fflush(stdin);
    system("cls");
    char ans = NULL;
    gotoxy(36, 6); printf("帮助文档");
    gotoxy(26, 8); printf("1.移动说明:键盘按键W、A、S、D。\n");
    gotoxy(26, 9); printf("2.游戏目的:吃掉尽可能多的食物。\n");
    gotoxy(26, 11); printf("请按回车键返回......\n");
    while (ans != 13)
    {
        ans = _getch();
    }
    game();
    return;
}

void setLevel()
{
    fflush(stdin);
    system("cls");
    char ans = NULL;
    int i = 10;
    gotoxy(36, 6); printf("设置难度");
    gotoxy(24, 8); printf("难度说明:默认为200ms,越小难度越大。");
    gotoxy(24, 9); printf("当前的游戏时间间隔:%dms。",speed);
    while(1){
        gotoxy(24, i++); printf("请输入您要设置的间隔时间(ms):");
        scanf_s("%d", &speed);
        if (speed <= 0)
            MessageBox(NULL, L"间隔小于零?别逗我了好吗!!!",L"对你无语!", MB_OK | MB_ICONINFORMATION);
        else if (speed>1000){
            MessageBox(NULL,L"不觉得有点慢了吗!",L"温馨提示", MB_OK | MB_ICONINFORMATION);
        }
        else
        {
            MessageBox(NULL, L"赶快进入游戏吧!", L"设置成功", MB_OK | MB_ICONINFORMATION);
            break;
        }
    }

    game();
    return;
}

void exit()
{
    system("cls");
    int i=MessageBox(NULL, L"确定要退出贪吃蛇游戏吗?", L"再次询问", MB_OKCANCEL | MB_ICONQUESTION);
    if (i == IDOK)    exit(0);
}

void InitMap()
{
    startPoint.X = 10;
    startPoint.Y = 6;
    mapStart.X = startPoint.X + 1;
    mapStart.Y = startPoint.Y;
    endPoint.X = 70;
    endPoint.Y = 22;
    return;
}

void InitSnake()
{
    int i = 3;                //i为什么取3??

    mysnake.statement = 1;
     mysnake.SnakeHead->pos.X =24;
     mysnake.SnakeHead->pos.Y =10;
     mysnake.SnakeHead->next =NULL;
     mysnake.SnakeHead->direction =Right;
    //初始化为长度为1的蛇(不含头结点)
    SnakeNode *current = mysnake.SnakeHead;
    lastNode = current;
    while (i--)
        addNode();
}

void CreateFood()
{
    int flag = 0;                              //这里是否需要一个seed种子srand函数?这样让rand函数可以任意产生随机数,而不用重复
    SnakeNode *current = mysnake.SnakeHead;
    while (1)
    {
        flag = 0;
        food.pos.X = mapStart.X + 2 + rand() % 56;     //随机产生0-56以内的随机数+11+2=13-69区间
        food.pos.Y = mapStart.Y + 2 + rand() % 12;     //随机产生0-12以内的随机数+6+2=8-20区间
        while (current != NULL)
        {
            if (food.pos.X == current->pos.X&&food.pos.Y == current->pos.Y)
            {

                flag = 1;                          //食物不能与本身的节点重合
                break;
            }   

            current = current->next;   //current->next是不是空指针????
        }
        if (flag == 0)                     //这个判断条件是什么意思?》退出while循环
            break;
    }
    gotoxy(food.pos.X, food.pos.Y); printf("$");
}

void updateSnake(char key)
{
    SnakeNode *current = mysnake.SnakeHead;
    switch (key)
    {
    case 'w':{
        if (current->direction == Down)      //表明按下与原方向相反的方向是无效果的
        {
            mysnake.SnakeHead->pos.Y++;  //mysnake.SnakeHead->pos.Y++和current->pos.Y++是否是等价的
            current->direction = Down;
            break;
        }
        mysnake.SnakeHead->pos.Y--;
        current->direction = Up;
        break;
    }
    case 's':{
        if (current->direction == Up)
        {
            mysnake.SnakeHead->pos.Y--;
            current->direction = Up;
            break;
        }
        mysnake.SnakeHead->pos.Y++;
        current->direction = Down;
        break;
    }
    case 'a':{
        if (current->direction == Right)
        {
            mysnake.SnakeHead->pos.X++;
            current->direction = Right;
            break;
        }
        mysnake.SnakeHead->pos.X--;
        current->direction = Left;
        break;
    }
    case 'd':{
        if (current->direction == Left)
        {
            mysnake.SnakeHead->pos.X--;
            current->direction = Left;
            break;
        }
        mysnake.SnakeHead->pos.X++;
        current->direction = Right;
        break;
    }
    default:
    {
        switch (mysnake.SnakeHead->direction)
        {
        case Up:current->pos.X, current->pos.Y--; break;
        case Down:current->pos.X, current->pos.Y++; break;
        case Left:current->pos.X--, current->pos.Y; break;
        case Right:current->pos.X++, current->pos.Y; break;
        }
        break;
    }
    }
    judge();
    updateNode();
}

void updateNode()                //这个函数在updateSnake最后用到
{
    int i=0,dir[100];
    Point node[100];
    SnakeNode *current = mysnake.SnakeHead;
    while (current!= NULL)
    {
        dir[i] = current->direction;
        node[i++] = current->pos;
        current = current->next;        //依次记录节点数和每个吃节点的方向
    }
    if (i > 99){
        MessageBox(NULL,L"你赢了!", L"恭喜通关", MB_OK|MB_ICONINFORMATION);

        Sleep(1000);
        game();
    }
    current = mysnake.SnakeHead->next;
    i = 0;
    while (current != NULL)                   //为什么又要重新将数据放回???
    {
        current->direction = dir[i];
        current->pos = node[i++];
        current = current->next;
    }
}

void addNode()
{
    switch (lastNode->direction)
    {
    case Up:lastNode->next->pos.Y = lastNode->pos.Y + 1; break;
    case Down:lastNode->next->pos.Y = lastNode->pos.Y - 1; break;
    case Left:lastNode->next->pos.X = lastNode->pos.X+1; break;
    case Right:lastNode->next->pos.X = lastNode->pos.X-1; break;
    }
    lastNode = lastNode->next;
    lastNode->next = NULL;
}

void judge()
{
    SnakeNode *current = mysnake.SnakeHead;
    srand((unsigned)time(NULL));                   //这是一个随机发生器函数,将time函数强制转换成unsigned类型作为参数
   

         //判断是否吃到了食物
    if (mysnake.SnakeHead->pos.X == food.pos.X&&mysnake.SnakeHead->pos.Y == food.pos.Y)
    {
        score += 10;
        gotoxy(10, 5); printf("分数:%4d分", score);
        addNode();
        CreateFood();
    }
    //判断是否撞墙,如果是,从墙的另一侧穿过来
    if (mysnake.SnakeHead->pos.X == mapStart.X)
    {
        mysnake.SnakeHead->pos.X = endPoint.X-1;
    }
    else if (mysnake.SnakeHead->pos.Y == mapStart.Y)
    {
        mysnake.SnakeHead->pos.Y = endPoint.Y-1;
    }
    else if (mysnake.SnakeHead->pos.X == endPoint.X)
    {
        mysnake.SnakeHead->pos.X = mapStart.X + 1;
    }
    else if (mysnake.SnakeHead->pos.Y == endPoint.Y)
    {
        mysnake.SnakeHead->pos.Y = mapStart.Y + 1;
    }
    //判断是否撞到了自己的身体
    current = mysnake.SnakeHead->next;
    while (current != NULL)
    {
        if (mysnake.SnakeHead->pos.X == current->pos.X&&mysnake.SnakeHead->pos.Y == current->pos.Y)
            mysnake.statement = 0;
        current = current->next;
    }
}

void drawMap()
{
    /*
        此块的绘制工作,主要依靠移动光标(gotoxy()函数),输出(printf()函数)实现的。
    */
    int i, j;
    //绘制标题,分数,速度
    gotoxy(37, 3); printf("贪吃蛇");
    gotoxy(10, 5); printf("分数:%4d分", score);
    gotoxy(60, 5); printf("速度:%4dms", speed);
    //for循环以扫描的方式绘制地图
    for (i = startPoint.Y; i <= endPoint.Y; i++)     //这个内嵌for循环是为了让四周都绘制好墙壁
    {
        for (j = startPoint.X; j <= endPoint.X;)
        {
            if (i == startPoint.Y || i == endPoint.Y || j == startPoint.X || j == endPoint.X)
            {
                gotoxy(j, i);
                printf("");
            }
            j += 2;
        }
    }
    gotoxy(20, 23);
    //版权信息
    printf("Write By ^(-@-)^. All rights reserved.");
    return;
}

void drawSnake()
{
    SnakeNode *current = mysnake.SnakeHead;
    gotoxy(lastPoint.X, lastPoint.Y);
    printf(" ");
    while (current!=NULL)
    {
        if (current->next == NULL)
            { lastPoint.X= current->pos.X;
              lastPoint.Y = current->pos.Y ;}
        gotoxy(current->pos.X, current->pos.Y);
        printf("*");
        current = current->next;
    }
}

φ(゜▽゜*)♪
2016-09-20 09:45
书生牛犊
Rank: 14Rank: 14Rank: 14Rank: 14
来 自:星夜征程
等 级:贵宾
威 望:10
帖 子:1101
专家分:5265
注 册:2015-10-27
收藏
得分:0 
搞个压缩包里面还只有一个.txt。。。蛮不方便的,明明可以直接上传代码。。

我没有VS,不能帮你测试。不过据我所知,大部分的程序从编译器到.exe  想要让.exe挪到别的地方也能用。貌似需要整合一些.dll。整合那些dll。怎么整合我不清楚。只是自己之前用QT写程序的时候遇见过类似问题,上百度查过。我到最后也没解决,就放弃了。

φ(゜▽゜*)♪
2016-09-20 09:48
love浪子
Rank: 1
等 级:新手上路
帖 子:13
专家分:0
注 册:2016-9-20
收藏
得分:0 
回复 2楼 书生牛犊
不好意思,我看有上传附件,我就上传了,下次留意。。关键我这边好像没有生产exe文件啊,我在项目中都找不到啊。。。。

还有有一个问题是,我在网上下载了别人的贪吃蛇exe程序,但是控制不了方向,按WSAD键是,总是弹出打字的界面。。这是什么原因啊,,望多多指教啊
2016-09-20 19:59
快速回复:贪吃蛇代码
数据加载中...
 
   



关于我们 | 广告合作 | 编程中国 | 清除Cookies | TOP | 手机版

编程中国 版权所有,并保留所有权利。
Powered by Discuz, Processed in 0.028509 second(s), 10 queries.
Copyright©2004-2024, BCCN.NET, All Rights Reserved