精华内容
下载资源
问答
  • c语言编写贪吃蛇

    2014-02-25 17:10:44
    c语言开发贪吃蛇小游戏的源代码 #include #include #include #include #include /*蛇的最大节数*/ #define MAX 200 #define LEFT 10 #define TOP 2 #define RIGHT 50 #define BOTTOM 23 #define TIME 0x1c /...
  • c语言编写贪吃蛇,内附代码,精心编写,注释详尽
  • 贪吃蛇小游戏——C语言编写

    千次阅读 多人点赞 2021-03-07 19:07:51
    完整代码 1.效果展示 2.设计思路 2.1图案显示 利用二维数组构建图案,总共有墙壁,蛇头,蛇身,食物,空白五种元素,因此只需要二维数组中的元素有五种不同的值即可; 2.2蛇头的移动 贪吃蛇是会自动移动的,我们...

    1.效果展示

    在这里插入图片描述

    2.设计思路

    2.1图案显示

    利用二维数组构建图案,总共有墙壁,蛇头,蛇身,食物,空白五种元素,因此只需要二维数组中的元素有五种不同的值即可;
    在这里插入图片描述

    在这里插入图片描述

    2.2蛇头的移动

    贪吃蛇是会自动移动的,我们首先让蛇头能自动移动。由于我们用数组来表示元素在地图中的位置,让元素移动就是让元素的坐标改变。
    因此我们需要构建函数来完成蛇头坐标的自动移动,同时需要对我们输入的方向键做出判断,改变移动的方向。
    在这里插入图片描述

    2.3食物的生成

    食物的生成很简单,只要种下一个随机数种子,然后给一个变量用来判断是否生成食物即可,需要注意的是食物的坐标别越界
    在这里插入图片描述

    2.4蛇身体的生成与移动

    蛇身体的计算:
    首先,蛇身体的移动前必须产生身体即是否吃到食物,可以给一个变量当计数器来判断有多少截身体;

    蛇身体坐标的保存:
    我们需要一个结构体数组,结构体数组的每个元素有两个成员x和y值,这两个值就代表我们的身体在二维数组中的坐标,
    即一个数组成员就代表一截身体;

    蛇身体坐标的获得:
    通过计数器来判断是否有身体,当计数器不为0时,蛇就有了身体,第一截身体的坐标来源就是蛇头吃到食物前的坐标;
    同理,后面吃到的食物增加,计数器的数值变大,就代表我们的结构体数组有多少个有效元素,然后给结构体数组里面的成员进行赋值;
    最后一截身体的数组下标=计数器-1,后面的身体坐标就是前面的身体移动前的坐标,由于我们的头是不断移动的,并且可以直接获得其坐标,所以从最后一截身体开始往前进行拷贝赋值;
    由于我们的赋值特点,数组(蛇身)从后往前进行覆盖式拷贝赋值,即完成了蛇身体的移动

    没有吃到食物时的细节:
    没有吃到食物时,蛇的身体长度是不变的,我们的身体坐标进行改变之后,在二维数组中留下了一个隐患;
    在这里插入图片描述
    在这里插入图片描述

    2.5判断是否撞墙和打印得分

    打印得分:得分即身体的长度即计数器的数值

    判断是否撞墙:判断蛇头的下一个位置在二维数组中是不是1即是不是墙壁即可
    在这里插入图片描述

    3.完整代码

    #ifndef _SNAKE_H_
    #define _SNAKE_H_
    
    #include <stdio.h>
    #include <windows.h>
    #include <time.h>
    #include <stdlib.h>
    #include <conio.h>
    
    
    #define MAX 500 //蛇身个数
    #define ROW 20  
    #define LINE 20
    
    typedef struct Body
    {
    	int x;
    	int y;
    }body;
    
    void MapPrint(char arr[][LINE], int count);//地图打印
    
    void Move(int *row, int *line, char *move);//蛇头移动函数,通过读取输入的键盘方向键来改变蛇头方向
    
    void GetCoordinate(int *row, int *line, char *move);//蛇头自动移动,通过获取的方向信息,决定蛇头往哪个方向自动移
    
    void food(char arr[][LINE], int *x, int *y);//随机生成一个食物
    
    void JudgeFood(int food_x, int food_y, int row, int line, int *count);//判断是否吃到食物
    
    void GetBody(char arr[][LINE], body body[], int count, int temp_x, int temp_y);//蛇体坐标更新
    
    int  Judge(char arr[][LINE], int row, int line);//判断是否撞墙
    
    void Game();
    
    
    #endif
    
    #include "snake.h"
    
    void gotoxy(int x, int y)//将光标移动到(x,y)位置
    {
    	HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
    	COORD pos;
    	pos.X = x;
    	pos.Y = y;
    	SetConsoleCursorPosition(handle, pos);
    
    
    }
    
    void MapPrint(char arr[][LINE],int count)
    {	
    	gotoxy(0, 0);
    	for (int i = 0; i < ROW; i++)
    	{
    		for (int j = 0; j < LINE; j++)
    		{
    			//第一行,最后一行,第一列,最后一列都是墙壁
    			if (arr[i][j]==1)
    				printf("■");
    
    			else if (arr[i][j] == 2)
    				printf("⊙");//蛇头
    
    			else if (arr[i][j] == 3)
    				printf("¤");//打印食物¤
    
    			else if (arr[i][j] == 4)
    				printf("●");//打印身体●
    
    			else
    				printf("  ");//一个墙体占两个空格
    		}
    		printf("\n");
    	}
    	printf("				\n");
    	printf("             当前得分:%d\n", count);
    	printf("				\n");
    }
    void Move(int *row, int *line,char *move)//蛇头移动函数,通过读取输入的键盘方向键来改变蛇头方向
    {
    		if (GetAsyncKeyState(VK_UP))//上
    		{
    			*move = 'w';
    		}
    		else if (GetAsyncKeyState(VK_DOWN))//下
    		{
    			*move = 's';
    		}
    		else if (GetAsyncKeyState(VK_LEFT))//左
    		{
    			*move = 'a';
    		}
    		else if (GetAsyncKeyState(VK_RIGHT))//右
    		{
    			*move = 'd';
    		}
    		GetCoordinate(row, line, move);//将获得的方向键信息传输过去
    }
    
    void GetCoordinate(int *row, int *line, char *move)//蛇头自动移动,通过获取的方向信息,决定蛇头往哪个方向自动移
    {
    	if (*move == 'w')
    		(*row)--;
    	else if (*move == 's')
    		(*row)++;
    	else if (*move == 'a')
    		(*line)--;
    	else if (*move == 'd')
    		(*line)++;
    }
    
    void food(char arr[][LINE],int *x,int *y)//随机生成一个食物
    {
    	int flag = 0;
    	for (int i = 0; i < ROW; i++)
    	{
    		for (int j = 0; j < ROW; j++)
    		{
    			if (arr[i][j] == 3)//食物为3
    				flag = 1;
    		}
    	}
    	if (!flag)//没有食物就生成食物
    	{
    		//食物不能在边框上
    		*x = rand() % (ROW-2)+1;
    		*y = rand() % (LINE-2)+1;
    	}
    }
    
    void JudgeFood(int food_x,int food_y,int row,int line,int *count)//判断是否吃到食物
    {
    	if (food_x == row&&food_y == line)//吃到食物
    	{
    		(*count)++;//吃到食物身体个数+1
    	}
    }
    
    void GetBody(char arr[][LINE], body body[], int count, int temp_x, int temp_y)//蛇体坐标更新
    {
    	//保留前一个蛇体的坐标
    	int befor_x = 0;
    	int befor_y = 0;
    	if (count > 0)//最少有一个蛇身
    	{
    		//记录下最后一个蛇身的位置
    		befor_x = body[count - 1].x;
    		befor_y = body[count - 1].y;
    	}
    	
    	
    	int keep = count;//保存一份蛇体个数
    
    	while (count)//蛇体坐标覆盖,后面的覆盖前面的
    	{
    		if (count == 1)//只有一个蛇体时,为原来蛇头位置
    		{
    			body[count - 1].x = temp_x;
    			body[count - 1].y = temp_y;
    		}
    		else
    		{
    			body[count - 1].x = body[count - 2].x;
    			body[count - 1].y = body[count - 2].y;
    		}
    		count--;
    	}
    
    	while (keep)//将对应的蛇体坐标赋值
    	{
    		arr[body[keep-1].x][body[keep-1].y] = 4;
    		keep--;
    	}
    
    	if (befor_x!=0)//最后一个蛇身的上一次所在位置清空
    	{
    		arr[befor_x][befor_y] = 0;
    	}
    	
    }
    
    int  Judge(char arr[][LINE],int row,int line)//判断是否撞墙
    {
    	if (arr[row][line] == 1)
    	{
    		printf("	 --------------\n");
    		printf("	|   撞到墙壁   |\n");
    		printf("	|   游戏结束   |\n");
    		printf("	 --------------\n");
    		system("pause");
    		return 0;
    	}
    	return 1;
    }
    
    void Game()
    {
    	char arr[ROW][LINE]=
    	{
    		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 ,1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1 },
    		{ 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 },
    
    	};//地图
    
    	int row = 10, line = 10;//蛇头起始位置
    	arr[row][10] = 2;
    
    	char move = 'w';//蛇头开始往上移动
    
    	int food_x = 0, food_y = 0;//食物的x,y坐标
    	srand((unsigned)time(NULL));//随机数种子
    
    	//保留一份蛇头移动前坐标
    	int temp_x = row;
    	int temp_y = line;
    
    	int count = 0;//蛇身体个数
    
    	body body[MAX] = { 0 };//蛇身坐标记录结构体数组
    
    	while (1)
    	{	
    		//生成食物
    		food(arr, &food_x, &food_y);
    		arr[food_x][food_y] = 3;
    
    		MapPrint(arr,count);//打印图形
    
    		if (count==0)
    		arr[row][line] = 0;//没有身体的时候,蛇头原来位置变为空白
    		
    		//保留蛇头移动前的位置
    		temp_x = row;
    		temp_y = line;
    
    		Move(&row, &line,&move);//蛇头移动
    
    		if (Judge(arr, line, row) == 0)//判断是否撞墙
    		{
    			break;
    		}
    
    		JudgeFood(food_x,food_y,row, line, &count);//判断是否吃到食物
    		GetBody(arr, body, count, temp_x, temp_y);//蛇身构造
    		arr[row][line] = 2;//新位置变成蛇头
    
    		Sleep(200);//通过控制休眠时间来控制蛇头移动速度
    	}
    }
    
    
    
    
    #include "snake.h"
    
    int main()
    {
    	
    	Game();
    	printf("游戏结束\n");
    
    	system("pause");
    	return 0;
    }
    
    展开全文
  • 一个C语言编写贪吃蛇游戏

    万次阅读 2015-07-27 15:59:29
    在VC6.0平台上,通过C语言和EasyX图形库编写的贪吃蛇小游戏,为了使用图形库函数,建立的文件是.cpp文件,使用的是C语言编写,游戏具有背景音乐,代码长度500行左右,代码和算法,都是我自己源生的,分享给有兴趣的...

    在VC6.0平台上,通过C语言和EasyX图形库编写的贪吃蛇小游戏,为了使用图形库函数,建立的文件是.cpp文件,使用的是C语言编写,游戏具有背景音乐,代码长度500行左右,代码和算法,都是我自己源生的,分享给有兴趣的朋友看看。

    源代码:

    #include<stdio.h>
    #include<graphics.h>
    #include<time.h>
    #include<conio.h>
    #include<easyx.h>


    #define MAXLEN 30
    #define MAXFOD 6
    #define eror 1
    #define ok 0
    #pragma comment ( lib, "Winmm.lib" )


    enum direction
    {
    left,up,right,down
    };
    int pos[MAXLEN][2];
    int food[MAXFOD][2];
    int LENFOD=0;
    int LENGTH=0;
    int MARK=0;
    int HIGHESTM=0;
    direction DIT;
    int snake();
    int drawLine();
    int init();
    int controlfood();
    int saveMark();
    boolean isdead();
    boolean iswin();
    int countmark();


    void main()
    {
    int i=0,count=1;
    srand((unsigned)time(0));
    initgraph(600,900);
    setcolor(YELLOW);
    setfont( 30, 0,"楷体");
    mciSendString( "open ./source/skycity.mp3 alias skycity", 0, 0, 0 );
    mciSendString( "play skycity repeat ", 0, 0, 0 );
    start:
    cleardevice();
    init();
    /*for(i=0;i<LENGTH;i++)
    printf("\n%d %d",pos[i][0],pos[i][1]);
    printf("\n");
    pos[0][1] -= 1;
    for(i=LENGTH-1;i>0;i--)
    {
    pos[i][0]=pos[i-1][0];
    pos[i][1]=pos[i-1][1];
    }
    closegraph();
    for(i=0;i<LENGTH;i++)
    printf("\n%d %d",pos[i][0],pos[i][1]);
    Sleep(50000);*/
    BeginBatchDraw();
    drawLine();
        snake();
    FlushBatchDraw();


    while(true)
    {
    if(kbhit())
    {
    switch(getch())
    {

    case 27:
    saveMark();
    closegraph();
    exit(ok);
    break;
    case 72:
    case 'w':
    case 'W':
    if(DIT!=down)
    {
    DIT=up;
    for(i=LENGTH-1;i>0;i--)
    {
    pos[i][0]=pos[i-1][0];
    pos[i][1]=pos[i-1][1];
    }
    pos[0][1] -= 1;
    }
    break;
    case 80:
    case 's':
    case 'S':
    if(DIT!=up)
    {
    DIT=down;
    for(i=LENGTH-1;i>0;i--)
    {
    pos[i][0]=pos[i-1][0];
    pos[i][1]=pos[i-1][1];
    }
    pos[0][1] += 1;
    }
    break;
    case 75:
    case 'a':
    case 'A':
    if(DIT!=right)
    {
    DIT=left;
    for(i=LENGTH-1;i>0;i--)
    {
    pos[i][0]=pos[i-1][0];
    pos[i][1]=pos[i-1][1];
    }
    pos[0][0] -= 1;
    }
    break;
    case 77:
    case 'd':
    case 'D':
    if(DIT!=left)
    {
    DIT=right;
    for(i=LENGTH-1;i>0;i--)
    {
    pos[i][0]=pos[i-1][0];
    pos[i][1]=pos[i-1][1];
    }
    pos[0][0] += 1;
    }
    break;
    }
    cleardevice();
    controlfood();
    drawLine();
    countmark();
    snake();
    count=1;
    FlushBatchDraw();
    }
    if(LENGTH<10)
    {
    if(count==20)
    {
    count=0;
    }
    }
    else if(LENGTH<15&&LENGTH>9)
    {
    if(count==15)
    count=0;
    }
    else if(LENGTH<20&&LENGTH>14)
    {
    if(count==10)
    count=0;
    }
    else
    {
    if(count==5)
    count=0;
    }
    if(count==0)
    {
    for(i=LENGTH-1;i>0;i--)
    {
    pos[i][0]=pos[i-1][0];
    pos[i][1]=pos[i-1][1];
    }
    switch(DIT)
    {
    case up:
    pos[0][1] -= 1;
    break;
    case down:
    pos[0][1] += 1;
    break;
    case left:
    pos[0][0] -= 1;
    break;
    case right:
    pos[0][0] += 1;
    break;
    }
    cleardevice();
    controlfood();
    drawLine();
    countmark();
    snake();
    FlushBatchDraw( );
    }
    if(isdead())
    {
    mciSendString( "play Lose ", 0, 0, 0 );
    outtextxy(240,275,"LOSSING!");
    FlushBatchDraw();
    while(true)
    {
    if(kbhit())
    {
    switch(getch())
    {
    case 13:
    mciSendString( "close Lose ", 0, 0, 0 );
    mciSendString( "close win ", 0, 0, 0 );
    goto start;
    case 27:
    mciSendString( "close skycity ", 0, 0, 0 );
    closegraph();
    exit(ok);
    }
    }
    }
    }
    if(iswin())
    {
    mciSendString( "play win ", 0, 0, 0 );
    outtextxy(240,275,"WINNING!");
    FlushBatchDraw();
    while(true)
    {
    if(kbhit())
    {
    switch(getch())
    {
    case 13:
    mciSendString( "close Lose ", 0, 0, 0 );
    mciSendString( "close win ", 0, 0, 0 );
    goto start;
    case 27:
    mciSendString( "close skycity ", 0, 0, 0 );
    closegraph();
    exit(ok);
    }
    }
    }
    }
    count++;
    Sleep(20);
    }
    }


    int snake()
    {
    int i=0,j=0;
    setfillcolor(YELLOW);
    for(i=0;i<LENGTH;i++)
    solidcircle(pos[i][0]*20+10,pos[i][1]*20+10,10);
    setfillcolor(RED);
    i=0;
    if(DIT==left)
    {
    solidcircle(pos[i][0]*20+5,pos[i][1]*20+5,3);
    solidcircle(pos[i][0]*20+5,pos[i][1]*20+15,3);
    }
    else if(DIT==right)
    {
    solidcircle(pos[i][0]*20+15,pos[i][1]*20+5,3);
    solidcircle(pos[i][0]*20+15,pos[i][1]*20+15,3);
    }
    else if(DIT==down)
    {
    solidcircle(pos[i][0]*20+5,pos[i][1]*20+15,3);
    solidcircle(pos[i][0]*20+15,pos[i][1]*20+15,3);
    }
    else
    {
    solidcircle(pos[i][0]*20+5,pos[i][1]*20+5,3);
    solidcircle(pos[i][0]*20+15,pos[i][1]*20+5,3);
    }
    setfillcolor(GREEN);
    //setfont( 18, 0,"楷体");
    for(i=0;i<LENFOD;i++)
    {
    solidcircle(food[i][0]*20+10,food[i][1]*20+10,7);
    /*j=rand()%2;
    if(j==0)
    {
    outtextxy(food[i][0]*20+1,food[i][1]*20+1,"");
    }
    else if(j==1)
    {
    outtextxy(food[i][0]*20+1,food[i][1]*20+1,"");
    }
    else
    {
    outtextxy(food[i][0]*20+1,food[i][1]*20+1,"");
    }*/
    }
    //setfont( 30, 0,"楷体");
    //solidcircle(food[i][0]*20+10,food[i][1]*20+10,7);
    setfillcolor(GREEN);
    return ok;
    }
    int drawLine()
    {
    int i;
    for(i=20;i<600;i+=20)
    {
    line(0,i,600,i);
    line(i,0,i,600);
    }
    line(0,i,600,i);
    line(0,i+5,600,i+5);
    return ok;
    }
    int init()
    {
    int i,j,k,l;
    FILE * fp;
    mciSendString( "open ./source/Lose.mp3 alias Lose", 0, 0, 0 );
    mciSendString( "open ./source/win.mp3 alias win", 0, 0, 0 );
    LENGTH=0;
    LENFOD=0;
    MARK=0;
    if((fp=fopen("highestscore.txt","r"))==NULL)
    {
    printf("File open eror!\n");
    exit(eror);
    }
    else
    {
    fscanf(fp,"%d",&HIGHESTM);
    if(fclose(fp))
    {
    printf("file close eror\n");
    exit(eror);
    }
    }
    setlinecolor(GREEN);
    setfillcolor(YELLOW);
    i=rand()%10+10;
    j=rand()%10+10;
    k=rand()%4;
        pos[0][0] = i;
    pos[0][1] = j;
    if(k==0)
    {
    for(i=1;i<5;i++)
    {
    pos[i][1]=pos[i-1][1]+1;
    pos[i][0]=pos[i-1][0];
    DIT=up;
    }
    }
    else if(k==1)
    {
    for(i=1;i<5;i++)
    {
    pos[i][0]=pos[i-1][0]-1;
    pos[i][1]=pos[i-1][1];
    DIT=right;
    }
    }
    else if(k==2)
    {
    for(i=1;i<5;i++)
    {
    pos[i][1]=pos[i-1][1]-1;
    pos[i][0]=pos[i-1][0];
    DIT=down;
    }
    }
    else
    {
    for(i=1;i<5;i++)
    {
    pos[i][0]=pos[i-1][0]+1;
    pos[i][1]=pos[i-1][1];
    DIT=left;
    }
    }
    LENGTH=5;
    k=rand()%4+1;
    for(l=0;l<k;l++)
    {
    i=rand()%30;
       j=rand()%30;
    food[LENFOD][0]=i;
    food[LENFOD++][1]=j;
    for(int m=0;m<LENGTH;m++)
    if(i==pos[m][0]&&j==pos[m][1])
    {
    l--;
    LENFOD--;
    break;
    }
    }
    return ok;
    }
    int controlfood()
    {
    int i=0,j,k,l;
    for(i=0;i<LENFOD;i++)
    {
    if(pos[0][0]==food[i][0]&&pos[0][1]==food[i][1])
    {
    if(LENGTH<10)
    {
    MARK+=5;
    }
    else if(LENGTH<15)
    {
    MARK+=10;
    }
    else if(LENGTH<20)
    {
    MARK+=15;
    }
    else if(LENGTH<25)
    {
    MARK+=20;
    }
    else
    {
    MARK+=25;
    }
    break;
    }
    }
    if(i<LENFOD)
    {
    for(j=i;j<LENFOD-1;j++)
    {
    food[j][0]=food[j+1][0];
    food[j][1]=food[j+1][1];
    }
    LENFOD--;
    LENGTH++;
    pos[LENGTH-1][0]=pos[LENGTH-2][0]*2-pos[LENGTH-3][0];
    pos[LENGTH-1][1]=pos[LENGTH-2][1]*2-pos[LENGTH-3][1];
    }
    if(LENFOD<2)
    {
    k=rand()%4+1;
    for(l=0;l<k;l++)
    {
    i=rand()%30;
    j=rand()%30;
    food[LENFOD][0]=i;
    food[LENFOD++][1]=j;
    for(int m=0;m<LENGTH;m++)
    if(i==pos[m][0]&&j==pos[m][1])
    {
    l--;
    LENFOD--;
    break;
    }
    }
    }
    return ok;
    }
    boolean isdead()
    {
    int i;
    if(pos[0][0]<0||pos[0][0]>30||pos[0][1]<0||pos[0][1]>30)
    {
    saveMark();
    return true;
    }
    for(i=3;i<LENGTH;i++)
    if(pos[0][0]==pos[i][0]&&pos[0][1]==pos[i][1])
    return true;
    return false;
    }
    boolean iswin()
    {
    if(LENGTH==MAXLEN&&!isdead())
    {
    saveMark();
    return true;
    }
    else 
    return false;
    }
    int countmark()
    {
    char num[10];
    sprintf(num, "%d", HIGHESTM);
    outtextxy(60,610,"Highest:");
    outtextxy(200,610,num);
    outtextxy(350,610,"YouScore:");
    sprintf(num, "%d", MARK);
    outtextxy(490,610,num);
    return ok;
    }
    int saveMark()
    {
    FILE * fp;
    if(MARK>HIGHESTM)
    {
    if((fp=fopen("highestscore.txt","w"))==NULL)
    {
    printf("File open eror!\n");
    exit(eror);
    }
    else
    {
    fprintf(fp,"%d",MARK);
    if(fclose(fp))
    {
    printf("file close eror\n");
    exit(eror);
    }
    }
    }
    return ok;
    }

    展开全文
  • 最近学完C语言后浑身精力澎湃总想做点什么东西 (结果差点被现实打的肿透了脸qwq ) 于是四处找项目,最终锁定贪吃蛇,曾经诺基亚上的小游戏给我的印象还是挺深的,最后在浏览其他一些大佬的项目后,了解具体思路就...

           这好像是第一次发博客hhh,最近学完C语言后浑身精力澎湃总想做点什么东西 (结果差点被现实打的肿透了脸qwq ) 于是四处找项目,最终锁定贪吃蛇,曾经诺基亚上的小游戏给我的印象还是挺深的,最后在浏览其他一些大佬的项目后,了解具体思路就上手尝试做了个简陋一点的版本,由于自己也是初学者,所以 代码有很多的不足,仅供交流参考


    前言

           贪吃蛇的原理较为简单,简单版本的利用数组就能对其进行主要功能的实现,当然如果有一定的C语言基础,写出这个应该是不难的。编程环境:VScode + gcc 9.2.0(为什么vscode不能装eazyX 呜呜呜)

    思路参考这位大佬的博客:https://blog.csdn.net/zs120197/article/details/88420297
    需要思路详解可以进去看看,讲的很详细。



          效果图如下:

    初始界面:
    在这里插入图片描述


    游戏界面:
    在这里插入图片描述


    提示:以下是本篇文章正文内容,下面案例可供参考

    一、主要功能的实现

    1.界面显示:主要通过光标定位后循环打印某些字符来组成整体画面以及一些常驻信息,然后通过函数来刷新消除显示残留。


    2.果子生成:果子分为小果子跟奖励果子,每吃相应数量的小果子就会生成一个奖励果子,通过 srand() 与 rand() 函数生成 伪随机数 来实现。


    3.控制部分:通过 _kbhit() 函数及 _getch() 函数 配合if语句进行监控键盘输入,来实现 蛇的控制以及菜单移动


    4.菜单部分:这部分我并没有用传统的输入数字用switch() 函数控制,而是模仿"诺基亚"那样用键盘控制,这部分代码或许会较为冗长,各位自己优化吧嘿嘿。


    二、部分函数提要

    1.光标定位

           由于这个程序并没有应用到 eazyX 的图形库 (为什么vscode装不了呜呜呜) ,所以需要另外的函数来进行界面内光标的定位来进行具体位置的绘制。

    // 光标定位
    void gotoxy(int x,int y)
    {
        HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);    //取句柄
        COORD coord;    //设置光标
        coord.X = x;
        coord.Y = y;
        SetConsoleCursorPosition(handle, coord); //定位到handle这个窗口,把光标移到coord坐标
    }
    

    需要深入了解的话参考以下:
           https://baike.baidu.com/item/SetConsoleCursorPosition/575826>
           https://baike.baidu.com/item/GetStdHandle/6909878?fr=aladdin
           https://baike.baidu.com/item/coord/4594820?fr=aladdin


    2.Windows界面设置

           谁不想让自己写的程序好看点,所以这边调用了系统函数进行黑框框的美化(没有图形库最大的美化只能这样了 ╮(╯_╰)╭ )

    // CMD图形界面设置
    void WindowsInterface()
    {
        system("color 87");
        system("title Greedy Snake V1.4");
        system("mode con:cols=120 lines=29");
    }
    

    另外关于system(“color xx”)函数:
    第一个为背景色,第二个为字体颜色
    0 = 黑色       8 = 灰色
    1 = 蓝色       9 = 淡蓝色
    2 = 绿色       A = 淡绿色
    3 = 湖蓝色   B = 淡浅绿色
    4 = 红色       C = 淡红色
    5 = 紫色       D = 淡紫色
    6 = 黄色       E = 淡黄色
    7 = 白色       F = 亮白色
    ( 试了一个小时还是前白后灰最好看 )


    三、主要模块

    1. 库函数、变量与函数定义

    所需的库函数、定义的变量及结构体如下

    #include<stdio.h>
    #include<stdlib.h>
    #include<Windows.h>
    #include<time.h>
    #include<conio.h>
    #include<time.h>
    #define maphigh 28				//定义墙的长宽
    #define mapwide 84
    unsigned short Snake_size = 500, Snake_speed = 150, Snake_lenth = 3, key = 'w';	//初始化相关
    int Scores = 0, fruitBonus = 3, BigfruitBonus = 24//与分数有关
    int coodr = 12;       		//与菜单控制有关
    struct fruit		//小果子相关
    {
        int number;
        int x;
        int y;
    }fruit;
    struct Bigfruit		//奖励果子相关
    {
        int number;
        int x;
        int y;
    }Bigfruit;
    struct snake		//蛇主体相关
    {
        int x[500];
        int y[500];
        int len;
        int speed;
    }snake;
    
    int Deathjudge();
    void Menu();
    void Game();
    void VertionInformation();
    void WindowsInterface();
    void gotoxy(int x,int y);
    void drawmenu();
    void drawmap();
    void ClearMenu();
    void ClearGames();
    void control();
    void Initialize();
    void creatfruit();
    void CreatBigFruit();
    void Score();
    //以上是所需的库函数与定义
    


    2. 游戏主体

    游戏的主体主要由绘制、控制、果子生成以及死亡判定组成。先附上游戏主体的主函数:

    // 游戏主程序
    void Game()
    {
        Initialize();
        for(;;)							//空循环实现不断运行游戏(游戏结束不关闭)
        {
            system("cls");				//系统清屏函数
            drawmap();					//游戏初始界面绘制
            getch();
            for(;;)
            {
                control();				//控制函数
                creatfruit();			//果子生成函数(包含奖励果子)
                Score();				//分数系统
                Sleep(Snake_speed);     //void sleep(int seconds),参数 seconds为要暂停的毫秒数。
                if (!Deathjudge())     //死亡条件,死亡时 Deathjudge = 0
                {
                    gotoxy(mapwide/2,maphigh/2);
                    printf("GAME OVER!!!");
                    getchar();
                    break;				//游戏结束时开启新一轮循环
                }
            }
        }
    }
    


      2.1  绘制部分

    绘制部分 利用打印与刷新来保证内容显示不出错,以下是初始界面绘制:

    // 绘制游戏界面
    void drawmap()
    {
        int i,k;
    
        //绘制地图
        for ( i = 0; i <= mapwide; i += 2)      //绘制上下边界
        {
            gotoxy(i, 0);
            printf("█");
            gotoxy(i, maphigh);
            printf("█");
        }
        for ( i = 0; i <= maphigh; i++)         //绘制左右边界
        {
            gotoxy(0,i);
            printf("█");
            gotoxy(mapwide,i);
            printf("█");
        }
    
        //绘制蛇
        snake.len = Snake_lenth;
        snake.speed = Snake_speed;
        snake.x[0] = mapwide/2;
        snake.y[0] = maphigh/2;
    
        gotoxy(snake.x[0],snake.y[0]);          //蛇头
        printf("█");
        for ( k = 1; k < snake.len; k++)        //蛇身
        {
            snake.x[k] = snake.x[k - 1] + 2;
            snake.y[k] = snake.y[k - 1];
            gotoxy(snake.x[k],snake.y[k]);
            printf("█");
        }
        
        srand((unsigned int)time(NULL));        //srand()与rand()函数随机生成果子位置
        while(1)
        {
            fruit.x = rand() % (mapwide - 4 ) + 1;       // + 1 与果子的符号所占的字符有关
            fruit.y = rand() % (maphigh - 2 ) + 1;
            if (fruit.x % 2 == 0)
                break;
        }
        gotoxy(fruit.x,fruit.y);				//绘制小果子
        printf("*");
    
        //右侧内容标注
        gotoxy(mapwide + 8, 6);					//移动到右侧标注位置
    	printf(" W");
    	gotoxy(mapwide + 6, 8);
    	printf("A  S  D    进行控制");
        gotoxy(mapwide + 6, 12);
    	printf("按 '空格' 以暂停");
        gotoxy(mapwide + 6, 18);
    	printf("Scores : %d",Scores);
    }
    
    

           以下部分是 游戏界面刷新 ,由于绘制会产生显示残留,目前所掌握的知识也没有更好的办法,所以就只能通过刷新后再绘制来进行消除显示残留,希望后续有大佬可以优化一下,代码如下:

    // 刷新游戏界面(清屏并绘制常驻信息)
    void ClearGames()
    {
        int i,k;
        system("cls");
        for ( i = 0; i <= mapwide; i += 2)      //绘制边界
        {
            gotoxy(i, 0);
            printf("█");
            gotoxy(i, maphigh);
            printf("█");
        }
        for ( i = 0; i <= maphigh; i++)
        {
            gotoxy(0,i);
            printf("█");
            gotoxy(mapwide,i);
            printf("█");
        }
        gotoxy(snake.x[0],snake.y[0]);          //绘制蛇
        printf("█");
        for ( k = 1; k < snake.len; k++)
        {
            gotoxy(snake.x[k],snake.y[k]);
            printf("█");
        }
        gotoxy(fruit.x,fruit.y);                //绘制果子
        printf("*");
        gotoxy(mapwide + 8, 6);                 //绘制右侧信息
    	printf(" W");
    	gotoxy(mapwide + 6, 8);
    	printf("A  S  D    进行控制");
        gotoxy(mapwide + 6, 12);
    	printf("按 '空格' 以暂停");
        gotoxy(mapwide + 6, 18);
    	printf("Scores : %d",Scores);
    }
    
    


      2.2  控制部分

    控制模块由 _kihit()函数与 _getch()函数配合if 语句构成。当键盘键入WASD或空格时进行对应操作。

    // 控制模块
    void control()
    {
        int i,temp;
        if (_kbhit())           //kbhit函数监控当前是否有键盘输入
        {
            fflush(stdin);      //清空缓冲区
            temp = _getch();
            if((temp == 'a' || temp == 'A') && (key !='D' && key !='d')) //防止反方向输入导致自杀
            {
                key = temp;
            }
            if((temp == 'd' || temp == 'D') && (key !='a' && key !='A'))
            {
                key = temp;
            }
            if((temp == 'w' || temp == 'W') && (key !='S' && key !='s'))
            {
                key = temp;
            }
            if((temp == 's' || temp == 'S') && (key !='w' && key !='W'))
            {
                key = temp;
            }
            if((temp == ' '))		//实现键入'空格'暂停
            {
                getch();
            }
        }
    
        gotoxy(snake.x[snake.len - 1], snake.y[snake.len - 1]);     //删去蛇的最后一节
        printf("  ");
    
        for ( 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]--;
                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("█");
    }
    


      2.3  果子生成

           果子生成分为小果子与奖励果子,均通过srand()函数与rand()函数实现随机生成,由于先前绘制游戏界面时已生成小果子,所以只需要进行生成新果子即可,小果子生成代码如下:

    void creatfruit()
    {
        if(snake.x[0] == fruit.x && snake.y[0] == fruit.y)        //当蛇吃掉小果子
        {
            snake.len++;
            fruit.number++;
            snake.speed -= 1;			//使身长越长速度越快
            Bigfruit.x = 0;            //防止大果子一直存在(小果子被吃掉时大果子消失)
            Bigfruit.y = 0;
            if(fruit.number %5 == 0)	//当吃掉 5个小果子时,生成一个奖励果子
            {
                CreatBigFruit();
            }
            
            srand((unsigned)time(NULL));
            
            while(1)
            {
                int tag = 1;
                fruit.x = rand() % (mapwide - 4 ) + 1;
                fruit.y = rand() % (maphigh - 2 ) + 1;
    
                for (int k = 0; k < snake.len; k++)         //防止fruit生成在蛇身上
                {
                    if (snake.x[k] == fruit.x && snake.y[k] == fruit.y)     //判断是否在蛇身上
                    {
                        tag = 0;
                        break;
                    }
                }
    
                if (tag == 1 && fruit.x %2 ==0)break;		//仅有当tag = 1时的小果子坐标才会被应用
            }
        }
        gotoxy(fruit.x,fruit.y);						//取小果子坐标并打印
        printf("*");
    
        if(snake.x[0] == Bigfruit.x && snake.y[0] == Bigfruit.y)        //当蛇吃大果子时
        {
            // printf("\a");
            snake.len+=2;
            Bigfruit.number++;
            snake.speed -= 2;
            ClearGames();           //刷新函数,防止果子被吃掉后仍残留在屏幕上
            Bigfruit.x = 0;
            Bigfruit.y = 0;
        }
    }
    

    此外,生成奖励果子的代码如下:

    // 生成奖励果子(原理同上)
    void CreatBigFruit()
    {
        int ret = 1;
        srand((unsigned)time(NULL));
            while(1)
            {
                Bigfruit.x = rand() % (mapwide- 8) + 2;
                Bigfruit.y = rand() % (maphigh- 4) + 2;
    
                for (int k = 0; k < snake.len; k++)         //防止 Bigfruit生成在蛇身上
                {
                    if (snake.x[k] == Bigfruit.x && snake.y[k] == Bigfruit.y)     //判断是否在蛇身上
                    {
                        ret = 0;
                        break;
                    }
                }
                if (ret == 1 && Bigfruit.x %2 ==0)break;
            }
        gotoxy(Bigfruit.x,Bigfruit.y);
        printf("★");
    }
    


      2.4  死亡判定

    死亡判断较简单,仅需判断 蛇头坐标墙体蛇身 是否重合即可。

    // 死亡判定
    int Deathjudge()
    {
        int ret;
        if ((snake.x[0] == 0 || snake.x[0] == mapwide) || (snake.y[0] == 0 || snake.y[0] == maphigh))
            return 0;
            
        for (int i = 1; i < snake.len; i++)
        {
            if(snake.x[0] == snake.x[i] && snake.y[0] == snake.y[i])
                return 0;
        }
        return 1;
    }
    

    3. 初始菜单

    首先绘制初始的菜单界面,由于箭头光标进行上下移动时会产生显示残留,所以需要一个菜单的刷新函数,最后就是菜单光标的控制

      3.1  绘制菜单

    绘制初始菜单界面,代码如下:

    // 绘制菜单界面
    void drawmenu()
    {
        int i;
        system("cls");
        for ( i = 0; i <= mapwide; i += 2)      //绘制边界
        {
            gotoxy(i, 0);
            printf("█");
            gotoxy(i, maphigh);
            printf("█");
        }
        for ( i = 0; i <= maphigh; i++)
        {
            gotoxy(0,i);
            printf("█");
            gotoxy(mapwide,i);
            printf("█");
        }
    
        gotoxy(mapwide + 9, 2);					//绘制右侧信息栏
        printf("Greedy Snake V1.4");
        gotoxy(mapwide + 8, 6);
    	printf("按 W 或 S 进行控制.");
        gotoxy(mapwide + 9, 8);
        printf("按 空格 进行选择.");
        
        gotoxy(mapwide + 9, coodr);
        printf("->");
        gotoxy(mapwide + 13, coodr);
        printf("开始游戏");
        gotoxy(mapwide + 13, coodr + 3);
        printf("版本信息");
        gotoxy(mapwide + 13, coodr + 6);
        printf("退出游戏");
    }
    

      3.2  刷新菜单

    防止光标移动后在原先位置留下残留,刷新界面后绘制常驻信息

    void ClearMenu()
    {
        int i;
        system("cls");
        for ( i = 0; i <= mapwide; i += 2)      //绘制边界
        {
            gotoxy(i, 0);
            printf("█");
            gotoxy(i, maphigh);
            printf("█");
        }
        for ( i = 0; i <= maphigh; i++)
        {
            gotoxy(0,i);    
            printf("█");
            gotoxy(mapwide,i);
            printf("█");
        }
        gotoxy(mapwide + 9, 2);					//右侧信息栏
        printf("Greedy Snake V1.4");
        gotoxy(mapwide + 8, 6);
    	printf("按 W 或 S 进行控制.");
        gotoxy(mapwide + 9, 8);
        printf("按 空格 进行选择.");
        gotoxy(mapwide + 13, coodr);
        printf("开始游戏");
        gotoxy(mapwide + 13, coodr + 3);
        printf("版本信息");
        gotoxy(mapwide + 13, coodr + 6);
        printf("退出游戏");
    }
    

      3.4  菜单控制

    为了还原诺基亚的感觉, 菜单 的实现并没有直接使用switch语句接收键盘输入的数字,而是用_kbhit() 函数监控键盘输入来实现键入特定字符来上下移动"光标" 与功能选择。

    void Menu()
    {
        int i = 1, end = 3;
        int temp;
        drawmenu();         //绘制菜单
        for (;;)            //光标控制
        {
            if (_kbhit())
            {
                fflush(stdin);
                temp = _getch();
                
                if(temp == 'w' || temp == 'W')		//当检测到输入w时
                {
                    if(i>1 && i<= end)
                    {
                        ClearMenu();			//刷新菜单界面
                        i--;
                        gotoxy(mapwide + 7,coodr + 3*(i-1));
                        printf("  ");
                        printf("->");
    
                    }
                }
                if(temp == 's' || temp == 'S')		//当检测到输入s时
                {
                    if(i>=1 && i< end)
                    {
                        ClearMenu();
                        i++;
                        gotoxy(mapwide + 7,coodr + 3*(i-1));
                        printf("  ");
                        printf("->");
                    }
                }
    
                if(temp == ' ')         //空格选择功能
                {
                    break;
                }
            }
        }
    
        switch (i)
        {
        case 1:
            Game();
            break;
        
        case 2:
            VertionInformation();
            return Menu();				//回到菜单
    
        case 3:
            exit(0);					//自带的退出程序函数
        }
    }
    

    4. 主函数入口

    由于添加了菜单界面,所以主函数入口应该从菜单进入以保持循环不断。

    int main()
    {
        WindowsInterface();			//设置 CMD 参数
        Menu();
        return 0;
    }
    

    5. 源代码

    全部源代码如下:

    #include<stdio.h>
    #include<stdlib.h>
    #include<Windows.h>
    #include<time.h>
    #include<conio.h>
    #include<time.h>
    #define maphigh 28
    #define mapwide 84
    unsigned short Snake_size = 500, Snake_speed = 150, Snake_lenth = 3, key = 'w';
    int Scores = 0, fruitBonus = 3, BigfruitBonus = 24, coodr = 12;
    char vertion[15] = "V1.4";
    struct fruit
    {
        int number;
        int x;
        int y;
    }fruit;
    struct Bigfruit
    {
        int number;
        int x;
        int y;
    }Bigfruit;
    struct snake
    {
        int x[500];
        int y[500];
        int len;
        int speed;
    }snake;
    
    int Deathjudge();
    void Menu();
    void Game();
    void VertionInformation();
    void WindowsInterface();
    void gotoxy(int x,int y);
    void drawmenu();
    void drawmap();
    void ClearMenu();
    void ClearGames();
    void control();
    void Initialize();
    void creatfruit();
    void CreatBigFruit();
    void Score();
    
    int main()
    {
        WindowsInterface();
        Menu();
        return 0;
    }
    
    
    /************************************************************************************/
    // 游戏主程序
    void Game()
    {
        Initialize();
        for(;;)
        {
            system("cls");
            drawmap();
            getch();
            for(;;)
            {
                control();
                creatfruit();
                Score();
                Sleep(Snake_speed);     //void sleep(int seconds),参数 seconds 为要暂停的毫秒数。
                if (!Deathjudge())     //死亡时Deathjudge = 0
                {
                    gotoxy(mapwide/2,maphigh/2);
                    printf("GAME OVER!!!");
                    getchar();
                    break;
                }
            }
        }
    }
    /************************************************************************************/
    // CMD图形界面设置
    void WindowsInterface()
    {
        system("color 87");
        system("title Greedy Snake V1.4");
        system("mode con:cols=120 lines=29");
    }
    /************************************************************************************/
    // 初始化
    void Initialize()
    {
    	fruit.number = 0;
    	Bigfruit.number = 0;
    }
    /************************************************************************************/
    // 光标定位
    void gotoxy(int x,int y)
    {
        HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);    //取句柄
        COORD coord;    //设置光标
        coord.X = x;
        coord.Y = y;
        SetConsoleCursorPosition(handle, coord); //定位到handle这个窗口,把光标移到coord坐标
    }
    /************************************************************************************/
    // 绘制游戏界面
    void drawmap()
    {
        int i,k;
    
        //绘制地图
        for ( i = 0; i <= mapwide; i += 2)      //绘制上下边界
        {
            gotoxy(i, 0);
            printf("█");
            gotoxy(i, maphigh);
            printf("█");
        }
        for ( i = 0; i <= maphigh; i++)         //绘制左右边界
        {
            gotoxy(0,i);
            printf("█");
            gotoxy(mapwide,i);
            printf("█");
        }
    
    
        //绘制蛇
        snake.len = Snake_lenth;
        snake.speed = Snake_speed;
        snake.x[0] = mapwide/2;
        snake.y[0] = maphigh/2;
    
        gotoxy(snake.x[0],snake.y[0]);          //蛇头
        printf("█");
        for ( k = 1; k < snake.len; k++)        //蛇身
        {
            snake.x[k] = snake.x[k - 1] + 2;
            snake.y[k] = snake.y[k - 1];
            gotoxy(snake.x[k],snake.y[k]);
            printf("█");
        }
    
        srand((unsigned int)time(NULL));        //随机生成果子位置
        while(1)
        {
            fruit.x = rand() % (mapwide - 4 ) + 1;       // + 1 与 * 所占的字符有关
            fruit.y = rand() % (maphigh - 2 ) + 1;
            if (fruit.x % 2 == 0)
                break;
        }
        gotoxy(fruit.x,fruit.y);
        printf("*");
    
        //右侧标注
        gotoxy(mapwide + 8, 6);
    	printf(" W");
    	gotoxy(mapwide + 6, 8);
    	printf("A  S  D    进行控制");
        gotoxy(mapwide + 6, 12);
    	printf("按 '空格' 以暂停");
        gotoxy(mapwide + 6, 18);
    	printf("Scores : %d",Scores);
    }
    /************************************************************************************/
    // 刷新游戏
    void ClearGames()
    {
        int i,k;
        system("cls");
        for ( i = 0; i <= mapwide; i += 2)      //绘制边界
        {
            gotoxy(i, 0);
            printf("█");
            gotoxy(i, maphigh);
            printf("█");
        }
        for ( i = 0; i <= maphigh; i++)
        {
            gotoxy(0,i);
            printf("█");
            gotoxy(mapwide,i);
            printf("█");
        }
    
        gotoxy(snake.x[0],snake.y[0]);          //绘制蛇
        printf("█");
        for ( k = 1; k < snake.len; k++)
        {
            gotoxy(snake.x[k],snake.y[k]);
            printf("█");
        }
    
        gotoxy(fruit.x,fruit.y);                //绘制果子
        printf("*");
    
        gotoxy(mapwide + 8, 6);                 //绘制右侧信息
    	printf(" W");
    	gotoxy(mapwide + 6, 8);
    	printf("A  S  D    进行控制");
        gotoxy(mapwide + 6, 12);
    	printf("按 '空格' 以暂停");
        gotoxy(mapwide + 6, 18);
    	printf("Scores : %d",Scores);
    }
    /************************************************************************************/
    // 绘制菜单界面
    void drawmenu()
    {
        int i;
        system("cls");
        for ( i = 0; i <= mapwide; i += 2)      //绘制边界
        {
            gotoxy(i, 0);
            printf("█");
            gotoxy(i, maphigh);
            printf("█");
        }
        for ( i = 0; i <= maphigh; i++)
        {
            gotoxy(0,i);
            printf("█");
            gotoxy(mapwide,i);
            printf("█");
        }
    
        gotoxy(mapwide + 9, 2);
        printf("Greedy Snake V1.4");
        gotoxy(mapwide + 8, 6);
    	printf("按 W 或 S 进行控制.");
        gotoxy(mapwide + 9, 8);
        printf("按 空格 进行选择.");
    
        gotoxy(mapwide + 9, coodr);
        printf("->");
        gotoxy(mapwide + 13, coodr);
        printf("开始游戏");
        gotoxy(mapwide + 13, coodr + 3);
        printf("版本信息");
        gotoxy(mapwide + 13, coodr + 6);
        printf("退出游戏");
    }
    /************************************************************************************/
    // 刷新菜单
    void ClearMenu()
    {
    
        int i;
        system("cls");
        for ( i = 0; i <= mapwide; i += 2)      //绘制边界
        {
            gotoxy(i, 0);
            printf("█");
            gotoxy(i, maphigh);
            printf("█");
        }
        for ( i = 0; i <= maphigh; i++)
        {
            gotoxy(0,i);    
            printf("█");
            gotoxy(mapwide,i);
            printf("█");
        }
    
        gotoxy(mapwide + 9, 2);
        printf("Greedy Snake V1.4");
        gotoxy(mapwide + 8, 6);
    	printf("按 W 或 S 进行控制.");
        gotoxy(mapwide + 9, 8);
        printf("按 空格 进行选择.");
    
        gotoxy(mapwide + 13, coodr);
        printf("开始游戏");
        gotoxy(mapwide + 13, coodr + 3);
        printf("版本信息");
        gotoxy(mapwide + 13, coodr + 6);
        printf("退出游戏");
    }
    /************************************************************************************/
    // 菜单控制
    void Menu()
    {
        int i = 1, end = 3;
        int temp;
    
        drawmenu();         //绘制菜单
    
        for (;;)            //光标控制
        {
            if (_kbhit())
            {
                fflush(stdin);
                temp = _getch();
    
                if(temp == 'w' || temp == 'W')
                {
                    if(i>1 && i<= end)
                    {
                        ClearMenu();
                        i--;
                        gotoxy(mapwide + 7,coodr + 3*(i-1));
                        printf("  ");
                        printf("->");
    
                    }
                }
                if(temp == 's' || temp == 'S')
                {
                    if(i>=1 && i< end)
                    {
                        ClearMenu();
                        i++;
                        gotoxy(mapwide + 7,coodr + 3*(i-1));
                        printf("  ");
                        printf("->");
                    }
                }
    
                if(temp == ' ')         //空格选择
                {
                    break;
                }
            }
        }
    
        switch (i)
        {
        case 1:
            Game();
            break;
        
        case 2:
            VertionInformation();
            return Menu();
    
        case 3:
            exit(0);
        }
    }
    /************************************************************************************/
    // 生成新果子
    void creatfruit()
    {
        if(snake.x[0] == fruit.x && snake.y[0] == fruit.y)        //当蛇吃掉小果子
        {
            snake.len++;
            fruit.number++;
            snake.speed -= 2;
            Bigfruit.x = 0;            //防止大果子一直存在(小果子被吃掉时大果子消失)
            Bigfruit.y = 0;
            if(fruit.number %5 == 0)
            {
                CreatBigFruit();
            }
            srand((unsigned)time(NULL));
            while(1)
            {
                int tag = 1;
                fruit.x = rand() % (mapwide - 4 ) + 1;
                fruit.y = rand() % (maphigh - 2 ) + 1;
    
                for (int k = 0; k < snake.len; k++)         //防止fruit生成在蛇身上
                {
                    if (snake.x[k] == fruit.x && snake.y[k] == fruit.y)     //判断是否在蛇身上
                    {
                        tag = 0;
                        break;
                    }
                }
    
                if (tag == 1 && fruit.x %2 ==0)break;
            }
        }
        gotoxy(fruit.x,fruit.y);
        printf("*");
    
        if(snake.x[0] == Bigfruit.x && snake.y[0] == Bigfruit.y)        //当蛇吃大果子时
        {
            snake.len+=2;
            Bigfruit.number++;
            snake.speed -= 3;
            ClearGames();           //防止果子被吃掉后仍残留在屏幕上
            Bigfruit.x = 0;
            Bigfruit.y = 0;
        }
    }
    /************************************************************************************/
    // 生成奖励果子
    void CreatBigFruit()
    {
        int ret = 1;
        srand((unsigned)time(NULL));
            while(1)
            {
                Bigfruit.x = rand() % (mapwide- 8) + 2;
                Bigfruit.y = rand() % (maphigh- 4) + 2;
    
                for (int k = 0; k < snake.len; k++)         //防止fruit生成在蛇身上
                {
                    if (snake.x[k] == Bigfruit.x && snake.y[k] == Bigfruit.y)     //判断是否在蛇身上
                    {
                        ret = 0;
                        break;
                    }
                }
    
                if (ret == 1 && Bigfruit.x %2 ==0)break;
            }
        gotoxy(Bigfruit.x,Bigfruit.y);
        printf("★");
    }
    /************************************************************************************/
    // 控制模块
    void control()
    {
        int i,temp;
        if (_kbhit())           //kbhit函数检查当前是否有键盘输入,若有则返回一个非0值,否则返回0
        {
            fflush(stdin);      //清空缓冲区
            temp = _getch();
            if((temp == 'a' || temp == 'A') && (key !='D' && key !='d'))        //防止反方向导致自杀
            {
                key = temp;
            }
            if((temp == 'd' || temp == 'D') && (key !='a' && key !='A'))
            {
                key = temp;
            }
            if((temp == 'w' || temp == 'W') && (key !='S' && key !='s'))
            {
                key = temp;
            }
            if((temp == 's' || temp == 'S') && (key !='w' && key !='W'))
            {
                key = temp;
            }
            if((temp == ' '))
            {
                getch();
            }
        }
    
        gotoxy(snake.x[snake.len - 1], snake.y[snake.len - 1]);     //删去最后一节
        printf("  ");
    
        for ( 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]--;
                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("█");
        gotoxy(mapwide + 2,0);          //移走光标
    }
    /************************************************************************************/
    // 死亡判定
    int Deathjudge()
    {
        int ret;
        if ((snake.x[0] == 0 || snake.x[0] == mapwide) || (snake.y[0] == 0 || snake.y[0] == maphigh))
            return 0;
            
        for (int i = 1; i < snake.len; i++)
        {
            if(snake.x[0] == snake.x[i] && snake.y[0] == snake.y[i])
                return 0;
        }
        return 1;
    }
    
    // 分数系统
    void Score()
    {
        Scores = fruit.number *fruitBonus + Bigfruit.number*BigfruitBonus;
        gotoxy(mapwide + 6, 18);
    	printf("Scores : %d",Scores);
    }
    /************************************************************************************/
    // 版本信息
    void VertionInformation()
    {
        ClearMenu();
    
        gotoxy(28,6);
        printf("\tGreedy Snake");
        gotoxy(28,9);
        printf("作者:北");
        gotoxy(28,12);
        printf("更新时间:2020.11.29");
        gotoxy(28,15);
        printf("版本:V1.4");
        gotoxy(28,18);
        printf("版本说明: 1.更新初始菜单界面");
        gotoxy(28,20);
        printf("\t      2.修复奖励果子一直存在的BUG");
    
        getch();
    }
    

    总结

           贪吃蛇这个小程序对于初学者而言,是个很好的练手目标,编写它花费了大约四天时间,其中调试占用了绝大多数的时间。期间也会遇到很多令人崩溃的难点,但是现在的互联网完全有能力让你自主解决这些问题,当你不断解决一个个出现的问题后,你就能显著的发现你的能力提升了不少,今后希望可以继续上手不同的项目,不断提升自己的能力

    展开全文
  • C语言贪吃蛇小游戏

    千次阅读 2018-08-27 21:54:48
    C语言编写贪吃蛇 整个代码都是C语言,其中调用少部分库函数,不如实现屏幕坐标打印的函数,贪吃蛇游戏代码的核心在于蛇身体坐标的更新,实现细节请看代码注释, 代码 //#include "stdafx.h" 如果是...

    C语言编写贪吃蛇

    整个代码都是C语言,其中调用少部分库函数,不如实现屏幕坐标打印的函数,贪吃蛇游戏代码的核心在于蛇身体坐标的更新,实现细节请看代码注释,

    代码

    
    
    //#include "stdafx.h"   如果是vc环境的话加上该头文件 
    #include<stdlib.h>
    #include <stdio.h>
    #include <windows.h>
    #include <conio.h>
    #include <time.h>
    #define  TURNUP    1     //宏定义蛇运动的四个方向 
    #define  TURNDOWN  2
    #define  TURNRIGHT 3
    #define  TURNLEFT  4
    #define  MAXROW    20
    #define  MAXCOL    30
    
    void printSnake(int bodylen,COORD bodypos[]);
    void run (int bodylen,COORD *body,int dirction,int times);
    void initSnake (int bodylen,COORD* body,COORD head);
    void disappeartSnake(int bodylen,COORD *bodypos);
    void createFood();
    void printwall();
    void printscore(int len);
    void supervisekeybot(COORD *body,int direction,int times);
    void createFood1();
    
    int len=5;
    COORD gfoodPos;            //定义三个全局变量,身体长度和两种食物 坐标
    COORD gfoodPos1;           // COORD为系统定义结构体,可实现屏幕坐标表示 
    
    int main(int argc, char* argv[])
    {
        int direction=TURNRIGHT;//没有按键输入时默认的初始方向
    
        COORD body[20]={0};
        COORD head={1,1};          
    
        printwall();
        initSnake (len,body,head);//根据head初始化蛇的身体
        printSnake(len,body);     //打印初始的蛇
        createFood();
        createFood1();
    
        supervisekeybot(body,direction,10);
    
        return 0;
    }
    
    
    /*******************************************
    函数名称:printSnake
    函数功能:打印蛇的身体
    函数参数:bodylen --身体的长度
              bodypos --蛇身体的坐标 
    函数返回:
    函数作者:forxn@qq.com 
    ********************************************/
    void printSnake(int bodylen,COORD *bodypos)
    {
            //调用库函数,获取蛇身体的坐标,并在该坐标点打印信息,蛇头为8,蛇身为* 
            HANDLE hOut;
            COORD pos=bodypos[bodylen-1];
            hOut=GetStdHandle(STD_OUTPUT_HANDLE);
            SetConsoleCursorPosition(hOut,pos);
            printf("8\n");
        for(int i=0;i<bodylen-1;i++)
        {
            HANDLE hOut;
            //获取蛇身体的坐标
            COORD pos=bodypos[i];
            hOut=GetStdHandle(STD_OUTPUT_HANDLE);
            SetConsoleCursorPosition(hOut,pos);
            //打印该点
            printf("*\n");
    
        }
    } 
    
    /*******************************************
    函数名称:changeDirction
    函数功能:实现蛇的转弯,或者说蛇身体的更新
    该函数为整个贪吃蛇的核心点,核心思想为以蛇头坐标为起点,
    此程序将蛇头坐标定为body[len-1]; 
    后面点的坐标都取其前一个点的的位置 
    ********************************************/
    void  changeDirction(int bodylen,COORD *body,int dirction)
    {
        int     p=bodylen;
        for(int i=0;bodylen>1;bodylen--)
        {
            body[i]=body[i+1];
            i++;
        }
        switch (dirction)
        {
        case TURNUP :
            {
                body[p-1].Y--;
                break;
            }
        case TURNDOWN :
            {
                body[p-1].Y++;
                break;
            }
        case TURNRIGHT:
            {
                body[p-1].X++;
                break;
            }
        case TURNLEFT :
            {
                body[p-1].X--;
                break;
            }
        default:
            {
                break;
            }
        }
        //吃到食物的时候
        if(body[p-1].X==gfoodPos.X
            &&body[p-1].Y==gfoodPos.Y)
        {
    
    
            body[p].X=body[p-1].X;
            body[p].Y=body[p-1].Y;
            len++;
            createFood();
            printscore(bodylen);
    
        }
    else    if(body[p-1].X==gfoodPos1.X   //此处必须加else;不然有bug
            &&body[p-1].Y==gfoodPos1.Y)
        {
            body[p].X=body[p-1].X;
            body[p].Y=body[p-1].Y;
            body[p+1].X=body[p].X;
            body[p+1].Y=body[p].Y;
            len=len+2;
            createFood1();
            printscore(bodylen);
        }
    
        //边界检测
        if(body[p-1].X==0||body[p-1].Y==0||body[p-1].X==MAXCOL||body[p-1].Y==MAXROW)
        {
            COORD a;
            a.X=5;
            a.Y=10;
            HANDLE hOut;
            hOut=GetStdHandle(STD_OUTPUT_HANDLE);
            SetConsoleCursorPosition(hOut,a);  
            printf("GAME  OVER!");
            printSnake(len,body);  
            exit(0);
    
        }
    
    
        for (int j=0;j<p;j++)
        {
            if (body[p-1].X==body[p-j-2].X&&body[p-1].Y==body[p-j-2].Y)
            {
                COORD b;
                b.X=5;
                b.Y=10;
                HANDLE hOut;
                hOut=GetStdHandle(STD_OUTPUT_HANDLE);
                SetConsoleCursorPosition(hOut,b);  
                printf("GAME  OVER!");
                printSnake(len,body);  
                exit(0);
            }
    
        }
    
    
    
    }
    
    /*******************************************
    函数功能:
    函数参数:
    ********************************************/
    void run (int bodylen,COORD *body,int dirction,int times)
    {
        for(int i=0;i<times;i++)
        {
            //重新设置蛇身体的点坐标
            changeDirction(bodylen,body,dirction);
    
            printSnake(bodylen,body);
            Sleep(200);
            disappeartSnake(bodylen,body);
        }          
    }
    /*******************************************
    函数功能:
    函数参数:
    ********************************************/
    
    void initSnake (int bodylen,COORD* body,COORD head)
    {
        for (int i=0;i<bodylen;i++)
        {
            body[bodylen-i-1].X=head.X;
            body[bodylen-1-i].Y=head.Y;
    
        }
    }
    
    /*******************************************
    函数功能:产生食物,调用rand函数随机位置产生两种食物 
    函数参数:
    ********************************************/
    void createFood()
    {
        srand(time(0));
        int x=rand()%(MAXCOL-1);
        int y=rand()%(MAXROW-1);
    
        gfoodPos.X=x;
        gfoodPos.Y=y;
        if(gfoodPos.X==0||gfoodPos.Y==0)
        {
            createFood();
        }
    
            HANDLE hOut;
            hOut=GetStdHandle(STD_OUTPUT_HANDLE);
            SetConsoleCursorPosition(hOut,gfoodPos);
            printf("A\n");
    
    }
    void createFood1()
    {
        //srand(time(0));
        int x=rand()%(MAXCOL-1);
        int y=rand()%(MAXROW-1);
    
        gfoodPos1.X=x;
        gfoodPos1.Y=y;
        if(gfoodPos1.X==0||gfoodPos1.Y==0)
        {
            createFood1();
        }
    
            HANDLE hOut;
            hOut=GetStdHandle(STD_OUTPUT_HANDLE);
            SetConsoleCursorPosition(hOut,gfoodPos1);
            printf("B\n");
    
    }
    /*******************************************
    函数功能:蛇身体的更新,调用system("cls")不能满足要求
              将坐标点依次打印空格可实现“清屏”效果 
    函数参数:
    ********************************************/
    
    void disappeartSnake(int bodylen,COORD *bodypos)
    {
        for(int i=0;i<bodylen;i++)
        {
            HANDLE hOut;
            COORD pos=bodypos[i];
            hOut=GetStdHandle(STD_OUTPUT_HANDLE);
            SetConsoleCursorPosition(hOut,pos);
            printf(" \n");
    
        }
    } 
    
    /*******************************************
    函数功能:打印墙的边界
    函数参数:
    ********************************************/
    void printwall()
    {
        for(int i=0;i<=MAXROW;i++)
        {
            for(int j=0;j<=MAXCOL;j++)
            {
                if(i==0||j==0||i==MAXROW||j==MAXCOL)          
                    putchar('#');
                else
                    printf(" ");
            }
            putchar('\n');
        }
    }
    
    /*******************************************
    函数功能:检测键盘的按键,实现蛇的实时控制 
    函数参数:
    ********************************************/
    void supervisekeybot(COORD *body,int direction,int times)
    {
        while(1)        // 蛇开始移动并监测键盘
        {   
            run (len,body,direction,1);
            printscore(len);
            if(_kbhit())//监测键盘是否有输入,也可采用多线程实现,此处调用_kbhit()
            {
                char ch=getch();
                switch (ch)
                {
                case 'w':
                    {
                        run (len,body,TURNUP,1);//此时times设置为1,才能实现实时控制响应;
                        direction=TURNUP;       //键盘键入时蛇的方向更新并维持
                        break;
                    }
                case 's':
                    {
                        run (len,body,TURNDOWN,1);
                        direction=TURNDOWN;
                        break;
                    }
                case 'a':
                    {
                        run (len,body,TURNLEFT,1);
                        direction=TURNLEFT;
                        break;
                    }
                case 'd':
                    {
                        run (len,body,TURNRIGHT,1);
                        direction=TURNRIGHT;
                        break;
                    }
                }
            }
    
    
    
        }
    
    }
    /*******************************************
    函数功能:将蛇的身体长度打印,作为分数 
    函数参数:
    ********************************************/
    void printscore(int len)
    {
        COORD score;
        score.X=32;
        score.Y=12;
        HANDLE hOut;
        hOut=GetStdHandle(STD_OUTPUT_HANDLE);
        SetConsoleCursorPosition(hOut,score);
        printf("SCORE:%d",len);     
    }
    
    
    展开全文
  • 经典的贪吃蛇代码代码容易看懂,操作方便。C语言编写,是做课设和练习编写游戏的首选。希望大家评分。
  • C语言在ubantu中编写贪吃蛇小游戏(linux系统) 1.展示 2.想明白做出来贪吃蛇要做什么?(3个大纲) ①游戏初始化 ②启动游戏 ③结束游戏 3.创建这些文件,并写入代码,Linux创建文件的命令 touch main.c,e而后...
  • -----------------------------------... 使用纯C语言编写的控制台贪吃蛇小游戏,可设置游戏难度,有连击分数加成,蛇身颜色自动随机变化,缓冲防闪,数据存储保护,排行榜与音效等功能,VC++与VS编译均通过,只使用V...
  • 初学C语言,自己编写了一个贪吃蛇小代码,会的不多,代码很简单,希望初学的C语言的通知能有所借鉴,也希望大佬多批评指正.谢谢!
  • C语言贪吃蛇代码

    2012-10-07 00:39:50
    这是我自己编写贪吃蛇小游戏,利用的是C语言,里面包含源代码。很适合初学者进行学习和参考,可以用来借鉴,希望给大家带来帮助
  • 贪吃蛇源码,大家可以下载学习,代码使用C语言编写,在codeblocks运行通过,包含工程文件,大家可以直接使用codeblocks打开,也可以将里面的文件加载至自己的IDE下。
  • 此次贪吃蛇小游戏的目的是使得我在Linux底下使用vi进行编写的 心得: 1.自己对linux中如何使用vi更加熟悉 如::wq yy pp dd u 等等 2.对c语言的指针,结构体,链表等更加的牢固 3.借此小项目也运用到多线程作为进入...
  • C语言编写的调用ACLLib函数库单人版贪吃蛇小游戏,运用MVC设计模式(三部分Model,View, Control),代码可重用,修改为双人版甚至多人版,附有有设计思路文档,代码注释。
  • vc++贪吃蛇小游戏

    2018-04-22 17:45:27
    自行敲写的代码游戏,可以利用c语言编写游戏,初学者装逼必备神器
  • 贪吃蛇小游戏

    2018-01-08 15:27:45
    贪吃蛇小游戏 共享使用 C++编写 虽然是用C++写的,但是没有用到类,大部分都 是C语言的东西。用GDI函数,写的。一共三个文件,一个头文件:Teris.h声明了一些数据类型和函数,定义了一些常量。一个Function.cpp定义...
  • 小白99行C代码编写经典游戏贪吃蛇(多关版本)

    千次阅读 多人点赞 2020-06-16 21:22:55
    文章目录前言一、实现原理1、地图打印2、蛇身运动3、方向键操控4、各种判定5、函数工具二、游戏试玩1、编译环境2、源代码三、代码详解1、游戏配置部分(第...所以要编写贪吃蛇,首先要解决的就是如何用输出动态图像的问
  • 序言 很多学习了C语言伙伴,虽然说学完了...这次的编写控制台贪吃蛇程序对学完C语言没做过项目的伙伴来说可能是一个不的挑战。 本文的贪吃蛇案例用的东西也并不是很多,游戏的实现主要是对一个二维数组...
  • 贪吃蛇C代码

    2015-03-26 14:06:04
    C语言编写贪吃蛇小游戏,新手编程,代码较多,请勿见怪。亲自使用过的,大家有什么问题请留言把。
  • Linux基本操作:包括但不限于 如何编写代码,如何编译代码,如何运行程序,如何创建文件夹 二、为什么需要ncurse 通俗易懂的来讲就是,C语言基础自带的库不存在单按方向键就能直接控制蛇的移动,必须按下方向键和...
  • 贪吃蛇代码

    2015-02-02 21:55:12
    使用C语言,利用VC绘图,需要用到graphics.h编写小游戏
  • 学习完这本书后,我又通过假期继续深造学习了C++,总想利用所学做一款经典游戏,今天我花了一下午的时间,整理出来了这篇文章,希望对你编写这个程序也会有所帮助。(本博文里面的代码均没涉及easyx图形库) /* 这一次...
  • 这次的编写控制台贪吃蛇程序对我来说是一个不的挑战。 文本版的贪吃蛇用的东西也并不是很多,游戏的实现主要是对一个二维数组按一定逻辑进行修改、变换(实际操作时,为了减少闪烁,我用的是字符串)。这里不对...
  • C语言课程设计

    2012-07-15 16:41:55
    C语言编写贪吃蛇小游戏,这里有完整的代码、截屏和分段程序功能说明。
  • 初学者的贪吃蛇游戏

    2016-01-27 22:05:33
    C语言贪吃蛇游戏制作初学编程,利用现有的知识编写了一个贪吃蛇小游戏。 目前游戏的制作程度仅限于“能玩”。 还有一定BUG有待改善。 以下是代码:#include #include #include #include #include<windows.h>#...
  • 包含贪吃蛇代码,还有相应图形库文件,更加完善此小游戏代码有详细注解,用C语言编写,可供一些大学生课程实践作为参考
  • vc代码合集

    2012-06-11 11:34:52
    2012-06-11 10:25 2,338 五子棋小游戏(linux C语言).c 2012-06-11 09:50 3,399 五子棋源码.rar 2012-06-11 11:14 1,440,656 人民币屏保.zip 2012-06-11 09:50 3,412,722 内部文件非内部程序员禁止访问谢谢...
  • 部分vc源代码合集1.rar

    2012-06-11 11:20:01
    2012-06-11 10:25 2,338 五子棋小游戏(linux C语言).c 2012-06-11 09:50 3,399 五子棋源码.rar 2012-06-11 09:50 3,412,722 内部文件非内部程序员禁止访问谢谢1234567890123456789能够实现文件的多选,统一上传,...
  • 2021-06-02

    2021-06-02 11:50:59
    学习C/C++语言如何做出带有图形界面的小游戏。(附带源代码和学习EasyX 图形库文件) 在此小编给大家指点方向,提供点学习方式及思路。 一. 对于学习C语言的初学者来说,做图形界面程序编写无从下手。 学习C语言时,...

空空如也

空空如也

1 2
收藏数 32
精华内容 12
关键字:

c语言编写贪吃蛇小游戏代码

c语言 订阅