服务器之家:专注于VPS、云服务器配置技术及软件下载分享
分类导航

PHP教程|ASP.NET教程|Java教程|ASP教程|编程技术|正则表达式|C/C++|IOS|C#|Swift|Android|VB|R语言|JavaScript|易语言|vb.net|

服务器之家 - 编程语言 - C/C++ - C语言基于EasyX实现贪吃蛇

C语言基于EasyX实现贪吃蛇

2022-12-24 15:52今天也要写bug、 C/C++

这篇文章主要为大家详细介绍了C语言基于EasyX实现贪吃蛇,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

本文实例为大家分享了C语言基于EasyX实现贪吃蛇的具体代码,供大家参考,具体内容如下

成品展示:

C语言基于EasyX实现贪吃蛇

实现思路:

贪吃蛇的实现思路并不复杂,由于我们需要将数据展示在图形窗口上,因此就不需要之前那种用数组表示整个游戏地图的方法。

贪吃蛇的蛇有X坐标和Y坐标,而且不止一节,因此需要一个坐标结构体数组来保存,蛇的移动思路是除了第一节以外,后面每一节都是前面一节的坐标,然后通过键盘的输入输出使蛇的X或Y坐标加或者减来起到上下左右移动的作用。通过判断蛇与食物的坐标是否重合绝对是否吃到食物,吃到食物以后,蛇的长度加一,分数增加,食物重新生成。通过与自身坐标比较和界面坐标比较,判断是否撞墙或者撞自己,此时游戏结束。一直循环移动并且在图形界面展示,其中通过睡眠函数Sleep来控制打印速度,从而控制蛇的移动速度。

最后如果需要在游戏时开启音乐,为了方便则需要在文件目录下放入音乐文件。

C语言基于EasyX实现贪吃蛇

代码实现

game.h

?
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
#pragma once
#include<stdio.h>
#include<time.h>
#include<stdlib.h>
#include<graphics.h>
#include<conio.h>
#include<windows.h>
#include<mmsystem.h>
#pragma comment(lib,"Winmm.lib")
 
#define length 100  //蛇长度
 
//1.数据分析:基本数据成员分析
//坐标属性,蛇属性,食物属性
 
//坐标属性
typedef struct pointXY
{
    int x;
    int y;
}MYPOINT;
 
//蛇属性
struct Snake
{
    int num;//蛇的节数
    MYPOINT xy[length]; //蛇最多有100节
    char postion;//蛇的方向
};
//食物的属性
struct Food
{
    MYPOINT fdxy;
    int eatgrade=0;//吃食物的分数
    int flag=0;//食物是否存在,0表示存在,1表示不存在
};
//方向
enum movePostion{right=77,left=75,down=80,up=72};
 
//主窗口
static HWND hwnd = NULL;
 
//2.过程分析:函数分析
//初始化蛇和食物
void initSnakeFood(struct Snake*snake, struct Food* food);
//画蛇
void drawSnake(struct Snake* snake);
//移动蛇
void moveSnake(struct Snake* snake);
//按键处理
void keyDown(struct Snake* snake);
//初始化食物
void initFood(struct Food*food, struct Snake* snake);
//画食物
void drawFood(struct Food* food);
 
//吃食物
void eatFood(struct Food* food, struct Snake* snake);
 
//判断是否游戏结束
int snakeDie(struct Snake* snake);
 
//判断游戏是否胜利
int winGame(struct Snake* snake);
 
//展示分数
void showGrade(struct Food* food);
 
//按空格键暂停
void pauseMoment();

这个头文件主要包含函数声明和头文件的引用。

game.cpp

?
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
#undef UNICODE
#undef _UNICODE
#include"game.h"
 
 
void initSnakeFood(struct Snake* snake, struct Food* food)
{
    //把前三节的属性写出来,初始化数据
    snake->xy[2].x = 0;
    snake->xy[2].y = 0;
 
    snake->xy[1].x = 10;
    snake->xy[1].y = 0;
 
    snake->xy[0].x = 20;
    snake->xy[0].y = 0;
 
    snake->num = 3;//开始有三节
 
    snake->postion = right;//初始化方向为右
 
    food->eatgrade = 0;
 
}
 
void drawSnake(struct Snake* snake)
{
    for (int i = 0; i < snake->num; i++)
    {
        setlinecolor(BLACK);//矩形边框线的颜色
        setfillcolor(RGB(rand() % 255, rand() % 255, rand() % 255));//内部填充颜色
        fillrectangle(snake->xy[i].x, snake->xy[i].y, snake->xy[i].x + 10, snake->xy[i].y + 10);
    }
}
 
void moveSnake(struct Snake* snake)
{
    //除了第一节之外,后面每一节都是前面一节的坐标
    for (int i = snake->num; i > 0; i--)
    {
        snake->xy[i].x = snake->xy[i - 1].x;
        snake->xy[i].y = snake->xy[i - 1].y;
    }
    //第一节的处理
    switch(snake->postion)
    {
    case right:
        snake->xy[0].x += 10;
        break;
    case left:
        snake->xy[0].x -= 10;
        break;
    case down:
        snake->xy[0].y += 10;
        break;
    case up:
        snake->xy[0].y -= 10;
    default:
        break;
    }
}
 
void keyDown(struct Snake* snake)
{
    char userkey = 0;
    userkey = _getch();
    switch (userkey)
    {
    case right:
        if (snake->postion != left)
            snake->postion = right;
        break;
    case left:
        if (snake->postion != right)
            snake->postion = left;
        break;
    case down:
        if (snake->postion != up)
            snake->postion = down;
        break;
    case up:
        if (snake->postion != down)
            snake->postion = up;
        break;
    }
}
 
void initFood(struct Food* food, struct Snake* snake)
{
    food->fdxy.x = rand() % 64 * 10;
    food->fdxy.y = rand() % 48 * 10;
    food->flag = 1;
 
    //如果食物出现在蛇身上,重新产生坐标
    for (int i = 0; i>snake->num; i++)
    {
        if (food->fdxy.x == snake->xy[i].x && food->fdxy.y == snake->xy[i].y)
        {
            food->fdxy.x = rand() % 64 * 10;
            food->fdxy.y = rand() % 48 * 10;
        }
    }
 
}
 
void drawFood(struct Food* food)
{
    setlinecolor(BLACK);//矩形边框线的颜色
    setfillcolor(RGB(rand() % 255, rand() % 255, rand() % 255));
    fillrectangle(food->fdxy.x, food->fdxy.y, food->fdxy.x + 10, food->fdxy.y + 10);
}
 
void eatFood(struct Food* food, struct Snake* snake)
{
    //蛇边长
    //食物重新生成
    //分数增加
    if (snake->xy[0].x == food->fdxy.x && snake->xy[0].y == food->fdxy.y)
    {
        snake->num++;
        food->eatgrade += 10;
        food->flag = 0;
    }
}
 
//蛇死亡,游戏结束
int snakeDie(struct Snake* snake)
{
    if (snake->xy[0].x > 640 || snake->xy[0].x < 0 || snake->xy[0].y>480 || snake->xy[0].y < 0|| (snake->xy[0].x + 10) > 640 || (snake->xy[0].x + 10) < 0 || (snake->xy[0].y + 10) > 480 || (snake->xy[0].y + 10) < 0)
    {
        outtextxy(200, 200, "撞墙");
        //MessageBox(hwnd, "游戏结束,点击确定重新开始", "撞墙", MB_OKCANCEL);
        return 1;//返回1,游戏结束
    }
    for (int i = 1; i < snake->num; i++)
    {
        if (snake->xy[0].x == snake->xy[i].x && snake->xy[0].y == snake->xy[i].y)
        {
            outtextxy(200, 200, "自杀");
            //MessageBox(hwnd, "游戏结束,点击确定重新开始", "自杀", MB_OKCANCEL);
            return 1;
        }
    }
    return 0;
}
int winGame(struct Snake* snake)
{
    if (snake->num == length)
    {
        outtextxy(200, 200, "胜利,恭喜通关");
        //MessageBox(hwnd, "游戏结束,点击确定重新开始", "恭喜通关", MB_OKCANCEL);
        return 1;//返回1,游戏结束
    }
    else
    {
        return 0;
    }
}
void showGrade(struct Food* food)
{
    char grade[100] = "";
    sprintf(grade, "%d", food->eatgrade);
    setbkmode(TRANSPARENT);
    settextcolor(LIGHTBLUE);
    outtextxy(560,20,"分数");
    outtextxy(610,20,grade);
}
 
void pauseMoment()
{
    if (_getch() == 32)
    {
        while (_getch() != 32);
    }
}

test.cpp

?
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
#include"game.h"
int main()
{
    mciSendString(L"open 1.mp3 alias bkmusic", NULL, 0, NULL);//打开音乐文件
    mciSendString(L"play bkmusic repeat", NULL, 0, NULL);     //循环播放音乐
    srand((unsigned int)time(NULL));//随机数种子
    struct Snake snake;//创建蛇
    struct Food food;//创建食物
    hwnd = initgraph(640, 480);//初始化窗口
    setbkcolor(WHITE);//设置窗口为白色
    int key = 0;//接收最终的弹窗指令,判断是否继续游戏
 
    do
    {
        initSnakeFood(&snake,&food);//初始化蛇和食物的分数
        key = 0;
        while (1)
        {
            BeginBatchDraw();缓冲区打印,防止闪屏
            cleardevice();//刷新
            if (food.flag == 0)
            {
                initFood(&food, &snake);
            }
            drawFood(&food);//画食物
            eatFood(&food, &snake);//是否吃食物
            showGrade(&food);//打印食物
            drawSnake(&snake);//画蛇
            EndBatchDraw();//缓冲区打印
            if (snakeDie(&snake))//判断是否四方
            {
                break;
            }
            if (winGame(&snake))//判断是否胜利
            {
                break;
            }
 
            while (_kbhit())//如果有按键则进入,否则不进入循环
            {
                pauseMoment();//暂停
                keyDown(&snake);
            }
            moveSnake(&snake);//移动蛇
            Sleep(100);
        }
        key=MessageBox(hwnd, L"点击确定重新开始", L"游戏结束", MB_OKCANCEL);
        
    } while (key==IDOK);//如果点击确定,则重新开始游戏
    closegraph();//关闭图形模式,释放由图形系统分配的所有内存
    system("pause");
    return 0;
}

这个文件主要是通过调用不同的函数,实现对蛇的操作和展示功能。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持服务器之家。

原文链接:https://blog.csdn.net/qq_52670477/article/details/119284366

延伸 · 阅读

精彩推荐
  • C/C++C语言实现扫雷附完整代码

    C语言实现扫雷附完整代码

    本文详细讲解了C语言实现扫雷并附完整代码,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...

    XiaoHang12285742022-03-03
  • C/C++C++ Opengl旋转功能附源码下载

    C++ Opengl旋转功能附源码下载

    这篇文章主要介绍了C++ Opengl旋转功能附源码下载,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...

    it_xiangqiang4102021-10-06
  • C/C++C语言封装函数字符串练习汇总分享

    C语言封装函数字符串练习汇总分享

    这篇文章主要介绍了C语言封装函数字符串练习汇总分享,分享内容有字符串查找、字符串拼接、字符串转整数等内容,需要而小伙伴可以参考一下...

    DS小龙哥6482022-10-26
  • C/C++C语言实现顺序表的顺序查找和折半查找

    C语言实现顺序表的顺序查找和折半查找

    这篇文章主要为大家详细介绍了C语言实现顺序表的顺序查找和折半查找,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考...

    Andrelia201717607412021-07-31
  • C/C++C语言实现简单电子通讯录(2)

    C语言实现简单电子通讯录(2)

    这篇文章主要为大家详细介绍了C语言实现简单电子通讯录的第二部分,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一...

    believe_s9342021-09-14
  • C/C++C语言实现简易版扫雷游戏

    C语言实现简易版扫雷游戏

    这篇文章主要为大家详细介绍了C语言实现简易版扫雷游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下...

    x_wgg7302021-11-04
  • C/C++C语言中 int main(int argc,char *argv[])的两个参数详解

    C语言中 int main(int argc,char *argv[])的两个参数详解

    这篇文章主要介绍了C语言中 int main(int argc,char *argv[])的两个参数详解的相关资料,需要的朋友可以参考下...

    C语言教程网4792021-05-04
  • C/C++C语言小程序 杨辉三角示例代码

    C语言小程序 杨辉三角示例代码

    输入要显示的杨辉三角的行数,会打印出金字塔型的杨辉三角,不过行数太多的话,效果不太好,可以再调整一下格式控制...

    C语言教程网5492020-12-19