C语言版简易贪吃蛇(使用了图形库)

这篇博客介绍了一个使用C++和EasyX图形库编写的贪吃蛇游戏。游戏支持自定义窗口大小和速度,通过键盘箭头控制蛇移动。代码中详细展示了游戏初始化、蛇的移动、食物生成与吃食、游戏结束条件等关键功能的实现。
摘要由CSDN通过智能技术生成

1、使用了c++图形库,easyx,下载安装网址EasyX 文档 - 基本说明

2,贪吃蛇使用说明:修改X,Y是修改窗口大小,修改SPEED是修改速度(数值越大速度越小

键盘的箭头控制上下左右

3,源码:

#include<stdio.h>
//随机
#include<conio.h>
#include<time.h>
#include<conio.h>//按键
#include<graphics.h>//图形界面库
//播放音乐(头文件库文件)
//#include<mmsystem.h>
//#pragma comment(lib,"winmm.lib")
#define  NUM   1000 
#define  SIZE  10   //一节蛇的宽度
#define  X     640
#define  Y     480
#define  SPEED 100  //速度
enum Ch {up =72,down=80,left=75,right=77};
struct Coor  //坐标
{
	int x;
	int y;
};
struct Snack //蛇
{
	int length; //节数
	Ch ch;//蛇的方向
	Coor array[NUM]; //用来存蛇

};
struct Food
{
	//食物坐标
	int x;
	int y;
	bool iseat;//判断是否被吃
};
Snack snack;   //蛇实体
Food food;     //food结构体变量(食物)
void GameInit()
{
	srand((unsigned int)time(NULL));//使用随机
	//初始化蛇3节
	snack.length = 3;
	snack.ch = right;
	snack.array[0].x=100;
	snack.array[0].y=100;
	snack.array[1].x=90;
	snack.array[1].y=100;
	snack.array[2].x=80;
	snack.array[2].y=100;
	//初始化食物
	food.iseat = true;
}
void DrawGame()//游戏内容绘制
{
	cleardevice();
	//绘制食物
	setfillcolor(GREEN);
	fillroundrect(food.x, food.y, food.x + SIZE, food.y + SIZE, 5, 5);
	//绘制蛇 snake.n节
	setfillcolor(RED);//提供颜色
	fillrectangle(snack.array[0].x, snack.array[0].y, 
		snack.array[0].x + SIZE, snack.array[0].y + SIZE);//填充蛇头
	for (int i = 1; i < snack.length; i++)
	{
		if (i % 2 == 1)
		{
			setfillcolor(YELLOW);
			fillrectangle(snack.array[i].x, snack.array[i].y, snack.array[i].x + SIZE, snack.array[i].y + SIZE);
		}
		else 
		{
			rectangle(snack.array[i].x, snack.array[i].y, snack.array[i].x + SIZE, snack.array[i].y + SIZE);
		}	
	}
}
//蛇的移动
void SnackMove()
{
	for (int i = snack.length - 1; i > 0; i--)
	{
		snack.array[i].x = snack.array[i - 1].x;
		snack.array[i].y = snack.array[i - 1].y;
	}
	switch (snack.ch)
	{
	case up:
		snack.array[0].y -= SIZE;
		break;
	case down:
		snack.array[0].y += SIZE;
		break;
	case left:
		snack.array[0].x -= SIZE;
		break;
	case right:
		snack.array[0].x += SIZE;
		break;
	}
}
void ChangeCh()//"<-"和"->"控制左右 
{
	//按键 up down left right
	char key;
	key = _getch();
	switch (key)
	{
	case up:
		if (snack.ch != down)
			snack.ch = up;
		break;
	case down:
		if (snack.ch != up)
			snack.ch = down;
		break;
	case left:
		if (snack.ch != right )
			snack.ch = left;
		break;
	case right:
		if (snack.ch != left)
			snack.ch = right;
		break;
	}
}
void CreateFood()//增加食物
{
	if (food.iseat == true)
	{
		bool flag=false;    //食物和蛇是否重复
		if (food.iseat == true)
		{
			while (1)
			{
				flag = false;
				//食物位置
				food.x = rand() % (X/SIZE) * SIZE;
				food.y = rand() % (Y/SIZE) * SIZE;
				//食物不能在蛇的身体上
				for (int i = 0; i < snack.length; i++)
				{
					if (food.x == snack.array[i].x && food.y == snack.array[i].y)
					{
						flag = true;//重复
						break;
					}
				}
				if (!flag)
				{
					food.iseat = false;
					break;
				}
			}
		}
	}
}
void EatFood()//吃食物
{
	if (snack.array[0].x == food.x && snack.array[0].y == food.y)
	{
		food.iseat = true;
		snack.length++;
	}
}
int GameOver()//结束游戏
{
	//跟墙碰撞
	if (snack.array[0].x < 0 || snack.array[0].x >= X || snack.array[0].y < 0 || snack.array[0].y >= Y)
	{
		return 1;
	}

	//跟自己身体碰撞
	for (int i = 1; i < snack.length - 1; i++)
	{
		if (snack.array[0].x == snack.array[i].x && snack.array[0].y == snack.array[i].y)
		{
			return 1;
		}
	}
	return 0;

}
int main()
{
	//初始化一个窗口界面
	initgraph(X,Y);

	GameInit();//初始化游戏
	int n = 0;
	while (1)
	{
		while (!_kbhit())
		{
			SnackMove();
			DrawGame();
			CreateFood();
			EatFood();
			//结束
			n = GameOver();
			if (n)
				break;
			Sleep(SPEED);//蛇的速度
		}
		if (n)//结束
			break;
		ChangeCh();
	}
	return 0;
}

4,游戏窗口

 

  • 4
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
#define N 200<br>#include <graphics.h><br>#include <stdlib.h><br>#include <dos.h><br>#define LEFT 0x4b00<br>#define RIGHT 0x4d00<br>#define DOWN 0x5000<br>#define UP 0x4800<br>#define ESC 0x011b<br>int i,key;<br>int score=0;/*得分*/<br>int gamespeed=50000;/*游戏速度自己调整*/<br>struct Food<br>{<br> int x;/*食物的横坐标*/<br> int y;/*食物的纵坐标*/<br> int yes;/*判断是否要出现食物的变量*/<br>}food;/*食物的结构体*/<br>struct Snake<br>{<br> int x[N];<br> int y[N];<br> int node;/*的节数*/<br> int direction;/*移动方向*/<br> int life;/* 的生命,0活着,1死亡*/<br>}snake;<br>void Init(void);/*图形驱动*/<br>void Close(void);/*图形结束*/<br>void DrawK(void);/*开始画面*/<br>void GameOver(void);/*结束游戏*/<br>void GamePlay(void);/*玩游戏具体过程*/<br>void PrScore(void);/*输出成绩*/<br>/*主函数*/<br>void main(void)<br>{<br> Init();/*图形驱动*/<br> DrawK();/*开始画面*/<br> GamePlay();/*玩游戏具体过程*/<br> Close();/*图形结束*/<br>}<br>/*图形驱动*/<br>void Init(void)<br>{<br> int gd=DETECT,gm;<br> initgraph(&gd,&gm,"c:\\tc");<br> cleardevice();<br>}<br>/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/<br>void DrawK(void)<br>{<br>/*setbkcolor(LIGHTGREEN);*/<br> setcolor(11);<br> setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/<br> for(i=50;i<=600;i+=10)/*画围墙*/<br> {<br> rectangle(i,40,i+10,49); /*上边*/<br> rectangle(i,451,i+10,460);/*下边*/<br> }<br> for(i=40;i<=450;i+=10)<br> {<br> rectangle(50,i,59,i+10); /*左边*/<br> rectangle(601,i,610,i+10);/*右边*/<br> }<br>}<br>/*玩游戏具体过程*/<br>void GamePlay(void)<br>{<br> randomize();/*随机数发生器*/<br> food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/<br> snake.life=0;/*活着*/<br> snake.direction=1;/*方向往右*/<br> snake.x[0]=100;snake.y[0]=100;/*头*/<br> snake.x[1]=110;snake.y[1]=100;<br> snake.node=2;/*节数*/<br> PrScore();/*输出得分*/<br> while(1)/*可以重复玩游戏,压ESC键结束*/<br> {<br> while(!kbhit())/*在没有按键的情况下,自己移动身体*/<br> {<br> if(food.yes==1)/*需要出现新食物*/<br> {<br> food.x=rand()%400+60;<br> food.y=rand()%350+60;<br> while(food.x%10!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让吃到*/<br> food.x++;<br> while(food.y%10!=0)<br> food.y++;<br> food.yes=0;/*画面上有食物了*/<br> }<br> if(food.yes==0)/*画面上有食物了就要显示*/<br> {<br> setcolor(GREEN);<br> rectangle(food.x,food.y,food.x+10,food.y-10);<br> }<br> for(i=snake.node-1;i>0;i--)/*的每个环节往前移动,也就是贪吃蛇的关键算法*/<br> {<br> snake.x[i]=snake.x[i-1];<br> snake.y[i]=snake.y[i-1];<br> }<br> /*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动头*/<br> switch(snake.direction)<br> {<br> case 1:snake.x[0]+=10;break;<br> case 2: snake.x[0]-=10;break;<br> case 3: snake.y[0]-=10;break;<br> case 4: snake.y[0]+=10;break;<br> }<br> for(i=3;i<snake.node;i++)/*从的第四节开始判断是否撞到自己了,因为头为两节,第三节不可能拐过来*/<br> {<br> if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0])<br> {<br> GameOver();/*显示失败*/<br> snake.life=1;<br> break;<br> }<br> }<br> if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||<br> snake.y[0]>455)/*是否撞到墙壁*/<br> {<br> GameOver();/*本次游戏结束*/<br> snake.life=1; /*死*/<br> }<br> if(snake.life==1)/*以上两种判断以后,如果死就跳出内循环,重新开始*/<br> break;<br> if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以后*/<br> {<br> setcolor(0);/*把画面上的食物东西去掉*/<br> rectangle(food.x,food.y,food.x+10,food.y-10);<br> snake.x[snake.node]=-20;snake.y[snake.node]=-20;<br> /*新的一节先放在看不见的位置,下次循环就取前一节的位置*/<br> snake.node++;/*的身体长一节*/<br> food.yes=1;/*画面上需要出现新的食物*/<br> score+=10;<br> PrScore();/*输出新得分*/<br> }<br> setcolor(4);/*画出*/<br> for(i=0;i<snake.node;i++)<br> rectangle(snake.x[i],snake.y[i],snake.x[i]+10,<br> snake.y[i]-10);<br> delay(gamespeed);<br> setcolor(0);/*用黑色去除的的最后一节*/<br> rectangle(snake.x[snake.node-1],snake.y[snake.node-1],<br> snake.x[snake.node-1]+10,snake.y[snake.node-1]-10);<br> } /*endwhile(!kbhit)*/<br> if(snake.life==1)/*如果死就跳出循环*/<br> break;<br> key=bioskey(0);/*接收按键*/<br> if(key==ESC)/*按ESC键退出*/<br> break;<br> else<br> if(key==UP&&snake.direction!=4)<br>/*判断是否往相反的方向移动*/<br> snake.direction=3;<br> else<br> if(key==RIGHT&&snake.direction!=2)<br> snake.direction=1;<br> else<br> if(key==LEFT&&snake.direction!=1)<br> snake.direction=2;<br> else<br> if(key==DOWN&&snake.direction!=3)<br> snake.direction=4;<br> }/*endwhile(1)*/<br>}<br>/*游戏结束*/<br>void GameOver(void)<br>{<br> cleardevice(); <br> PrScore();<br> setcolor(RED);<br> settextstyle(0,0,4);<br> outtextxy(200,200,"GAME OVER");<br> getch();<br>}<br>/*输出成绩*/<br>void PrScore(void)<br>{ <br> char str[10];<br> setfillstyle(SOLID_FILL,YELLOW);<br> bar(50,15,220,35);<br> setcolor(6);<br> settextstyle(0,0,2);<br> sprintf(str,"score:%d",score);<br> outtextxy(55,20,str);<br>}<br>/*图形结束*/<br>void Close(void)<br>{ <br> getch();<br> closegraph();<br>}<br>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

致奋斗的自己

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值