首页 > 编程语言 >用Dev C++实现NOKIA经典游戏贪吃蛇

用Dev C++实现NOKIA经典游戏贪吃蛇

时间:2024-03-25 22:30:27浏览次数:15  
标签:hout struct food NOKIA framey C++ length 贪吃蛇 snake

前期准备

头文件:

#include<bits/stdc++.h>
#include<stdio.h>
#include<conio.h>
#include<windows.h>

控制界面配置:

void color(int x)
{
	SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), x);
}//设置不同颜色
void Hide ()
{
	HANDLE hOut;
	CONSOLE_CURSOR_INFO curInfo;
	hOut=GetStdHandle (STD_OUTPUT_HANDLE);
	curInfo.bVisible=0;
	curInfo.dwSize=1;
	SetConsoleCursorInfo(hOut,&curInfo);
}//隐藏光标
void gotoxy(HANDLE hout,int x,int y)
{
    COORD pos;
    pos.X=x;
    pos.Y=y;
    SetConsoleCursorPosition(hout,pos);
}//光标直接移动至x,y

定义框架常量: 

#define framex 30
#define framey 5
#define wide 12
#define high 16

定义蛇与食物 :

struct  Snake
{
    int x[100];
    int y[100];
    int speed;
    int length;
    int count;
};
struct Food
{
    int x;
    int y;
};

我们为蛇开了100*100个空间,用于存储100节身体的x,y坐标。同时,我们定义了速度speed,长度length(方便我们计算蛇身)、分数。对于食物,设定了x,y,代表坐标。  

以上的内容,直接照搬进程序中就行。 

程序框架

void makeframe(){}
//打印边框
void infor(HANDLE hout,struct Snake* snake){}
//打印分数
void initsnake(struct Snake *snake){}
//初始化蛇
void printsnake(HANDLE hout ,struct Snake *snake){}
//打印蛇
void movesnake(HANDLE hout,struct Snake *snake){}
//蛇身的移动
void printfood (HANDLE hout,struct Snake *snake,struct Food* food){}
//打印食物
void eatfood(HANDLE hout,struct Snake * snake,struct Food *food){}
//蛇与食物的交互
int ifdead(struct Snake* snake){}
//判定蛇死亡
void Gaming (struct Snake* snake,struct Food *food){}
//操控蛇,上下左右等
void Gameover (){}
//打印游戏结束
int main(){}
//主程序

下面,我们详细对每个模块的实现进行阐述。 

打印边框

void makeframe()
{
    HANDLE hout=GetStdHandle(STD_OUTPUT_HANDLE);
    gotoxy(hout,framex+wide*2+5,framey);
    for(i=0;i<high;i++)
	{
        gotoxy(hout,framex,framey+i);
        printf("#");
    }
//打印左边框
    for(i=0;i<high;i++)
	{
        gotoxy(hout,framex+wide*2+2,framey+i);
        printf("#");
    }
//打印右边框
    for(i=0;i<wide*2+3;i++)
	{
        gotoxy(hout,framex+i,framey-1);
        printf("#");
    }
//打印上边框
    for(i=0;i<wide*2+3;i++)
	{
        gotoxy(hout,framex+i,framey+high);
        printf("#");
    }
//打印下边框
}

运行以上程序,我们会得到一个从坐标点(framex,framey-1)开始打印的宽为wide*2+2,高为high+2的边框。(如果觉得这数字丑,也可以重新调整一下)

打印分数

void infor(HANDLE hout,struct Snake* snake)
{
    gotoxy(hout,framex+wide+1,framey);
    printf("%d",snake->count);
}

运行这个模块,将会在上框架中心输出分数。 

初始化蛇

void initsnake(struct Snake *snake)
{
    snake->x[0]=framex+16;
    snake->y[0]=framey+6;
    snake->count=0;
    snake->length=3;
    snake->speed=200;
    for(i=1;i<snake->length;i++)
	{
        snake->x[i]=snake->x[i-1]+2;
        snake->y[i]=snake->y[i-1];
    }
}

让蛇出现在框架大概右侧的位置,头朝向为向左,长度为3,还原了NOKIA中的贪吃蛇初始状态。 

打印蛇

void printsnake(HANDLE hout ,struct Snake *snake)
{
  	color(6);
    for(i=0;i<snake->length;i++)
	{
		char z=111;
        gotoxy(hout,snake->x[i],snake->y[i]);
        if(i==snake->length-1) 
            printf ("%c",z);
        else if(i==0)
            printf("*");
        else 
            printf("*"); 
    }
	color(7);
}

打印一条黄色的*蛇(蛇头为o),这是因为用c++还原蛇的动画还要做另外的处理,这里懒得贴图了。

蛇身的移动

这是极其关键的一部分。关系到蛇是否能够越变越长。

void movesnake(HANDLE hout,struct Snake *snake)
{
    gotoxy(hout,snake->x[0],snake->y[0]);
    printf("  ");
    for(i=1;i<snake->length;i++)
	{
        snake->x[i-1]=snake->x[i];
        snake->y[i-1]=snake->y[i];
    }
}

打印食物

void printfood (HANDLE hout,struct Snake *snake,struct Food* food)
{
    srand((unsigned)time(NULL));
    while(1)
	{
        food->x=rand()%(wide-2)+1;
        food->y=rand()%(high-2)+1;
        if(food->x==0&&food->y==0)
            continue;
        food->x=2*food->x+framex;
        food->y+=framey;
        for(i=0;i<snake->length;i++)
		{
            if(food->x==snake->x[i]&&food->y==snake->y[i])
            break;
        }
        if(i==snake->length)
		{
			k+=1;
            gotoxy(hout,food->x,food->y);
            if (k==3)
            {
            	k=0;
				c[0]=food->x;
				c[1]=food->y;
  				color(4);
            	printf ("@");
  				color(7);
  				z=2;
			}
			else
			{
				d[0]=food->x;
				d[1]=food->y;
           		printf("Φ");
            	break;
			}
        }
    }
}

创设随机数,使得食物(Φ)随机出现在边框内部,同时规定每3个食物输出一个大食物(@)。 

蛇与食物的交互

void eatfood(HANDLE hout,struct Snake * snake,struct Food *food)
{
    if (snake->x[snake->length-1]==d[0]&&snake->y[snake->length-1]==d[1])
	{
        snake->length++;
        for(i=snake->length-1;i>0;i--)
		{
            snake->x[i]=snake->x[i-1];
            snake->y[i]=snake->y[i-1];
        }
        snake->x[0]=a[0];
        snake->y[0]=a[1];
        printfood(hout,snake,food);
        snake->count++;
    }
    if (snake->x[snake->length-1]==c[0]&&snake->y[snake->length-1]==c[1])
	{
		c[0]=0;
		c[1]=0;
        snake->length++;
        for(i=snake->length-1;i>0;i--)
		{
            snake->x[i]=snake->x[i-1];
            snake->y[i]=snake->y[i-1];
        }
        snake->x[0]=a[0];
        snake->y[0]=a[1];
        snake->count+=tim*3;
        z=0;
    }
}

判定蛇的死亡

int ifdead(struct Snake* snake)
{
    for(i=0; i<snake->length-1; i++) 
        if( snake->x[snake->length-1]==snake->x[i] && snake->y[snake->length-1]==snake->y[i] ) 
            return 0;
    return 1;
}

游戏交互核心

void Gaming (struct Snake* snake,struct Food *food)
{
    HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
    unsigned char ch ='d';
    int q2=0;
    clock_t start ;
	while(1)
	{
        infor(hout,snake);
        a[0]=snake->x[0];
        a[1]=snake->y[0];
        j=0;
        if(kbhit())
            ch=getch();
        switch(ch)
		{
            case 'w':
			{
				if (q!=3)
				{
                	movesnake(hout,snake);
                	snake->y[snake->length-1]-=1;
                	if (snake->y[snake->length-1]==framey-1)
                		snake->y[snake->length-1]=framey+high-1;
                	q=1;
               		break;
				}
				else 
				{
					movesnake(hout,snake);
					snake->y[snake->length-1]+=1;
					if (snake->y[snake->length-1]==framey+high)
                		snake->y[snake->length-1]=framey;
               		break;
				}
            }
            case 's':
			{
				if (q!=1)
				{
                	movesnake(hout,snake);
                	snake->y[snake->length-1]+=1;
					if (snake->y[snake->length-1]==framey+high)
                		snake->y[snake->length-1]=framey;
                	q=3;
               		break;
				}
				else 
				{
					movesnake(hout,snake);
					snake->y[snake->length-1]-=1;
                	if (snake->y[snake->length-1]==framey-1)
                		snake->y[snake->length-1]=framey+high-1;
               		break;
				}
            }
            case 'a':
			{
				if (q!=0)
				{
                	movesnake(hout,snake);
                	snake->x[snake->length-1]-=2;
                	if (snake->x[snake->length-1]==framex)
                		snake->x[snake->length-1]=framex+wide*2;
                	q=2;
               		break;
				}
				else 
				{
					movesnake(hout,snake);
					snake->x[snake->length-1]+=2;
                	if (snake->x[snake->length-1]==framex+wide*2+2)
                		snake->x[snake->length-1]=framex+2;
               		break;
				}
            }
            case 'd':
            {
            	if (q!=2)
				{
                	movesnake(hout,snake);
                	snake->x[snake->length-1]+=2;
                	if (snake->x[snake->length-1]==framex+wide*2+2)
                		snake->x[snake->length-1]=framex+2;
                	q=0;
               		break;
				}
				else 
				{
					movesnake(hout,snake);
					snake->x[snake->length-1]-=2;
                	if (snake->x[snake->length-1]==framex)
                		snake->x[snake->length-1]=framex+wide*2;
               		break;
				}
            }
            default:
            	q=5;
            	q2=0;
            
        }
        if(ifdead(snake)==0||ch==27)
            break;
        if (q!=5 && q2==1)
		{
			gotoxy(hout,framex+9,framey+4);
			printf("          ");
			gotoxy(hout,framex+10,framey+5);
    		printf("        ");
   			gotoxy(hout,framex+9,framey+6);
   			printf("          ");
   			q2=0;
		}
        eatfood(hout,snake,food);
        printsnake(hout,snake);
        if (q==5 && q2==0)
        {
        	start=clock(); 
        	q2=1;
            gotoxy(hout,framex+9,framey+4);
			printf("——————————");
			gotoxy(hout,framex+10,framey+5);
    		printf("游戏暂停");
   			gotoxy(hout,framex+9,framey+6);
   			printf("——————————");
		}
		if (z==2 && q!=5 && q2!=1)
		{
			z=1;
			start = clock(); 
			timeprint (hout,start);
		}
		else if (z==1 && q!=5 && q2!=1)
		{
			timeprint (hout,start);
		}
		else if (z==0 && q!=5 && q2!=1)
		{
			gotoxy (hout,c[0],c[1]);
			printf (" ");
			c[0]=0;
			c[1]=0;
		}
		infor(hout,snake);
        Sleep(snake->speed);
    }
}

打印游戏结束

void Gameover ()
{
    HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
	gotoxy(hout,framex+9,framey+4);
	printf("——————————");
	gotoxy(hout,framex+10,framey+5);
    printf("游戏结束");
    gotoxy(hout,framex+9,framey+6);
    printf("——————————");
    Sleep(1000);
    gotoxy(hout,0,framey+20);
}

主程序

int main()
{
	
    HANDLE hout = GetStdHandle(STD_OUTPUT_HANDLE);
    struct Snake s, *snake=&s;
    struct Food  f, *food=&f;
	Hide ();
    makeframe();
    int b=CoverChoose ();
    if (b==framey+1)
    {
    	makeframe();
    	initsnake(snake);
   	 	printfood(hout,snake,food);
    	Sleep(500);
   	 	Gaming (snake,food);
    	Gameover ();
	}
    return 0;
}

标签:hout,struct,food,NOKIA,framey,C++,length,贪吃蛇,snake
From: https://blog.csdn.net/Crowd_Of_Silver/article/details/137027198

相关文章

  • 学会在 C++ 中使用变量:从定义到实践
    C++变量变量是用于存储数据值的容器。在C++中,有不同类型的变量(使用不同的关键字定义),例如:int-存储整数(没有小数点),例如123或-123double-存储浮点数,带有小数点,例如19.99或-19.99char-存储单个字符,例如'a'或'B'。字符值用单引号括起来string-存储文本,例如......
  • C++调用C# (使用C++/CLI)
    简介C++/CLI简介见上文 C#调用C++(使用C++/CLI)-咸鱼翻身?-博客园(cnblogs.com)新建解决方案->CPlusCSharpSolution新建C#类库->CSharpNative新建类NativeCalculate1publicclassNativeCalculate2{3publicintAdd(inta,intb)4{......
  • C#调用C++ (使用C++/CLI)
    简介C++/CLI(C++CommonLanguageInfrastructure)是一种允许在.NET平台上创建托管代码(managedcode)和非托管代码(unmanagedcode)之间互操作的语言。其原理可以概括如下:编译器支持:C++/CLI编译器能够编译同时包含托管和非托管代码的源文件。这使得在同一个项目中可以混合使用......
  • 蓝桥杯n皇后问题C++
    用到了dfs算法#include<iostream>usingnamespacestd;intn;inta[10][10]={0};intsum=0;voidprin(inta[][10]){for(inti=0;i<n;i++){for(intj=0;j<n;j++){cout<<a[i][j]<......
  • C++动态内存管理
    目录C/C++内存分配C++内存管理C++内存管理介绍C++内存管理使用C++内存管理基本语法operatornew和operatordelete函数定位new表达式(placement-new)基本语法使用场景malloc/free和new/delete相同点不同点C/C++内存分配在C语言动态内存管理章节已经了解到内......
  • C++中用户自定义数据类型
    在C++中,用户自定义数据类型通常指的是通过struct、class、enum和typedef关键字定义的类型。这些自定义类型可以包含各种成员,包括基本数据类型、其他自定义类型、成员函数(对于class)、访问修饰符等。下面是这些自定义数据类型可以包含的组件的概述:结构体(struct)结构体是一种......
  • C++学习
    学习主线算法基础:https://www.acwing.com/activity/content/11/理解算法原理,完成模板题,熟练使用模版课外练习:针对特定主题,可以进行拓展练习爱思创题库:https://aisichuang.net/main/questionBank/questionBankhttps://leetcode.cn/leetbook/https://ac.nowcoder.co......
  • C++第五十六篇——VC获取显示器状态(捕获熄屏/亮屏)
    参考链接:https://blog.csdn.net/rocklee/article/details/76636253此篇文章实现C++可以获取屏幕亮灭的消息,程序在后台运行,不会有控制台窗口显示。第一步:新建一个控制台程序 第二步:编写屏幕亮灭的代码ScreenTest.cpp#include<windows.h>#include<iostream>usingname......
  • 【C++从0到1-黑马程序员】文件操作
    C++从0到1-黑马程序员课程学习笔记课程链接:61C++文件操作-文本文件-写文件_哔哩哔哩_bilibili程序运行时产生的数据都属于临时数据,程序一旦运行结束都会被释放可以通过文件将数据持久化C++中对文件操作需要包含头文件 <fstream>文件类型分为两种:文本文件-文件以......
  • 【C++从0到1-黑马程序员】引用
     C++从0到1-黑马程序员课程学习笔记课程链接: 06C++中的引用-引用的基本语法_哔哩哔哩_bilibili1.引用的基本语法作用:给变量起别名语法:数据类型&别名=原名2.引用的注意事项1.引用必须有初始化    举个......