C语言实战 - 贪吃蛇(图像界面)

news2025/1/20 10:48:16
  • 由于本人精力有限,暂时先把素材和代码放上,等以后有空再补教程。

目录

效果预览

准备工作

EasyX图形库

音频素材

代码编写

Transfer.h文件

game.cpp文件

main.c文件


效果预览

先来看一下最终成品效果

贪吃蛇图形界面

准备工作

EasyX图形库

这个贪吃蛇项目是基于EasyX图形库写的,所以需要安装一个easy图像库,官方下载地址如下:

EasyX Graphics Library for C++icon-default.png?t=N3I4https://easyx.cn/

音频素材

CSDN资源下载地址:贪吃蛇素材文件(图片+音频)-C文档类资源-CSDN文库

PS:如果遇到非会员下载不了的情况可以私信或者在评论区留言,作者再想办法。

代码编写

  • Transfer.h文件


//头文件
#pragma once
#include<stdio.h>
#include<graphics.h>
#include<easyx.h>
#include<windows.h>
#include<conio.h>
#include<stdlib.h>
#include<time.h>
#include<mmsystem.h>//包含多媒体设备接口头文件
#pragma comment(lib,"winmm.lib")//加载静态库

//类型定义
typedef struct snake_coor {//蛇的坐标
	int x;
	int y;
}COOR;
typedef enum dir {//蛇的方向
	up, down, left, right,stop
}DIR;
typedef  struct snake_information {//蛇的信息
	COOR coor[1000]={0};
	int length=0;
	int state=0;
	DIR direction;
}INF;
typedef struct food_coor {//食物坐标
	int x=0;
	int y=0;
}FOOD;

//函数声明
void button(int x, int y, int len, int wid, 
const char* text,int chg1,int chg2);				//按钮函数
int menu();											//菜单界面
void background();									//游戏背景
void snake_Initialization();						//初始化蛇
void snkae_key();									//按键控制
void snake_move();									//蛇的移动
void snake_draw();									//蛇的绘制
void food_draw();									//画出食物
void food_coor();									//食物坐标
void judge();										//判断函数
void game();										//游戏函数
  • game.cpp文件

#include"Transfer.h"
INF snake;				//蛇的定义
FOOD food;				//定义食物

void button(int x,int y,int len,int wid,const char* text,int chg1,int chg2)
{
	//图形部分
	setlinecolor(TRANSPARENT);
	setfillcolor(YELLOW);
	setlinecolor(BROWN);
	fillroundrect(x, y, x + len, y + wid,20,20);

	//文字部分
	char text_trans[50];			
	strcpy_s(text_trans, text);
	setbkmode(TRANSPARENT);
	settextstyle(30, 0, "华文行楷");
	settextcolor(BLACK);
	int x_end = x+chg1;
	int y_end = y+chg2;
	outtextxy(x_end,y_end, text_trans);
}
int menu()//菜单
{
	//播放背景音乐
	mciSendString("play ./menu_bgm.mp3 repeat", 0, 0, 0);			
	cleardevice();
	//右边区域
	HRGN words_area = CreateRectRgn(680, 0, 900, 580);
	setcliprgn(words_area);
	IMAGE pic_left;
	loadimage(&pic_left, "./background_other.jpg", 0, 0);
	putimage(680, 0, &pic_left);
	RECT words{ 700, 150, 850, 400 };
	DeleteObject(words_area);
	//左边区域
	HRGN menu_area = CreateRectRgn(0, 0, 680, 580);
	setcliprgn(menu_area);
	IMAGE background_menu;
	loadimage(&background_menu, "./background_menu.jpg", 0, 0);
	putimage(0, 0, &background_menu);	
	button(260, 80, 160, 50, "开始游戏",25,10);
	button(260, 200, 160, 50, "退出游戏", 25, 10);
	//鼠标选择
	MOUSEMSG click;
	while (1)
	{
		if (MouseHit())
		{
			click = GetMouseMsg();										//获取鼠标信息
			if (click.uMsg == WM_LBUTTONDOWN)							//按下左键时
			{
			//第一个按钮
			if (click.x >= 260 && click.x <= 420 && click.y >= 80 && click.y <= 130)		
				{
				mciSendString("stop ./menu_bgm.mp3",0, 0, 0);			//停止菜单背景音乐
				mciSendString("play click_sound.mp3", 0, 0, 0);			//点击音效
				mciSendString("play ./game_bgm.mp3 repeat", 0, 0, 0);	//播放游戏背景音乐
				return 1;
				}
			//第二个按钮
			if (click.x >= 260 && click.x <= 420 && click.y >= 200 && click.y <= 250)		
				{
				mciSendString("stop ./menu_bgm.mp3", 0, 0, 0);			//停止菜单背景音乐
				mciSendString("play click_sound.mp3", 0, 0, 0);			//点击音效				
				return 0;
				}
			}
		}
	}
	return 0;
}
void background()
{
	cleardevice();
	//右边图片
	HRGN words_area = CreateRectRgn(680, 0, 900, 580);
	setcliprgn(words_area);
	IMAGE pic_left;
	loadimage(&pic_left, "./background_right.jpg", 0, 0);
	putimage(680, 0, &pic_left);
	//右边文字
	settextstyle(18, 0, "宋体");
	settextcolor(BLACK);
	setbkmode(TRANSPARENT);
	outtextxy(690, 500, "退出:Esc    暂停:Space");
	//得分区域
	settextstyle(40, 0, "微软雅黑"); 
	settextcolor(BLUE);
	setbkmode(TRANSPARENT); 
	char grade[50]; 
	sprintf_s(grade ,"%d" ,snake.length - 3);
	outtextxy(790, 344, grade); 
	//释放空间
	DeleteObject(words_area); 
	//游戏区域
	HRGN game_area = CreateRectRgn(0, 0, 680, 580);
	setcliprgn(game_area);
	IMAGE background_menu;
	loadimage(&background_menu, "./background_left.jpg", 0, 0);
	putimage(0, 0, &background_menu);
}
void snake_Initialization()
{
	//初始化长度
	snake.length = 3;
	//初始化蛇头
	snake.coor[0].x = 320;
	snake.coor[0].y = 250;
	//初始化蛇身
	snake.coor[1].x = 310;
	snake.coor[1].y = 250;
	//初始化蛇尾
	snake.coor[2].x = 300;
	snake.coor[2].y = 250;
	//初始化食物坐标
	food.x = (rand() % 69) * 10;
	food.y = (rand() % 56) * 10;
	//初始化方向
	snake.direction = right;
}
void snake_draw()
{
	int i = 0, j = 0;
	for (i = 0; i < snake.length; i++)
	{
			//线条颜色
			setlinecolor(YELLOW);
			//蛇身颜色
			if (i!=0&&i!=snake.length-1)
			{
				setfillcolor(RGB(51,255,88));			
				fillrectangle(snake.coor[i].x, snake.coor[i].y, snake.coor[i].x + 10, snake.coor[i].y + 10);
			}
			//蛇头颜色
			if (i == 0)
			{
				setfillcolor(RGB(31,100,255));				
				fillrectangle(snake.coor[i].x, snake.coor[i].y, snake.coor[i].x + 10, snake.coor[i].y + 10);
			}
			//蛇尾颜色
			if (i == snake.length - 1)
			{
				setfillcolor(RGB(159,255,213)); 			
				fillrectangle(snake.coor[i].x, snake.coor[i].y, snake.coor[i].x + 10, snake.coor[i].y + 10);
			}				
	}
}
void snkae_key()
{
	char get;
	//获取键盘内容
	printf("2");
	if (_kbhit())
	{
		printf("3");
		get = _getch();
		printf("1");
		if ( (get == 'W' || get =='w') && snake.direction != down)
		{
			snake.direction = up;			//上 --- W
		}
		if ( (get == 'A' || get == 'a') && snake.direction != right)
		{
			snake.direction = left;			//左 --- A 
		}
		if ((get == 'S' || get == 's') && snake.direction != up)
		{
			snake.direction = down;			//下 --- S
		}
		if ((get == 'D' || get == 'd') && snake.direction != left)
		{
			snake.direction = right;		//右 --- D
		}
		if (get == ' ')						
		{
			system("pause");			    //暂停 - Space
		}
		if (get == 27)
		{
			exit(0);						//退出 - Esc
		}
		if (get == 72 && snake.direction != down)
		{
			snake.direction = up;			//上					
		}
		if (get == 80 && snake.direction != up)
		{
			snake.direction = down;			//下					
		}
		if (get == 75 && snake.direction != right)
		{
			snake.direction = left;			//左					
		}
		if (get == 77 && snake.direction != left)
		{
			snake.direction = right;		//右					
		}

	}
}
void snake_move()
{
	//蛇身坐标前移
	for (int i = snake.length - 2; i >= 0; i--)
	{
		snake.coor[i + 1].x = snake.coor[i].x;
		snake.coor[i + 1].y = snake.coor[i].y;
	}
	//蛇头坐标移动
	if (snake.direction==up)//上
	{
		snake.coor[0].y -= 10;		
	}
	if (snake.direction == down)//下
	{
		snake.coor[0].y += 10;
	}
	if (snake.direction == left)//左
	{
		snake.coor[0].x -= 10;
	}
	if (snake.direction == right)//右
	{
		snake.coor[0].x += 10;
	}	
	//画出新的蛇
	snake_draw();
}
void food_draw()
{
		setfillcolor(RGB(255,0,0));			
		solidrectangle(food.x, food.y, food.x + 10, food.y + 10);
}
void food_coor()
{
		int x, y;
		x = ((rand() % 66) +1) * 10; 
		y = ((rand() % 56) +1) * 10; 
		//食物不能与蛇身重合
		for (int i = 0;( x==snake.coor[i].x  && y == snake.coor[i].y); i++)
		{
			x = ((rand() % 66) + 1) * 10;
			y = ((rand() % 56) + 1) * 10;
		}
		food.x = x;
		food.y = y;
}
void judge()
{
		HWND result= GetHWnd();
		int out;
		char grade[50];
		//判断吃否吃到食物
		if (snake.coor[0].x == food.x&& snake.coor[0].y == food.y)
		{
			mciSendString("open ./eat_sound.mp3", 0, 0, 0);	//食物音效
			mciSendString("play eat_sound.mp3", 0, 0, 0);	//食物音效
			food_coor();			
			snake.length++;
		}
		//判断是否撞墙
		if (snake.direction == up && snake.coor[0].y <=10 )
		{
			mciSendString("play death_sound.mp3", 0, 0, 0);			//播死亡音效
			mciSendString("stop ./game_bgm.mp3", 0, 0, 0);			//停止游戏背景音乐
			sprintf_s(grade, "分数:%d", snake.length - 3);			
			out = MessageBox(result, grade, "游戏结束",MB_DEFBUTTON1);
			snake.state = 1;
		}
		if (snake.direction == down && snake.coor[0].y >=560  )
		{
			mciSendString("play death_sound.mp3", 0, 0, 0);			//播死亡音效 
			mciSendString("stop ./game_bgm.mp3", 0, 0, 0);			//停止游戏背景音乐
			sprintf_s(grade, "分数:%d", snake.length - 3);
			out = MessageBox(result, grade, "游戏结束", MB_DEFBUTTON1);
			snake.state = 1;
		}
		if (snake.direction == left && snake.coor[0].x<=10  )
		{
			mciSendString("play death_sound.mp3", 0, 0, 0);			//播死亡音效
			mciSendString("stop ./game_bgm.mp3", 0, 0, 0);			//停止游戏背景音乐
			sprintf_s(grade, "分数:%d", snake.length - 3);
			out = MessageBox(result, grade, "游戏结束", MB_DEFBUTTON1);
			snake.state = 1;
		}
		if (snake.direction == right && snake.coor[0].x>=660 )
		{
			mciSendString("play death_sound.mp3", 0, 0, 0);			//播死亡音效
			mciSendString("stop ./game_bgm.mp3", 0, 0, 0);			//停止游戏背景音乐
			sprintf_s(grade, "分数:%d", snake.length - 3);
			out = MessageBox(result, grade, "游戏结束", MB_DEFBUTTON1);
			snake.state = 1;
		}
		//判断是否撞到蛇身
		for (int i = 1; i < snake.length; i++)
		{
		if (snake.coor[0].x == snake.coor[i].x && snake.coor[0].y == snake.coor[i].y)
			{
			mciSendString("play ./death_sound.mp3", 0, 0, 0);		//播死亡音效
			mciSendString("stop ./game_bgm.mp3", 0, 0, 0);			//停止游戏背景音乐	
			sprintf_s(grade, "分数:%d", snake.length - 3);
			out = MessageBox(result, grade, "游戏结束", MB_DEFBUTTON1);
			snake.state = 1;
			}
		}
}
void game()
{	
	int m, n;
	snake_Initialization();			//初始化蛇
	while (snake.state != 1)		//进入循环
	{								//
	BeginBatchDraw();				//开始批量绘图
	background();					//游戏背景
	food_draw();					//画食物
	snake_move();					//蛇移动
	m = 180 - (snake.length - 3);	//控制速度变化
	n = (m >= 10) ? (m) : (10);		//控制速度变化
	Sleep(n);						//休眠 - 控制速度
	EndBatchDraw();					//结束批量绘图
	snkae_key();					//按键检测
	judge();						//进行判断
	}								//

}
  • main.c文件

#include"Transfer.h"

extern INF snake;	
int main()
{
	//打开音乐
	mciSendString("open ./click_sound.mp3", 0, 0, 0);
	mciSendString("open ./death_sound.mp3", 0, 0, 0);
	mciSendString("open ./eat_sound.mp3", 0, 0, 0);
	mciSendString("open ./menu_bgm.mp3", 0, 0, 0);
	mciSendString("open ./game_bgm.mp3", 0, 0, 0);
	//设置随机数
	srand((unsigned)time(NULL));
	//设置画面大小
	initgraph(900, 580, 0);
	int choice;
	while (1)
	{
		choice = menu();
		if ( choice == 1 )//进入游戏
		{	
			game();
			if (snake.state == 1)
				snake.state = 0;
		}
		if ( choice == 0 )//退出游戏
		{	
			exit(0);
		}
	}
	getchar();
	return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/522946.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Stable Diffusion云端部署只需三步, 不吃电脑配置, 模型快速部署

牙叔教程 简单易懂 我是小白, 小白跟我一步一步做就可以了, 鼠标点两下就OK了, 学点新东西, 好吗? 不想学的就走吧, 离我远点. Stable Diffusion是什么 Stable diffusion是一个基于Latent Diffusion Models&#xff08;潜在扩散模型&#xff0c;LDMs&#xff09;的文图生成…

瑞吉外卖 - 后台系统登陆功能(3)

某马瑞吉外卖单体架构项目完整开发文档&#xff0c;基于 Spring Boot 2.7.11 JDK 11。预计 5 月 20 日前更新完成&#xff0c;有需要的胖友记得一键三连&#xff0c;关注主页 “瑞吉外卖” 专栏获取最新文章。 相关资料&#xff1a;https://pan.baidu.com/s/1rO1Vytcp67mcw-PD…

Baumer工业相机堡盟工业相机IO介绍与配置

Baumer工业相机堡盟工业相机IO介绍与配置 Baumer工业相机Baumer工业相机IO的作用Baumer工业相机IO的作用Baumer工业相机IO上点连 Baumer工业相机 Baumer工业相机堡盟相机是一种高性能、高质量的工业相机&#xff0c;可用于各种应用场景&#xff0c;如物体检测、计数和识别、运…

Android基础复习:Service组件详解

Android基础复习&#xff1a;Service组件详解 概况 Service组件是一种可在后台执行长时间运行操作而不提供界面的应用组件。服务可由其他应用组件启动&#xff0c;而且即使用户切换到其他应用&#xff0c;服务仍将在后台继续运行。此外&#xff0c;组件可通过绑定到服务与之进…

【动手学深度学习】现代卷积神经网络汇总

文章目录 1 LeNet2 AlexNet3 VGG4 NiN5 GoogLeNet6 ResNet7 DenseNet 本文为作者阅读学习李沐老师《动手学深度学习》一书的阶段性读书总结&#xff0c;原书地址为&#xff1a;Dive into Deep Learning。 1 LeNet 网络结构 实现代码 net nn.Sequential(nn.Conv2d(1, 6, kern…

springboot+vue社区医院管理服务系统(源码+文档)

风定落花生&#xff0c;歌声逐流水&#xff0c;大家好我是风歌&#xff0c;混迹在java圈的辛苦码农。今天要和大家聊的是一款基于springboot的社区医院管理服务系统。项目源码以及部署相关请联系风歌&#xff0c;文末附上联系信息 。 &#x1f495;&#x1f495;作者&#xff1…

从C出发 32 --- 自定义数据类型(上)

字节 指的就是 byte , 而一个 byte 占用 8 位&#xff0c; 在 C 语言里面有没有 直接提供 表示 8 位的数据类型&#xff1f; char 最小的整型&#xff0c;就可以表示 8 位的数据类型 char 的取值范围 -128 - 127 一个字节的取值范围是 0 - 25…

RK3308B部署mobilenetv2_ssdlite

目录 1. 在PC端运行mobilenetv2_ssdlite模型1.1 安装NCNN和Opencv1.1.1 安装NCNN1.1.2 安装Opencv 1.2 运行mobilenetv2_ssdlite模型 2. 交叉编译部署到RK3308B板子上并运行模型2.1 交叉编译NCNN和Opencv2.1.1 交叉编译Opencv2.1.2 交叉编译ONNX 2.2 交叉编译mobilenetv2_ssdli…

总结850

学习目标&#xff1a; 月目标&#xff1a;5月&#xff08;张宇强化前10讲&#xff0c;背诵15篇短文&#xff0c;熟词僻义300词基础词&#xff09; 周目标&#xff1a;张宇强化前3讲并完成相应的习题并记录&#xff0c;英语背3篇文章并回诵 每日必复习&#xff08;5分钟&#…

深度学习环境配置系列文章(五):配置Docker深度学习开发环境

深度学习环境配置系列文章目录 第一章 专业名称和配置方案介绍 第二章 Anaconda配置Python和PyTorch 第三章 配置VS Code和Jupyter的Python环境 第四章 配置Windows11和Linux双系统 第五章 配置Docker深度学习开发环境 第五章文章目录 深度学习环境配置系列文章目录前言一, Do…

AI工具分享第二期:11款国内外AI绘画提示词工具整理

工具整理自未来百科AI工具箱&#xff0c;更多提示词工具可自行寻找 Midjourney中文教程 Midjourney 学习导航 PromptHero 描述 通过 DALL-E、Stable Diffusion、Midjourney 等 AI 模型搜索数以百万计的艺术图像… PromptDen AI 在线社区促使爱好者联系、协作和分享想法。 …

支付系统设计三:渠道网关设计07-后置处理

文章目录 前言一、订单数据更新1. 领域模型更新服务工厂2. 聚合创建工厂2.1 数据库更新服务2.2 聚合创建工厂 二、限流渠道入队三、异步通知1. 判断是否需要通知2. 组装异步通知报文3. 获取异步通知协议类型3. 异步通知 总结 前言 本篇将继业务处理之后的后置处理逻辑进行介绍&…

瑞吉外卖 - 后台系统退出功能(4)

某马瑞吉外卖单体架构项目完整开发文档&#xff0c;基于 Spring Boot 2.7.11 JDK 11。预计 5 月 20 日前更新完成&#xff0c;有需要的胖友记得一键三连&#xff0c;关注主页 “瑞吉外卖” 专栏获取最新文章。 相关资料&#xff1a;https://pan.baidu.com/s/1rO1Vytcp67mcw-PD…

瑞吉外卖 - 项目介绍(1)

某马瑞吉外卖单体架构项目完整开发文档&#xff0c;基于 Spring Boot 2.7.11 JDK 11。预计 5 月 20 日前更新完成&#xff0c;有需要的胖友记得一键三连&#xff0c;关注主页 “瑞吉外卖” 专栏获取最新文章。 相关资料&#xff1a;https://pan.baidu.com/s/1rO1Vytcp67mcw-PD…

CSS盒子模型、表格标签(table)、表单标签(form)

盒子&#xff1a;页面中所有的元素&#xff08;标签&#xff09;&#xff0c;都可以看做是一个 盒子&#xff0c;由盒子将页面中的元素包含在一个矩形区域内&#xff0c;通过盒子的视角更方便的进行页面布局 盒子模型组成&#xff1a;内容区域&#xff08;content&#xff09;…

Qt扫盲-QScatterSeries理论总结

QScatterSeries理论总结 一、概述二、使用三、扩展四、扩展使用1.创建描述散点图对象2. 对散点图像添加值3. 自定义散点4. 将绘图设备与散点图对象联系5. 设置坐标轴6. 将绘图设备与GUI控件绑定并显示 一、概述 QScatterSeries 类以散点图的形式呈现数据。散点数据在图表上显示…

基于jdk1.8的Java服务监控和性能调优

JVM的参数类型 X参数 非标准参数-Xint: 解释执行-Xcomp: 第一次使用就编译成本地代码-Xmixed: JVM自己来决定是否编译成本地代码 默认使用的是mixed mode 用的不多, 只需要做了解, 用的比较多的是XX参数 XX参数 非标准化参数相对不稳定主要用来JVM调优和Debug Boolean: …

Vivado综合属性系列之一 ASYNC_REG

目录 一、属性简介 二、示例 2.1 工程说明 ​ ​2.2 工程代码 ​ ​2.3 生效确认 一、属性简介 ASYNC_REG属性的作用对象为寄存器&#xff0c;寄存器添加该属性后&#xff0c;即表明寄存器的数据输入口D接收的是来自异步时钟触发器的数据或是该寄存器在一个同步链中属于…

【CSS系列】第九章 · CSS定位和布局

写在前面 Hello大家好&#xff0c; 我是【麟-小白】&#xff0c;一位软件工程专业的学生&#xff0c;喜好计算机知识。希望大家能够一起学习进步呀&#xff01;本人是一名在读大学生&#xff0c;专业水平有限&#xff0c;如发现错误或不足之处&#xff0c;请多多指正&#xff0…

Uni-app 离线打包 apk

Uni-app 离线打包 apk 1. Android Studio 下载 Android Studio官网 2. HBuilderX下载 HBuilderX下载 3. App离线SDK下载 Android 离线SDK - 正式版 下载后解压文件&#xff0c;将 HBuilder-Integrate-AS 重命名 build-template 并拷贝到一个专门打包用的文件夹下作为打包…