当前位置:   article > 正文

纯C语言贪吃蛇游戏_c语言贪吃蛇,

c语言贪吃蛇,

说明

我在2018年5月8日重新更新了贪吃蛇的代码,现在它比以前更精简,且未使用全局变量
函数均使用功能命名,可以轻易明白函数功能
贪吃蛇通过链表实现

你可以前往我的github下载此代码,仅可在vs下编译,调用GameEntrance()即可
如果想使用vc,请点击这里下载.cpp文件运行

效果图

jo-qzy的博客

代码

#pragma once

#include <stdio.h>
#include <stdlib.h>
#include <windows.h>
#include <time.h>
#include <stdbool,h>

#define _LENTH 28//修改游戏棋盘大
#define _WIDTH 28//只需输入内部的大小为N*N即可
#define _SNAKE_LENTH 3//蛇的初始长度
#define _SNAKE_SPEED 300//蛇初始速度

typedef struct SNAKE
{
    int x;
    int y;
    struct SNAKE *pNext;
}snake;

static void Pos(int x, int y);//移动光标函数
static void SnakeInit(snake** head,snake**tail);//初始化蛇
static void GetFood(snake* head,snake** food);
static void FoodPrint(snake* food);
static int SnakeFoodJudge(snake* head,snake* food);
static void GameCycle();
static void Pause();
static void SnakeMove(snake** head, snake** tail, snake** food,short key,int* score);
static void DoNotBitYourself(snake* head);
static void StayAwayFromWall(snake* head);
void GameEntrance();

static void PrintGameWall();
static void Welcome();

static void Pos(int x, int y)//获取
{
    COORD pos;
    HANDLE output;
    CONSOLE_CURSOR_INFO cci;
    pos.X = x;
    pos.Y = y;
    output = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(output, pos);
    GetConsoleCursorInfo(output, &cci);//获取当前光标信息
    cci.bVisible = false;//设置光标不可见
    SetConsoleCursorInfo(output, &cci);
}

static void SnakeInit(snake** head,snake** tail)
{
    snake* cur = NULL;
    int i = 0;
    cur = (snake*)malloc(sizeof(snake));
    *head = cur;//保存头
    cur->x = (_LENTH + 2) / 2 * 2;
    cur->y = (_WIDTH + 2) / 2;
    for (i = 1; i < _SNAKE_LENTH; i++)
    {
        *tail = (snake*)malloc(sizeof(snake));
        (*tail)->x = (*head)->x - i * 2;
        (*tail)->y = (*head)->y;
        cur->pNext = *tail;
        cur = cur->pNext;
    }
    (*tail)->pNext = NULL;
    cur = *head;
    while (cur != NULL)
    {
        Pos(cur->x, cur->y);
        printf("■");
        cur = cur->pNext;
    }
}

static void GetFood(snake* head,snake** food)
{
    srand((unsigned int)time(0));
    do
    {
        (*food)->x = (rand() % (_LENTH - 1) + 1) * 2;
        (*food)->y = rand() % (_WIDTH - 1) + 1;
    } while (SnakeFoodJudge(head,*food) == 0);
    FoodPrint(*food);
}

static void FoodPrint(snake* food)
{
    Pos(food->x, food->y);
    printf("■");
}

static int SnakeFoodJudge(snake* head,snake* food)
{
    snake* cur = head;
    while (cur != NULL)
    {
        if((cur->x == food->x) && (cur->y == food->y))
        {
            return 0;
        }
        cur = cur->pNext;
    }
    return 1;
}

static void GameCycle()
{
    snake* food = (snake*)malloc(sizeof(snake));
    snake* head = NULL;
    snake* tail = NULL;
    short key = VK_RIGHT;
    int score = 0;
    int speed = _SNAKE_SPEED;
    int next_level = 30;
    SnakeInit(&head, &tail);
    GetFood(head,&food);
    while (1)
    {
        if (GetAsyncKeyState(VK_UP) && (key != VK_DOWN))
        {
            key = VK_UP;
        }
        else if (GetAsyncKeyState(VK_DOWN) && (key != VK_UP))
        {
            key = VK_DOWN;
        }
        else if (GetAsyncKeyState(VK_LEFT) && (key != VK_RIGHT))
        {
            key = VK_LEFT;
        }
        else if (GetAsyncKeyState(VK_RIGHT) && (key != VK_LEFT))
        {
            key = VK_RIGHT;
        }
        else if (GetAsyncKeyState(VK_SPACE))
        {

            Pause();
        }
        SnakeMove(&head,&tail,&food,key,&score);
        DoNotBitYourself(head);
        StayAwayFromWall(head);
        if ((score == next_level) && (speed >= 10))
        {
            speed -= 10;
            next_level += 30;
            Pos(75, 12);
            printf("当前移动速度:每隔%d毫秒移动向前移动", speed);
        }
        Sleep(speed);
    }
}

static void Pause()
{
    while (1)
    {
        Sleep(300);
        if (GetAsyncKeyState(VK_SPACE))
        {
            break;
        }
    }
}

static void SnakeMove(snake** head, snake** tail,snake** food,short key,int* score)
{
    snake* cur = NULL;
    cur = (snake*)malloc(sizeof(snake));
    cur->pNext = *head;
    switch (key)
    {
    case VK_UP:
        cur->x = (*head)->x;
        cur->y = (*head)->y - 1;
        break;
    case VK_DOWN:
        cur->x = (*head)->x;
        cur->y = (*head)->y + 1;
        break;
    case VK_LEFT:
        cur->x = (*head)->x - 2;
        cur->y = (*head)->y;
        break;
    case VK_RIGHT:
        cur->x = (*head)->x + 2;
        cur->y = (*head)->y;
        break;
    }
    (*head) = cur;
    Pos((*head)->x, (*head)->y);
    printf("■");
    if (((*head)->x == (*food)->x) && ((*head)->y == (*food)->y))
    {
        *score += 10;
        Pos(75, 11);
        printf("得分:%d", *score);
        GetFood(*head,food);
        return;
    }
    if (((*head)->x != (*tail)->x) || ((*head)->y != (*tail)->y))
    {
        Pos((*tail)->x, (*tail)->y);
        printf("  ");
    }
    while (cur->pNext->pNext != NULL)
    {
        cur = cur->pNext;
    }
    free(*tail);
    *tail = cur;
    (*tail)->pNext = NULL;
}

static void DoNotBitYourself(snake* head)
{
    snake* cur = head->pNext;
    while (cur != NULL)
    {
        if ((head->x == cur->x) && (head->y == cur->y))
        {
            Pos(_LENTH, _WIDTH / 2);
            printf("游戏结束你咬到自己了\n");
            Pos(_LENTH, _WIDTH / 2 + 1);
            system("pause");
            exit(0);
        }
        cur = cur->pNext;
    }
}

static void StayAwayFromWall(snake* head)
{
    if ((head->x == 0) || (head->x == (_LENTH + 1) * 2) || (head->y == 0) || (head->y == _WIDTH + 1))
    {
        Pos(_LENTH, _WIDTH / 2);
        printf("游戏结束你撞墙了\n");
        Pos(_LENTH, _WIDTH / 2 + 1);
        system("pause");
        exit(0);
    }
}

void GameEntrance()
{
    Welcome();
    Pos(75, 11);
    printf("得分:0");
    Pos(75, 12);
    printf("当前移动速度:每隔300毫秒移动向前移动");
    Pos(75, 13);
    printf("每获得30分速度会加快");
    Pos(75, 14);
    printf("不能撞墙不能撞自己");
    Pos(75, 15);
    printf("按空格可以暂停……");
    PrintGameWall();
    Pos(40, 20);
    GameCycle();
}

//UI部分
static void PrintGameWall()
{
    int x = 0, y = 0;
    for (x = 0; x < (_LENTH + 1) * 2; x += 2)
    {
        Pos(x, 0);
        printf("■");
        Pos(x, _WIDTH + 1);
        printf("■");
    }
    for (y = 0; y < _WIDTH + 2; y++)
    {
        Pos(0, y);
        printf("■");
        Pos((_LENTH + 1) * 2, y);
        printf("■");
    }
}

static void Welcome()
{
    Pos(28, 10);
    printf("欢迎来到贪吃蛇");
    Pos(28, 11);
    printf("游戏规则:");
    Pos(28, 12);
    printf("1、不能撞墙");
    Pos(28, 13);
    printf("2、不能撞自己");
    Pos(28, 14);
    printf("3、空格可以暂停,再次按下继续游戏");
    Pos(28, 15);
    system("pause");
    system("cls");
}
  • 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
  • 111
  • 112
  • 113
  • 114
  • 115
  • 116
  • 117
  • 118
  • 119
  • 120
  • 121
  • 122
  • 123
  • 124
  • 125
  • 126
  • 127
  • 128
  • 129
  • 130
  • 131
  • 132
  • 133
  • 134
  • 135
  • 136
  • 137
  • 138
  • 139
  • 140
  • 141
  • 142
  • 143
  • 144
  • 145
  • 146
  • 147
  • 148
  • 149
  • 150
  • 151
  • 152
  • 153
  • 154
  • 155
  • 156
  • 157
  • 158
  • 159
  • 160
  • 161
  • 162
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • 174
  • 175
  • 176
  • 177
  • 178
  • 179
  • 180
  • 181
  • 182
  • 183
  • 184
  • 185
  • 186
  • 187
  • 188
  • 189
  • 190
  • 191
  • 192
  • 193
  • 194
  • 195
  • 196
  • 197
  • 198
  • 199
  • 200
  • 201
  • 202
  • 203
  • 204
  • 205
  • 206
  • 207
  • 208
  • 209
  • 210
  • 211
  • 212
  • 213
  • 214
  • 215
  • 216
  • 217
  • 218
  • 219
  • 220
  • 221
  • 222
  • 223
  • 224
  • 225
  • 226
  • 227
  • 228
  • 229
  • 230
  • 231
  • 232
  • 233
  • 234
  • 235
  • 236
  • 237
  • 238
  • 239
  • 240
  • 241
  • 242
  • 243
  • 244
  • 245
  • 246
  • 247
  • 248
  • 249
  • 250
  • 251
  • 252
  • 253
  • 254
  • 255
  • 256
  • 257
  • 258
  • 259
  • 260
  • 261
  • 262
  • 263
  • 264
  • 265
  • 266
  • 267
  • 268
  • 269
  • 270
  • 271
  • 272
  • 273
  • 274
  • 275
  • 276
  • 277
  • 278
  • 279
  • 280
  • 281
  • 282
  • 283
  • 284
  • 285
  • 286
  • 287
  • 288
  • 289
  • 290
  • 291
  • 292
  • 293
  • 294
  • 295
  • 296
  • 297
  • 298
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/很楠不爱3/article/detail/358854
推荐阅读
相关标签
  

闽ICP备14008679号