一个控制台贪吃蛇小游戏(wsad控制移动)
2013-06-25 12:26
591 查看
/******************************************** * 程序名称:MR.DUAN 的贪吃蛇游戏(链表法) * 作 者:WindAutumn <fluttingleaves@hotmail.com> * 最后修改:2012-7-25-PM * 版 本 号:1.3 * * * 以后有空再修改 * *****************************************/ #include<stdio.h> #include<windows.h> #include<conio.h> #include<time.h> #define MAXWIDE 80 #define MAXHIGH 24 typedef struct { int x; int y; } POSITION; // 食物,节点 typedef struct snackbody { POSITION body; snackbody * link; } SNACK; // 蛇身的链表 void StartGame(); void InitScreen(HANDLE hSnack); void HideCursor(HANDLE hSnack); void GotoXY(HANDLE hSnack, int x, int y); void PrintRandFood(HANDLE hSnack, POSITION * food); void PrintSnack(HANDLE hSnack, SNACK * snack, int mode); //int HeadDirection(); SNACK * SnackHeadWalk(SNACK * snack, int direction); void IsDied(HANDLE hSnack, SNACK * snack, POSITION * food); void GameOver(HANDLE hSnack); void main() { system("color 7b");// 白色背景 SetConsoleTitle("MR.DUAN 的贪吃蛇游戏"); StartGame(); } void StartGame() { POSITION food; SNACK * snack = (SNACK *)malloc(sizeof(SNACK)); char length = 0;// 定义长度 int direction_get = 0;// 定义获取的方向 int direction_last = 0;// 定义之后的方向 int key_direct;// 按下的按键 int foodflag = 0;// 食物是否存在,1--是,0--否 HANDLE hSnack = GetStdHandle(STD_OUTPUT_HANDLE); HideCursor(hSnack); InitScreen(hSnack); srand(time(NULL));// 初始化随机数生成器,以便产生随机 食物 snack->body.x = 40;// 蛇头 snack->body.y = 12; snack->link = NULL; PrintSnack(hSnack, snack, 0);// mode 0 打印初始蛇头 Sleep(500); while(1)// 贪吃蛇操作 { if(_kbhit()) { key_direct = getch(); switch(key_direct) { case 'w' : direction_get = 1; break;// 上// 键盘四按键的逆序 case 'a' : direction_get = 2; break;// 左 case 's' : direction_get = 3; break;// 下 case 'd' : direction_get = 4; break;// 右 } } if((direction_last != direction_get + 2)&&(direction_last != direction_get - 2)) direction_last = direction_get;// 如果行进方向和获取方向不为相反,则改变行进方向 snack = SnackHeadWalk(snack, direction_last); if(0 == foodflag) { PrintRandFood(hSnack, &food);// 如果食物已经被吃,则产生新的食物 foodflag = 1;// 食物标记为 未吃 } if(snack->body.x == food.x && snack->body.y == food.y)// 头碰到食物 { PrintSnack(hSnack, snack, 0);// 只打头不去尾 foodflag = 0;// 食物被吃,没有食物了 length++; } else { PrintSnack(hSnack, snack, 0);// 打头 PrintSnack(hSnack, snack, 1);// 去尾 } IsDied(hSnack, snack, &food); Sleep(500); } } void InitScreen(HANDLE hSnack)// 打印周围红框框 { int i; SetConsoleTextAttribute(hSnack, FOREGROUND_INTENSITY | FOREGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED);// 红色字体,白色背景 GotoXY(hSnack, 0, 0); printf("╔"); for(i=1; i<(MAXWIDE-1)/2; i++) printf("═"); printf("╗"); for(i=1; i< MAXHIGH; i++) { GotoXY(hSnack, 0, i); printf("║"); GotoXY(hSnack, MAXWIDE-2, i); printf("║"); } GotoXY(hSnack, 0, MAXHIGH); printf("╚"); for(i=1; i<(MAXWIDE-1)/2; i++) printf("═"); printf("╝"); GotoXY(hSnack, 0, 0); } void HideCursor(HANDLE hSnack) { CONSOLE_CURSOR_INFO cursor_info = {1, 0}; SetConsoleCursorInfo(hSnack, &cursor_info); } void GotoXY(HANDLE hSnack, int x, int y) { COORD coord; coord.X = x; coord.Y = y; SetConsoleCursorPosition(hSnack, coord); } void PrintRandFood(HANDLE hSnack, POSITION * food)// 2--78 中的偶数, 1--23 { food->x = (rand()%76 + 2)/2*2; food->y = rand()%22 + 1; SetConsoleTextAttribute(hSnack,FOREGROUND_GREEN | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED); GotoXY(hSnack, food->x, food->y); printf("█"); } void PrintSnack(HANDLE hSnack, SNACK * snack, int mode) { if(0 == mode) { GotoXY(hSnack, snack->body.x, snack->body.y); SetConsoleTextAttribute(hSnack,FOREGROUND_BLUE | BACKGROUND_BLUE | BACKGROUND_GREEN | BACKGROUND_RED); printf("□"); } if(1 == mode) { SNACK * ptail, *pnext; ptail = snack; pnext = ptail->link; while(pnext->link!=NULL) { ptail = ptail->link; pnext = ptail->link; } GotoXY(hSnack, pnext->body.x, pnext->body.y); printf(" "); ptail->link = NULL; free(pnext); } } /*int HeadDirection() { HANDLE hInput = GetStdHandle(STD_INPUT_HANDLE); INPUT_RECORD inRec; DWORD res; ReadConsoleInput(hInput, &inRec, 0, &res); if(inRec.EventType == KEY_EVENT) { switch(inRec.Event.KeyEvent.wVirtualKeyCode) { case VK_UP : return 1; case VK_DOWN : return 2; case VK_LEFT : return 3; case VK_RIGHT : return 4; } } return 0; }*/ SNACK * SnackHeadWalk(SNACK * snack, int direction) { // 0为默认值,默认向右,1为向上,2为向下,3为向左,4为向右 SNACK * newhead = (SNACK * )malloc(sizeof(SNACK)); switch(direction) { case 1 : newhead->body.x = snack->body.x; newhead->body.y = snack->body.y - 1; break; case 3 : newhead->body.x = snack->body.x; newhead->body.y = snack->body.y + 1; break; case 2 : newhead->body.x = snack->body.x - 2; newhead->body.y = snack->body.y; break; case 0 : case 4 : newhead->body.x = snack->body.x + 2; newhead->body.y = snack->body.y; break; } newhead->link = snack; return newhead; } void IsDied(HANDLE hSnack, SNACK * snack, POSITION * food) { SNACK * pCompare = snack; if(snack->body.x == 0 || snack->body.y ==0 || snack->body.x == MAXWIDE ||snack->body.y == MAXHIGH) GameOver(hSnack);// 撞墙死亡 while(pCompare->link!=NULL) { if(pCompare->body.x == snack->body.x && pCompare->body.y == snack->body.y && pCompare!=snack) GameOver(hSnack);// 吃到自己死亡 pCompare = pCompare->link; } } void GameOver(HANDLE hSnack) { GotoXY(hSnack, MAXWIDE/2, MAXHIGH/2); printf("GAME OVER!"); GotoXY(hSnack, MAXWIDE/2, MAXHIGH/2 + 1); printf("PRESS ANY KEY TO EXIT."); getch(); exit(0); }
相关文章推荐
- c语言控制台的一个贪吃蛇小游戏
- 糊糊的前端学习笔记——25行代码实现一个贪吃蛇小游戏【Day06】
- J2ME 2D小游戏入门之控制飞机移动
- 一个小游戏的几个关键类(敌人的移动类型)
- 窗体和控件的一个小实验:控制一个飞机左右移动
- 控制台界面控制(七):移动文本
- [Py]一个贪吃蛇小游戏的雏形
- 在Sprite 基础之上创建一个既可以控制移动,也可以动画的对象定义。
- C++控制台贪吃蛇小游戏详细教程
- UE4蓝图控制一个物体的移动
- js实现一个贪吃蛇的小游戏(已经没有Bug了,已经完善)
- 利用方向键来控制一个猪字的移动。
- C++基于控制台实现的贪吃蛇小游戏
- 用链表做控制台下的贪吃蛇小游戏
- 一个贪吃蛇小游戏(17行代码)
- 一个贪吃蛇小游戏 用 C WINAPI 写的
- 一个unix的贪吃蛇小游戏
- C语言写WSAD控制移动
- C#写一个控制台小游戏(猜拳游戏)
- easyX写一个界面程序【控制圈的移动】