有趣的小游戏,实现关键点有光标移动,按键检测,状态转移,随机数生成等。欢迎讨论!
#include<stdio.h>
#include<windows.h>
#include<time.h>
#include<conio.h>#define UP 'w'
#define DOWN 's'
#define LEFT 'a'
#define RIGHT 'd'
#define ESC 27
#define ENTER 13
#define WALLLENGTH 40
#define WALLWIDTH 15/*构造蛇*/
struct snake_tag {short x[100];//各点的横向坐标short y[100];//各点的纵向坐标short len;//长度short speed;//速度因子
}snake;/*光标移动函数*/
void gotoxy(short x, short y) {COORD coord = { x, y };SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), coord);
}/*随机苹果*/
void apple_gen(int &applex, int &appley)
{
regen:srand(time(NULL));applex = rand() % (WALLLENGTH - 2) + 1;appley = rand() % (WALLWIDTH - 2) + 1;for (int i = 0; i < snake.len; i++){if (applex == snake.x[i] && appley == snake.y[i])goto regen;}
}/*方向键检测*/
char direction_key_capture()
{char key = '\0';if (!_kbhit())//_kbhit()可以检测键盘是否有输入,有返回非零值,无则返回零值{return NULL;//未按键}else{key = getch();if (key == UP || key == DOWN || key == LEFT || key == RIGHT)return key;else if (key == ESC)return ESC;elsereturn NULL;}
}/*蛇移动*/
void snake_move(char direction)
{//1.第二个点至蛇尾的各点坐标,最后一个点snake.x[snake.len]生成的为待判断点,不确定是否为蛇的一部分for (int k = snake.len; k > 0; k--){snake.x[k] = snake.x[k - 1];snake.y[k] = snake.y[k - 1];}//2.蛇首坐标switch (direction){case UP:snake.y[0]--; break;case DOWN:snake.y[0]++; break;case LEFT:snake.x[0]--; break;case RIGHT:snake.x[0]++; break;default:;}
}/*打印画面*/
void wall_display()
{for (int i = 0; i < WALLLENGTH; i++){for (int j = 0; j < WALLWIDTH; j++){gotoxy(i, j);if (i == 0 || i == WALLLENGTH - 1){if (i == 0 && j == 0)printf("┍");else if (i == 0 && j == WALLWIDTH - 1)printf("┕");else if (i == WALLLENGTH - 1 && j == 0)printf("┑");else if (i == WALLLENGTH - 1 && j == WALLWIDTH - 1)printf("┙");elseprintf("│");}else if (j == 0 || j == WALLWIDTH - 1){printf("━");}else;}}gotoxy(0, 0);
}
void snake_display()
{gotoxy(snake.x[0], snake.y[0]);printf("@");if (snake.x[snake.len] != 0 && snake.y[snake.len] != 0){gotoxy(snake.x[snake.len], snake.y[snake.len]);printf(" ");}gotoxy(0, 0);
}
void apple_display(int &applex, int &appley)
{gotoxy(applex, appley);printf("*");gotoxy(0, 0);
}/*菜单*/
int menu()
{gotoxy(0, WALLWIDTH);printf("按ESC键返回游戏,其他键退出...\n");printf("==贪吃蛇==\nby:雪沐osays\nQQ:1624784311\n");gotoxy(0, 0);char ch = getch();if (ch == ESC){return 1;}return 0;
}int main()
{
restart:system("cls");/*数据初始化*/snake.x[0] = WALLLENGTH / 2;snake.y[0] = WALLWIDTH / 2 + 1;snake.x[1] = WALLLENGTH / 2;snake.y[1] = WALLWIDTH / 2;snake.x[2] = WALLLENGTH / 2;snake.y[2] = WALLWIDTH / 2 - 1;snake.len = 3;snake.speed = 300;//越小越快char direction = DOWN;int applex, appley;apple_gen(applex, appley);/*画面初始化*/wall_display();for (int i = 0; i < snake.len; i++){gotoxy(snake.x[i], snake.y[i]);printf("@");}/*运行*/while (1){/*键入方向*/char directionKey = direction_key_capture();if (directionKey == ESC){//system("cls");if (menu() == 1){gotoxy(0, WALLWIDTH );printf(" \n \n \n \n");}else{system("cls");return 0;}}else if (directionKey == NULL){direction = direction;}else if ((directionKey ==UP&&direction==DOWN)||(directionKey == DOWN&&direction == UP)||(directionKey == LEFT&&direction == RIGHT)||(directionKey == RIGHT&&direction == LEFT)){direction = direction;}else{direction = directionKey;}/*移动蛇*/snake_move(direction);/*吃苹果判定*/if (snake.x[0] == applex&&snake.y[0] == appley){snake.len++;apple_gen(applex, appley);}/*失败判定*/for (int i = 1; i < snake.len; i++){if ((snake.x[0] == snake.x[i] && snake.y[0] == snake.y[i]) || snake.x[0] == 0 || snake.x[0] == WALLLENGTH - 1 || snake.y[0] == 0 || snake.y[0] == WALLWIDTH-1){gotoxy(WALLLENGTH / 2 - 4, WALLWIDTH / 2 - 1);printf("游戏结束\n");gotoxy(WALLLENGTH / 2 - 4, WALLWIDTH / 2);printf("分数:%d\n", (snake.len - 3) * 100);gotoxy(0, WALLWIDTH + 1);printf("是否重开?y/n\n");gotoxy(0, 0);char choice = getch();if (choice== 'y'||choice==ENTER)goto restart;elsesystem("cls");return 0;}}/*画面更新*/snake_display();apple_display(applex, appley);/*延时*/Sleep(snake.speed);}return 0;
}