C语言实现字符界面贪吃蛇
2021/12/31 6:09:08
本文主要是介绍C语言实现字符界面贪吃蛇,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
使用c语言实现字符界面贪吃蛇。
亲测可以在Windows Terminal下运行。
直接上源码。
欢迎交流。
效果图
#include <windows.h> #include <conio.h> #include <stdio.h> #include <stdlib.h> #include <time.h> //每个位置的状态是什么 #define Nothing 0 //空 #define Wall 1 //墙 #define Food 2 //食物 #define Head 3 //蛇头 #define Body 4 //蛇身 //方向 #define Left 5 //左移 #define Right 6 //右移 #define Up 7 //上移 #define Down 8 //下移 HANDLE consoleHandle; // 操作控制台需要的一个变量 int w, h; // 高度,宽度,对应 y 和 x int score = 0;//记录得分 int status[3000][120] = {{0}};//记录每个位置的状态是什么 int flag_death = 0;//判断是否死亡 int flag_q = 0;//判断是否退出游戏 //结构体:蛇头 struct snack_head { int len; int x; int y; int dir; //分别为蛇长(不包括蛇头),蛇头横坐标,纵坐标,方向 }snack; //结构体,蛇身 struct snack_body { int x; int y; //蛇身中一节的横坐标 }body[10086];//用二维数组是一样的 //结构体,食物 struct FOOD { int x; int y; }food; // 打印输入的一个字符 void mvaddch(int y, int x, char ch) { //y表示高度,x表示宽度 COORD co = (COORD) { .X = x, .Y = y }; SetConsoleCursorPosition(consoleHandle, co); putchar(ch); } //打印一个字符串 void mvaddstr(int y, int x, char *s) { int len = strlen(s); for (int i = 0; i < len; ++i) mvaddch(y, x + i, *(s + i));//y表示高度,x表示宽 } // 清屏(全屏空格) void ClearScr() { for (int i = 1; i <= h; ++i) for (int j = 1; j <= w; ++j) mvaddch(i, j, ' '); } //开始游戏的面板 void EnterGame() { mvaddstr(12, 50, " Welcome ! "); mvaddstr(16, 50, "Press any key to start !"); } //初始化面板 void PrintBoard() {//宽为30~90 高为1~28 for (int i = 1; i <= 28; ++i) for (int j = 30; j <= 90; j++) status[i][j] = Nothing; for (int i = 30; i <= 90; ++i){ mvaddch(1, i, '-'); status[0][i] = Wall; } for (int i = 30; i <= 90; ++i) { mvaddch(28, i, '-'); status[29][i] = Wall; } for (int i = 1; i <= 28; ++i) { mvaddch(i, 29, '|'); status[i][28] = Wall; } for (int i = 1; i <= 28; ++i) { mvaddch(i, 91, '|'); status[i][92] = Wall; } mvaddstr(12,94,"press 'p' to pause"); mvaddstr(13,94, "press 'space' to continue"); } //打印得分 void PrintScore(int y,int x, int score_) { COORD co = (COORD) {.X = x, .Y = y}; SetConsoleCursorPosition(consoleHandle, co); printf("score:%d", score_); } //游戏失败时候的界面 void Game_Defeat() { flag_death = 1; PrintScore(h / 2 - 2, w / 2 - 3, score); mvaddstr(h / 2 - 1, w / 2 - 3, "Good game!"); mvaddstr(h / 2, w / 2 - 10, "Press any key to restart."); score = 0; } void InitSnack() {//初始化蛇 snack.len = 1;//蛇身初始长度为一节 snack.x = 60; snack.y = 16;//y指的蛇头高度 snack.dir = Right;//蛇头的初始横纵坐标及方向 body[0].x = 59; body[0].y = 16;//第一节蛇身的横纵坐标 } void GenerateFood() {//随机产生一个食物,注意食物的那个位置在这之前必须是空的 srand((unsigned ) time(NULL)); do { food.x = rand() % 59 + 31; food.y = rand() % 26 + 2; } while (status[food.y][food.x] != Nothing); status[food.y][food.x] = Food; mvaddch(food.y, food.x, '*'); } //判断得分和是否结束,x,y分别指左移或右移的距离,如果吃到食物根据方向做相应的处理 void judge() { if (snack.dir == Up) { if (snack.x == food.x && snack.y - 1 == food.y) { status[snack.y][snack.x] = Body; status[food.y][food.x] = Head; mvaddch(snack.y, snack.x, '#'); mvaddch(food.y, food.x, '@'); for (int i = snack.len; i >= 1; i--) body[i] = body[i - 1]; body[0].x = snack.x; body[0].y = snack.y; snack.len++; snack.y--; score++; GenerateFood(); } else if (status[snack.y - 1][snack.x] == Wall || status[snack.y - 1][snack.x] == Body || status[snack.y][snack.x - 1] == Wall || status[snack.y][snack.x+1] == Wall) { Game_Defeat(); } } else if (snack.dir == Down) { if (snack.x == food.x && snack.y + 1 == food.y) { status[snack.y][snack.x] = Body; status[food.y][food.x] = Head; mvaddch(snack.y, snack.x, '#'); mvaddch(food.y, food.x, '@'); for (int i = snack.len; i >= 1; i--) body[i] = body[i - 1]; body[0].x = snack.x; body[0].y = snack.y; snack.len++; snack.y--; score++; GenerateFood(); } else if (status[snack.y + 1][snack.x] == Wall || status[snack.y + 1][snack.x] == Body||status[snack.y][snack.x - 1] == Wall || status[snack.y][snack.x+1] == Wall) { Game_Defeat(); } } else if (snack.dir == Left) { if (snack.x - 1 == food.x && snack.y == food.y) { status[snack.y][snack.x] = Body; status[food.y][food.x] = Head; mvaddch(snack.y, snack.x, '#'); mvaddch(food.y, food.x, '@'); for (int i = snack.len; i >= 1; i--) body[i] = body[i - 1]; body[0].x = snack.x; body[0].y = snack.y; snack.len++; snack.x = snack.x - 1; score++; GenerateFood(); } else if (status[snack.y][snack.x - 1] == Wall||status[snack.y][snack.x - 1] == Body||status[snack.y+1][snack.x+1] == Wall||status[snack.y -1][snack.x]==Wall) { Game_Defeat(); } } else if (snack.dir == Right) { if (snack.x + 1 == food.x && snack.y == food.y) { status[snack.y][snack.x] = Body; status[food.y][food.x] = Head; mvaddch(snack.y, snack.x, '#'); mvaddch(food.y, food.x, '@'); for (int i = snack.len; i >= 1; i--) body[i] = body[i - 1]; body[0].x = snack.x; body[0].y = snack.y; snack.len++; snack.x = snack.x + 1; score++; GenerateFood(); } else if (status[snack.y][snack.x + 1] == Wall||status[snack.y][snack.x + 1] == Body||status[snack.y+1][snack.x+1] == Wall||status[snack.y -1][snack.x]==Wall) { Game_Defeat(); } } } void Clear_Snack() {//更新蛇之前先擦掉蛇 mvaddch(snack.y, snack.x,' '); status[snack.y][snack.x] = Nothing; for (int i = 0 ;i < snack.len; i++) { mvaddch(body[i].y, body[i].x, ' '); status[body[i].y][body[i].x] = Nothing; } } void Draw_Snack() {//画蛇 status[snack.y][snack.x] = Head; mvaddch(snack.y, snack.x, '@'); for (int i = 0; i < snack.len; i++) { status[body[i].y][body[i].x] = Body; mvaddch(body[i].y, body[i].x, '#'); } } void Dir_Change() {//根据输入调整方向 if (_kbhit()) { switch (_getch()) { case 'q': case 'Q': flag_q = 1; break; case 'W': case 'w': if (snack.dir != Down) { snack.dir = Up; break; } else { Game_Defeat(); break; } case 'S': case 's': if (snack.dir != Up) { snack.dir = Down; break; } else { Game_Defeat(); break; } case 'A': case 'a': if (snack.dir != Right) { snack.dir = Left; break; } else { Game_Defeat(); break; } case 'D': case 'd': if (snack.dir != Left) { snack.dir = Right; break; } else { Game_Defeat(); break; } case 'p': case 'P': while (1){ if (_getch() == ' ') { break; } } } } } void MoveSnack() {//改变坐标 for (int i = snack.len - 1; i >= 0; i--) { if ( i != 0) { body[i] = body[i - 1]; } else { body[i].x = snack.x; body[i].y = snack.y; } } switch (snack.dir) { case Up: snack.y--; break; case Down: snack.y++; break; case Left: snack.x = snack.x - 1; break; case Right: snack.x = snack.x + 1; break; } } int main(){ consoleHandle = GetStdHandle(STD_OUTPUT_HANDLE); // 初始化这个操作器 CONSOLE_SCREEN_BUFFER_INFO csbi; // 屏幕的信息 GetConsoleScreenBufferInfo(consoleHandle, &csbi); // 获取屏幕信息 w = csbi.dwSize.X; h = csbi.dwSize.Y; // 得到宽度高度 // 游戏里面,如果一直有输入的光标,就有点不好看。我们可以让它不显示 CONSOLE_CURSOR_INFO cci; // 光标信息 cci.dwSize = 100; cci.bVisible = FALSE; // 不可见 SetConsoleCursorInfo(consoleHandle, &cci); // 将光标特性应用到控制台 // 到这里,闪烁的光标就消失了。 ClearScr(); EnterGame();//调出开始界面 getch(); ClearScr(); PrintBoard(); InitSnack(); GenerateFood(); while (1){ if (flag_q == 1) { goto end; } MoveSnack(); Draw_Snack(); if (score <= 3){ Sleep(160); } else if (score <= 7) { Sleep(190); } else if (score <= 12) { Sleep(210); } else { Sleep(250); } PrintScore(10, 94, score); Dir_Change(); if (flag_death == 1) { flag_death = 0; getch(); main(); } judge(); if (flag_death == 1) { flag_death = 0; getch(); main(); } Clear_Snack(); } end :cci.bVisible = TRUE; // 可见 SetConsoleCursorInfo(consoleHandle, &cci); // 重新设置 }
这篇关于C语言实现字符界面贪吃蛇的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-22怎么实现ansible playbook 备份代码中命名包含时间戳功能?-icode9专业技术文章分享
- 2024-11-22ansible 的archive 参数是什么意思?-icode9专业技术文章分享
- 2024-11-22ansible 中怎么只用archive 排除某个目录?-icode9专业技术文章分享
- 2024-11-22exclude_path参数是什么作用?-icode9专业技术文章分享
- 2024-11-22微信开放平台第三方平台什么时候调用数据预拉取和数据周期性更新接口?-icode9专业技术文章分享
- 2024-11-22uniapp 实现聊天消息会话的列表功能怎么实现?-icode9专业技术文章分享
- 2024-11-22在Mac系统上将图片中的文字提取出来有哪些方法?-icode9专业技术文章分享
- 2024-11-22excel 表格中怎么固定一行显示不滚动?-icode9专业技术文章分享
- 2024-11-22怎么将 -rwxr-xr-x 修改为 drwxr-xr-x?-icode9专业技术文章分享
- 2024-11-22在Excel中怎么将小数向上取整到最接近的整数?-icode9专业技术文章分享