c语言贪吃蛇(极简版,基本能玩)
c语言贪吃蛇
整体逻辑
- 界面绘制
- 定义结构体以及结构体的初始化
2.1 一节变三节 - 蛇的移动
3.1 监控键盘
3.2 蛇的移动 - 食物
4.1 定义
4.2 初始化
4.3 食物的绘制 - 食物的再生与身体增长、分数
- 死亡与结束
- 优化
7.1 getch()函数会返回两个数值,过滤第一个,留下第二个真实键值
界面绘制与主函数
#include<graphics.h> //图形界面库
#include<stdio.h>
#include<stdlib.h>
int main()
{
//界面绘制
initgraph(WIN_WIDTH, WIN_HEIGTH);//初始化窗口
setbkcolor(RGB(207, 214, 229));//设置背景颜色
cleardevice();//刷新窗口
//初始化
GemeInit();
while (1) {
//绘制
GameDraw();
//移动
GameMove();
BeginBatchDraw();//双缓存机制,减少闪烁
//控制键盘
KeyControl;
FlushBatchDraw();//刷新双缓冲区
EatFood();
Sleep(100);
}
}
定义和初始化
-
蛇
//定义蛇 struct Snake { int num; //蛇身长 int dir; //方向 int score; //分数 int size; //蛇的宽和高 定位 int speed;//蛇速度 //坐标 struct Pos coor[MAX_SNAKE]; }snake; // 定位 struct Pos { int x; int y; };
-
食物
//定义食物 struct Food { int x; int y; bool flag;//判断食物是否存在 }food;
-
初始化
//初始化 void GemeInit() { snake.num = 3; snake.dir = RIGHT; snake.score = 0; snake.size = 15; snake.speed = 10; //三节蛇身的初始化 snake.coor[0].x = 200; //修改初始位置,避免蛇身重叠 snake.coor[0].y = 200; snake.coor[1].x = 185; snake.coor[1].y = 200; snake.coor[2].x = 170; snake.coor[2].y = 200; //食物的初始化 food.x = rand() % (WIN_WIDTH / 10) * 10; food.y = rand() % (WIN_HEIGTH / 10) * 10; food.flag = true; }
根据坐标绘制图形
-
绘制蛇身、食物、分数
void GameDraw() { cleardevice();//清屏 //三节蛇身 for (int i = 0; i < snake.num; i++) { //蛇的填充色 setfillcolor(BLACK); //画矩形 fillrectangle(snake.coor[i].x, snake.coor[i].y, snake.coor[i].x + snake.size, snake.coor[i].y + snake.size); } //食物,复用蛇身 setfillcolor(BLACK); fillrectangle(food.x, food.y, food.x + snake.size, food.y + snake.size); //分数 char temp[20] = ""; sprintf(temp, "分数%d", snake.score); outtextxy(10, 10, temp); }
蛇的移动
-
监控键盘
void KeyControl() { //只有按键按下时才处理 if (_kbhit()) { char key = _getch();//接收getch()函数的第一个返回值 char key2 = _getch();//接收getch()函数的第二个返回值,即真实键值 if (key == -32) { switch (key2) { case 72: if (snake.dir != DOWN) { snake.dir = UP; printf("↑\n"); } break; case 75: if (snake.dir != RIGHT) { snake.dir = LEFT; printf("←\n"); } break; case 77: if (snake.dir != LEFT) { snake.dir = RIGHT; printf("→\n"); } break; case 80: if (snake.dir != UP) { snake.dir = DOWN; printf("↓\n"); } break; } } } }
-
蛇的移动
void GameMove() { //从蛇尾开始覆盖,a,b,c三节考虑。 for (int i = snake.num - 1; i > 0; i--) { snake.coor[i].x = snake.coor[i - 1].x; snake.coor[i].y = snake.coor[i - 1].y; } switch (snake.dir) { case UP: snake.coor[0].y -= snake.speed; break; case DOWN: snake.coor[0].y += snake.speed; break; case LEFT: snake.coor[0].x -= snake.speed; break; case RIGHT: snake.coor[0].x += snake.speed; break; } }
吃食物
-
消失与再生
//吃食物 void EatFood() { if (food.flag && snake.coor[0].x == food.x && snake.coor[0].y == food.y) { food.flag = false; snake.num++; snake.score += 10; } CreateFood(); } //生成食物 void CreateFood() { if (!food.flag) { food.x = rand() % (WIN_WIDTH / 10) * 10; food.y = rand() % (WIN_HEIGTH / 10) * 10; food.flag = true; } }
完整代码
/*
1. 界面绘制
2. 定义结构体以及结构体的初始化
2.1 一节变三节,绘制蛇身
3. 蛇的移动
3.1 监控键盘
3.2 蛇的移动
4. 绘制食物
4.1 定义
4.2 初始化
4.3 食物的绘制
5. 食物的再生与身体增长、分数
6. 死亡与结束
7. 优化
7.1 getch()函数会返回两个数值,过滤第一个,留下第二个真实键值
*/
#include<graphics.h> //图形界面库
#include<stdio.h>
#include <conio.h> //键盘监控
#include<stdlib.h>
#define MAX_SNAKE 500
#define WIN_WIDTH 640
#define WIN_HEIGTH 480
// 定位
struct Pos
{
int x;
int y;
};
// 蛇的结构体
struct Snake {
int num; //蛇身长
int dir; //方向
int score; //分数
int size; //蛇的宽和高 定位
int speed;//蛇速度
//坐标
struct Pos coor[MAX_SNAKE];
}snake;
struct Food {
int x;
int y;
bool flag;//判断食物是否存在
}food;
//枚举类型定义方向
enum DIR {
UP,
DOWN,
LEFT,
RIGHT
};
//初始化
void GemeInit() {
snake.num = 3;
snake.dir = RIGHT;
snake.score = 0;
snake.size = 15;
snake.speed = 10;
//三节蛇身
snake.coor[0].x = 200; //修改初始位置,避免蛇身重叠
snake.coor[0].y = 200;
snake.coor[1].x = 185;
snake.coor[1].y = 200;
snake.coor[2].x = 170;
snake.coor[2].y = 200;
//食物
food.x = rand() % (WIN_WIDTH / 10) * 10;
food.y = rand() % (WIN_HEIGTH / 10) * 10;
food.flag = true;
}
// 绘制三节蛇身、食物、分数
void GameDraw() {
cleardevice();//
for (int i = 0; i < snake.num; i++)
{
//蛇的填充色
setfillcolor(BLACK);
//画矩形
fillrectangle(snake.coor[i].x, snake.coor[i].y, snake.coor[i].x + snake.size, snake.coor[i].y + snake.size);
}
//食物的填充色
setfillcolor(BLACK);
//画矩形
fillrectangle(food.x, food.y, food.x + snake.size, food.y + snake.size);
char temp[20] = "";
sprintf(temp, "分数%d", snake.score);
outtextxy(10, 10, temp);
}
//蛇的移动
void GameMove() {
//从蛇尾开始覆盖,a,b,c三节考虑。
for (int i = snake.num - 1; i > 0; i--) {
snake.coor[i].x = snake.coor[i - 1].x;
snake.coor[i].y = snake.coor[i - 1].y;
}
switch (snake.dir) {
case UP:
snake.coor[0].y -= snake.speed;
break;
case DOWN:
snake.coor[0].y += snake.speed;
break;
case LEFT:
snake.coor[0].x -= snake.speed;
break;
case RIGHT:
snake.coor[0].x += snake.speed;
break;
}
}
//监控键盘
void KeyControl() {
//只有按键按下时才处理
if (_kbhit()) {
char key = _getch();//接收getch()函数的第一个返回值
char key2 = _getch();//接收getch()函数的第二个返回值,即真实键值
if (key == -32) {
switch (key2) {
case 72:
if (snake.dir != DOWN) {
snake.dir = UP;
printf("↑\n");
}
break;
case 75:
if (snake.dir != RIGHT) {
snake.dir = LEFT;
printf("←\n");
}
break;
case 77:
if (snake.dir != LEFT) {
snake.dir = RIGHT;
printf("→\n");
}
break;
case 80:
if (snake.dir != UP) {
snake.dir = DOWN;
printf("↓\n");
}
break;
}
}
}
}
//生成食物
void CreateFood() {
if (!food.flag) {
food.x = rand() % (WIN_WIDTH / 10) * 10;
food.y = rand() % (WIN_HEIGTH / 10) * 10;
food.flag = true;
}
}
//吃食物
void EatFood() {
if (food.flag && snake.coor[0].x == food.x && snake.coor[0].y == food.y) {
food.flag = false;
snake.num++;
snake.score += 10;
}
CreateFood();
}
int main()
{
//界面绘制
initgraph(WIN_WIDTH, WIN_HEIGTH);//初始化窗口
setbkcolor(RGB(207, 214, 229));//设置背景颜色
cleardevice();//刷新窗口
GemeInit();
while (1) {
//绘制
GameDraw();
//移动
GameMove();
BeginBatchDraw();//双缓存机制,减少闪烁
//控制键盘
KeyControl;
FlushBatchDraw();//刷新双缓冲区
EatFood();
Sleep(100);
}
}
原文地址:https://blog.csdn.net/WYyanyufei/article/details/145246963
免责声明:本站文章内容转载自网络资源,如侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!