1、作为一个游戏,必须要有个显示的面吧,不然怎么显示出来。 2。贪吃蛇印象中是有着围墙的,而且一碰墙就意味着游戏结束了。 3。既然是贪吃蛇那必须要有食物吧,这个食物也最好是随机的,(不随机我也不会写) 4. 控制蛇的最基本的上下左右 5. 蛇吃了一个食物就会变长一点 6. 暂时没想到,想到在补
好了,开始写吧 首先自然是能要用到得头文件,反正也不知道要哪几个,一股脑全写上得了,这个光标设置的API是什么意思内,我的理解可以认为是“”要控制的窗口“”,不过这个time和conio是什么意思我还不能很明确的表达,不过不要紧,下次遇到再查呗。
#include<stdio.h> #include<stdlib.h> #include<windows.h> //光标设置的API #include<time.h> //随机的食物 #include<conio.h> //按键好了,接着来头文件完了就是基本的宏定义,这里我定义了三个常量,这里的常量是宏定义里的,好记就叫常量了
#define mapchang 25 //地图长 #define mapkuan 60 //地图宽 #define snakesize 50 //蛇的长好了开始正式写,先定义两个结构,也就只有两个,一个蛇,一个蛇吃的食物。
struct food //食物 { int x; //食物的定位 int y; }food; struct snake //蛇 { int x[snakesize]; //记录蛇一节的坐标 int y[snakesize]; int len; //长度 int speed; //移动速度, }snake;再来定义几个全局变量,不要问我为什么在这定义,我也不知道,想到蛇的初始移动方向,
int key = 'w'; //初始化移动方向 int change_flag = 0; //蛇的变化的标志 int init_flag = 0; //初始化标志然后接下来就是各个模块化的设计了,不想打字直接复制粘贴,注意分号,这里就相当于老师常说的你函数没定义那里的定义,放主函数上头
/// 1.画地图 void drawMap(); ///2.食物的产生 void createFood(); ///3.按键操作 void keyDowm(); ///4.蛇的状态,判断是否结束游戏 int snakestatus(); ///5.辅助函数,光标移动 void gotoxy(int x,int y); //TC 里是有的,但现在已经淘汰了,要自己实现接下来就是主函数的定义了 好了,定义完就可以来第一步找到自己的窗口,找窗口可以看成是固定的函数公式就行
//5.辅助函数:光标移动 void gotoxy(int x, int y) { //调用win32 API 去设置控制台的光标位置 //1.找到控制台的这个窗口 HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE); //找到 获取窗口 //2.光标的结构体 COORD coord; // //3.设置坐标 coord.X = x; coord.Y = y; //4.同步到控制台 SetConsoleCursorPosition(handle, coord); }好了,现在外框差不多都好了,现在就要定义之前主函数上那些模块的设计
void drawMap() { //□:蛇身 o:食物 srand((unsigned int)time(NULL)); //随机函数食物坐标 //1.圈墙圈地 //1.1 左右边框 for (int i = 0; i < MAPHEIGHT; i++) { gotoxy(0, i); printf("□"); gotoxy(MAPWIDTH-2, i); printf("□"); } //1.2 上下边框 //+=2因为口占两个字符 for (int i = 0; i < MAPWIDTH; i += 2) { gotoxy(i, 0); //对称 printf("□"); gotoxy(i, MAPHEIGHT-1); printf("□"); } //2.画蛇 //2.1确定蛇的属性 snake.len = 3; // 开始的长度 snake.speed = 700; //kaishi de shu du //开头蛇在屏幕的中间 snake.x[0] = MAPWIDTH / 2; snake.y[0] = MAPHEIGHT / 2; //2.2 化蛇 //化舌头 gotoxy(snake.x[0], snake.y[0]); //蛇头的坐标 printf("□"); //一结是x = 2 //画剩下身体 for (int k = 1; k < snake.len; k++) { snake.x[k] = snake.x[k - 1] + 2; // 等于前面那一节的加2 snake.y[k] = snake.y[k - 1]; gotoxy(snake.x[k], snake.y[k]); //合体 printf("□"); } //3.化食物 要先确定食物被吃 //3.1确定坐标 while (1) { food.x = rand() % (MAPWIDTH - 4); //-4and-2是除去边框的宽度 food.y = rand() % (MAPHEIGHT - 2); if (food.x % 2 == 0) { break; } } //3.2画出来就可以了 gotoxy(food.x, food.y); printf("□"); //2.食物的产生 } void createFood() { //蛇把食物吃了 if (snake.x[0] == food.x&&snake.y[0] == food.y) //蛇的坐标是否等于食物的坐标 { //产生的食物不能再蛇的身上,并且坐标是偶数 因为蛇头的宽度是偶数 srand((unsigned int)time(NULL)); while (1) { int flag = 1; food.x = rand() % (MAPWIDTH - 4) + 2; food.y = rand() % (MAPHEIGHT-2) + 1; //产生的食物不能再蛇的身上 for (int k = 0; k < snake.len; k++) //判断每一节蛇的坐标和食物比较 { if(snake.x[k]==food.x&&snake.y[k] == food.y) { flag = 0; break; } } if (flag&&food.x % 2 == 0) { break; } } gotoxy(food.x,food.y); printf("□"); snake.len++; //吃完边长 changeFlag = 1;//蛇的标记是1 } } //3.按键操作 void keyDown() { //无按键的处理 if (_kbhit()) { // 有按键接收 fflush(stdin); key = _getch(); } //擦除最后的位置 消尾巴 if (!changeFlag) //如果没有移动 { gotoxy(snake.x[snake.len - 1], snake.y[snake.len - 1]); printf(" "); //后面的蛇身 } for (int i = snake.len - 1; i > 0; i--) { snake.x[i] = snake.x[i - 1]; snake.y[i] = snake.y[i - 1]; } //移动方向的处理 switch (key) { case 'w': case 'W': snake.y[0]--; //往上走y-- break; case 's': case 'S': snake.y[0]++; break; case 'A': case 'a': snake.x[0] -= 2; //一个符号占用两个字符 break; case 'd': case 'D': snake.x[0] += 2; break; } gotoxy(snake.x[0], snake.y[0]); //蛇头 printf("□"); changeFlag = 0; //移动标记置为0 gotoxy(MAPHEIGHT + 2, 0); //移动不能一直看着光标 光标从蛇头的位置移开 } //4.蛇的状态:判读是否结束游戏 int snakeStatus() { if (snake.x[0] == 2 || snake.x[0] == MAPWIDTH - 2 || snake.y[0] == 0 ||snake.y[0]== MAPHEIGHT-1) return 0; //蛇头不能撞自己 for(int k=1;k < snake.len; k++) { if (snake.x[0] == snake.x[k] && snake.y[k] == snake.y[0]) return 0; } return 1; } int main(int argc,char*argc[]) { draw_Map(); while (1) { create_Food(); Sleep(snake.spend); key_Dowm(); if (!snake_status()) { break; } } go_to_xy(MAPWIDTH /2 , MAPHEIGHT / 2); printf("GameOver"); system("pause"); return 0; }这里的if是判断蛇的状态的,看它是否碰墙啊撞自己之类的,这个gotoxy是将光标移到中间。 好了,第一篇结束。 成果图如下