基于EasyX的贪吃蛇游戏(C语言)
贪吃蛇游戏EasyX图形库C语言
#前言
关于贪吃蛇游戏这种学生时代,用来应付一个期末设计的东西。网上各式各样用不同方式实现的核心代码已经烂大街了。
用esayX这种图形库,可以简单进行蛇体,游戏界面的绘制。
我是通过确定了坐标后,直接插入的外部图片(图都是自己用画的)
主要增加了一下分数排行,分数显示,播放音乐等功能。都是些很简单的小玩意
#运行界面
以下是源代码
#pragma warning(disable:4996)
#include <stdio.h>
#include <graphics.h> //调用EasyX的图形库
#include <windows.h>
#include <conio.h>
#include <time.h>
#include <stdlib.h>
#include <wchar.h>
#pragma comment(lib, "Winmm.lib")//调用有关多媒体的动态连接库#define GAMEWIDTH 640 //游戏窗口的宽
#define GAMEHIGH 480 //游戏窗口的高
#define N 20 //蛇每节的大小20x20
#define SNAKELEN 1000 //蛇的最大长度1000
#define SPEED 180 //定义初始的移动速度
#define PATHFILE "rank.txt"//分数存储的文件//自定义函数
//——————————————————————————————void menu(); //进入游戏的主菜单界面
void about(); //关于游戏界面
void initgame(); //初始化游戏界面
void OverGame(); //游戏失败界面
void gameegg(); //游戏彩蛋界面void snakepic(); //加载蛇头蛇身的图片
void showsnake(); //生成蛇
void showfood(); //加载食物图片
void snakepicmove(); //控制蛇移动
void setfoodcrd(); //食物的生成坐标
void EatFood(); //吃到食物
void GameEnd(); //游戏退出和触发彩蛋的条件
void SnakeDirection(); //蛇头的方向
void addscore(); //显示分数
int rank(); //储存排行榜
int readrank(); //输出排行榜
void speedup(); //游戏加速//自定义结构体和全局变量
//——————————————————————————————MOUSEMSG m; //定义鼠标,引用Exasy库
int s; //定义游戏分数// 方便以后在程序中改变速度
int speed = SPEED;
//定义使用的外部图片
IMAGE foods, snakeup, snakedown, snakeleft, snakerigth, snakebody, background, gameoverbk, reback, scorebk, gameeggbk;typedef struct inf //定义一个结构体存放分数
{int score;
}info;enum DIR //运动方向的结构体
{up = 72, //上、下、左、右、空格键ASCII码down = 80,left = 75,right = 77,space = 32
};typedef struct COOR //表示坐标的结构体
{int x; //横坐标int y; //纵坐标
};struct SNAKE //定义结构体,来存储蛇的相关信息
{COOR crd[SNAKELEN]; //保存蛇的每个结数的坐标,最多有1000节int node; //保存蛇当前节数DIR dir; //当前蛇行进的方向
}snake;struct FOOD //食物的结构体
{COOR crd; //食物坐标int flag; //表示有没有食物 1代表没有食物,没有食物需要生成食物
}food;//=================================================================
//主函数
int main()
{initgraph(GAMEWIDTH, GAMEHIGH); //创建一个680X480窗口menu(); //主菜单函数return 0; //程序正常结束
} //主菜单界面模块
void menu()
{loadimage(&background, _T("pic\\bk.jpg"), 640, 480); //从文件中读取图像putimage(0, 0, &background); //重载用于在当前设备上绘制指定图像setbkmode(TRANSPARENT); //字体背景透明while (true){while (MouseHit()) //检测当前是否有鼠标消息{m = GetMouseMsg(); //函数用于获取一个鼠标消息if (m.uMsg == WM_LBUTTONDOWN) //左键按下消息{if (m.x >= 60 && m.x <= 280) //鼠标点击的区域横坐标为60-280{ if (m.y >= 160 && m.y <= 215) //鼠标点击的区域纵坐标为160-215{mciSendString(_T("open pic\\Sushi.mp3 alias mysong"), NULL, 0, NULL); //从指定目录调用音乐mciSendString(_T("play MySong repeat"), NULL, 0, NULL); //播放音乐initgame(); //进入游戏游戏界面}if (m.y >= 260 && m.y <= 315){//分数排行榜readrank();}if (m.y >= 360 && m.y <= 415){//关于游戏about();}}}}}}//游戏说明界面
void about()
{cleardevice(); //清除屏幕内容loadimage(&reback, _T("pic\\aboutbk.jpg"), 640,480);//背景图片putimage(0, 0 ,&reback);while (true) //鼠标点击,返回主菜单界面{if (MouseHit()){m = GetMouseMsg();if (m.uMsg == WM_LBUTTONDOWN){if (m.x >=540 && m.x <= 660 && m.y >=417 && m.y <= 460){menu(); //主菜单函数}}}}
}//载入蛇身,蛇头的图片
void snakepic()
{setbkcolor(WHITE); //背景窗口设置为白色loadimage(&snakeup, _T("pic\\蛇头上.jpg"), N, N);loadimage(&snakedown, _T("pic\\蛇头下.jpg"), N, N);loadimage(&snakeleft, _T("pic\\蛇头左.jpg"), N, N);loadimage(&snakerigth, _T("pic\\蛇头右.jpg"), N, N);loadimage(&snakebody, _T("pic\\贪吃蛇身体.jpg"), N, N);snake.crd[0].x = 0; //蛇出现的横坐标snake.crd[0].y = 0; //蛇出现的纵坐标snake.node = 1; //蛇出生的节数snake.dir = down; //蛇头运动的初始方向food.flag = 0; //没有食物cleardevice(); //清除屏幕内容
}//初始化游戏的界面,运行游戏
void initgame()
{srand(time(NULL)); //设置一个随机种子,每次运行都能保证随机种子不同。snakepic(); //载入蛇身,蛇头的图片s = -10; //循环开始时,将分数设置为负数while (1){while (!_kbhit()){if (!food.flag) //食物不存在,就生成食物{setfoodcrd();s += 10; //每生产一次食物加10分}cleardevice();showfood(); //食物图片addscore(); //左上角显示分数snakepicmove(); //showsnake(); //Sleep(speed); //移动速度EatFood(); //吃到食物GameEnd(); //游戏结束条件}SnakeDirection();}
}//随机生成食物的坐标
void setfoodcrd()
{food.crd.x = rand() % (640 /N) *N;food.crd.y = rand() % (480 /N) *N;food.flag = 1;
}//放置食物的图片
void showfood()
{loadimage(&foods, _T("pic\\食物.jpg"), N, N);putimage(food.crd.x, food.crd.y, &foods);
}//放置蛇头以及蛇身的图片
void showsnake()
{//蛇头switch (snake.dir)//获取运动方向,改变蛇头图片{case up:putimage(snake.crd[0].x, snake.crd[0].y, &snakeup);break;case down:putimage(snake.crd[0].x, snake.crd[0].y, &snakedown);break;case left:putimage(snake.crd[0].x, snake.crd[0].y, &snakeleft);break;case right:putimage(snake.crd[0].x, snake.crd[0].y, &snakerigth);break;default:break;}//蛇身//通过一个从(node-1)到1的循环,生成蛇身,进行贴图for (int i = snake.node - 1; i > 0; i--){putimage(snake.crd[i].x, snake.crd[i].y, &snakebody);}
}//蛇体贴图坐标的移动
void snakepicmove()
{//倒数第一节蛇身的贴图坐标等于倒数第二节for (int i = snake.node - 1; i > 0; i--){snake.crd[i].x = snake.crd[i - 1].x;snake.crd[i].y = snake.crd[i - 1].y;}switch (snake.dir){case up:snake.crd[0].y -= N;break;case down:snake.crd[0].y += N;break;case left:snake.crd[0].x -= N;break;case right:snake.crd[0].x += N;break;default:break;}
}//键盘操作控制蛇移动方向
void SnakeDirection()
{switch (_getch()){case 72:if (snake.dir != down)snake.dir = up;break;case 80:if (snake.dir != up)snake.dir = down;break;case 75:if (snake.dir != right)snake.dir = left;break;case 77:if (snake.dir != left)snake.dir = right;break;case 32://空格暂停system("pause");default:break;}
}//吃到食物:食物的坐标和蛇头坐标的重合
void EatFood()
{if (snake.crd[0].x == food.crd.x && snake.crd[0].y == food.crd.y)//食物的坐标和蛇头坐标(snake.crd.[0])的重合{snake.node++; //节数增加food.flag = 0; //生成食物的标志变为0speedup(); //每次吃到食物后,加速}
}//判断游戏退出
void GameEnd()
{//撞墙if (snake.crd[0].y < -1 || snake.crd[0].y>471 || snake.crd[0].x < -1 || snake.crd[0].x>631){//退出OverGame();}//吃到自己for (int i = snake.node - 1; i > 0; i--){if (snake.crd[0].x == snake.crd[i].x && snake.crd[0].y == snake.crd[i].y){//退出OverGame();}}//分数到达520if (s ==520){ //彩蛋界面gameegg();}
}//游戏结束画面及相关操作
void OverGame()
{mciSendString(_T("close MySong"), NULL, 0, NULL); //游戏结束,关闭背景音乐loadimage(&gameoverbk, _T("pic\\gameoverbk.jpg"),640,480);putimage(0, 0, &gameoverbk);setbkmode(TRANSPARENT); //字体背景透明settextcolor(BLACK); //黑色字体settextstyle(31,31,_T("字魂27号-布丁体")); //字体大小,样式TCHAR myscore[20]; //定义一个数组用来显示分数swprintf_s(myscore, _T("你的分数:%d"), s); //输出数组outtextxy(226,246, myscore); //文本输出的位置//鼠标操作while (true){while (MouseHit()){m = GetMouseMsg();if (m.uMsg == WM_LBUTTONDOWN){if (m.x >= 220 && m.x <= 420){if (m.y >= 250&& m.y <=295 ){rank();}if (m.y >= 320 && m.y <= 365){rank();menu();}if (m.y >= 390 && m.y <= 435){rank();exit(0);}}}}}
}//游戏分数的显示
void addscore()
{TCHAR myscore[20];swprintf_s(myscore, _T("score:%d"), s);// 输出数值,先将数字格式化输出为字符串settextcolor(BLACK);outtextxy(0,0,myscore);//输出分数的文本内容
}//创建一个文件储存分数
int rank()
{info tmp;FILE* fp;tmp.score = s;fp = fopen(PATHFILE, "a");//追加 向文本文件尾添加数据if (fp == NULL){return -1;}fwrite(&tmp, sizeof(struct inf), 1, fp);fclose(fp); return 0;
}//分数排行榜
int readrank(){ //载入分数界面的背景图片------------------------------loadimage(&scorebk, _T("pic\\scorebk.jpg"), 640, 480);putimage(0, 0, &scorebk);//读取分数进行排序------------------------------------info tmp[N]; info temp; //空的结构体用于交换int n = 0, j = 0, i = 0,k=0;FILE* fp;fp = fopen(PATHFILE, "a+");if (fp == NULL){printf("cannot open the files\n");}while (!feof(fp)) //数组tmp读取文件,未到达文件尾{fread(&tmp[i], sizeof(struct inf), 1, fp);i++; //每读取一条数据,i+1}n = i - 1; //记录排行榜人数for (i = 0; i < n; i++) //冒泡排序对分数排序for (j = i + 1; j < n; j++)if (tmp[i].score < tmp[j].score){temp =tmp[i];tmp[i] = tmp[j];tmp[j] = temp;}//显示排序后的分数--------------------------------------TCHAR myscore[20]; if(i>=10) //当记录的分数数据超过10条{for (i = 0; i < 10; i++) //只显示前10个分数{swprintf_s(myscore, _T("%d %d"), i + 1, tmp[i].score);settextcolor(BLACK);settextstyle(25, 25, _T("字魂75号-柳叶竹眉体"));outtextxy(185, 120 + i * 20, myscore);//输出分数的文本内容}fclose(fp);}if (i < 10) //当记录的分数数据不超过10条 {for (k = 0; k < i; k++) //只显示前i条分数{swprintf_s(myscore, _T("%d %d"), k + 1, tmp[k].score);settextcolor(BLACK);settextstyle(25, 25, _T("字魂75号-柳叶竹眉体"));outtextxy(185, 120 + k * 20, myscore);//输出分数的文本内容}fclose(fp);//关闭文件}//鼠标操作返回主菜单--------------------------------------while (true) {while (MouseHit()){m = GetMouseMsg();if (m.uMsg == WM_LBUTTONDOWN){if (m.x >= 540 && m.x <= 660 && m.y >= 417 && m.y <= 460)//返回主菜单界面{menu();}if (m.x >= 460 && m.x <=500 && m.y >= 417 && m.y <= 460){remove(PATHFILE);//清空记录}}}}
}
//游戏彩蛋
void gameegg()
{mciSendString(_T("close MySong"), NULL, 0, NULL);mciSendString(_T("open pic\\InsideStory.mp3 alias mysong2"), NULL, 0, NULL);mciSendString(_T("play MySong2 repeat"), NULL, 0, NULL);loadimage(&gameeggbk, _T("pic\\gameeggbk.jpg"),640,480);putimage(0, 0, &gameeggbk);//返回菜单while (true){while (MouseHit()){m = GetMouseMsg();if (m.uMsg == WM_LBUTTONDOWN){if (m.x >= 540 && m.x <= 660 && m.y >= 417 && m.y <= 460)//返回主菜单界面{mciSendString(_T("close MySong2"), NULL, 0, NULL); //游戏结束,关闭背景音乐rank();menu();}}}}
}//游戏加速
void speedup()
{if (speed >= 80){speed= speed - 10;}
}
下面是整个文件的链接
链接:https://pan.baidu.com/s/1Vp7khf_UfUR-b1fU1PQzkQ
提取码:jk71
仅供学习参考
基于EasyX的贪吃蛇游戏(C语言)相关推荐
- 基于EasyX的贪吃蛇游戏
基于EasyX的贪吃蛇游戏 一.预备知识 二.游戏逻辑 1.贪吃蛇元素 2.贪吃蛇规则 三.游戏设计 1.地图设计 2.移动设计 3.速度设计 4.整体设计 一.预备知识 1.使用EasyX必须要知道 ...
- Linux下基于SDL库贪吃蛇游戏
Linux下基于SDL库贪吃蛇游戏 SDL(Simple DirectMediaLayer)是一套开放源代码的跨平台多媒体开发库,使用C语言写成.SDL提供了数种控制图像.声音.输出入的函数,让开 ...
- python贪吃蛇设计目标_基于 pygame 设计贪吃蛇游戏
基于 pygame 设计贪吃蛇游戏 贪吃蛇游戏通过玩家控制蛇移动,不断吃到食物增长,直到碰到蛇身或边界游戏结束.其运行效果如下所示: 游戏开始时,先导入可能需要用到的包. import time im ...
- 基于React的贪吃蛇游戏的设计与实现
代码地址如下: http://www.demodashi.com/demo/11818.html 贪吃蛇小游戏(第二版) 一年半前层用react写过贪吃蛇小游戏https://github.com/c ...
- 基于HTML5的贪吃蛇游戏的设计与实现
基于HTML5的贪吃蛇游戏的设计与实现 功能要求: 贪吃蛇游戏是一款经典的单机休闲游戏,玩家通过上下左右按键控制蛇头的移动方向使其向指定方向前进,并吃掉随机位置上产生食物来获得分数.每吃掉一次食物,贪 ...
- 基于单片机的贪吃蛇游戏
绪论 1.1 研究背景与意义 随着社会的发展,人们生活的步调日益加快,越来越多的人加入了全球化的世界. 人们不再拘泥于--,J,块天地,加班,出差成了现代人不可避免的公务.而此时一款可以 随时随地娱乐 ...
- 基于单片机的贪吃蛇游戏设计_前端入门,基于html,css,javascript的贪吃蛇游戏
源代码: 贪吃蛇 .box1{ font-size: 15px; float:left; display: block; margin-right: 150px; } .box2{ font-size ...
- 基于linux的贪吃蛇游戏设计_贪吃蛇还能这么玩?绝对是你从未体验过的全新版本(上)...
上个月 Gitee 宣布推出「Python 贪吃蛇魔改大赛」的活动,受到了众多开发者们的欢迎.半个多月后,我们收到了共计 42 个参赛作品,有的作品创意无限,有的作品视觉效果极佳,看看下面的作品一览, ...
- 贪吃蛇游戏 C语言程序设计
<计算机程序设计>课程设计报告 课 题 名 称贪吃蛇游戏 班 级 软件1班 姓 名 neolone 目录 1 需求分析... 1 2 系统分析和设计... 1 2. ...
最新文章
- Cortex-M0微处理器异常入口流程的细节
- linux中用户的分类
- java学习(142):file类的基本创建
- mysql 创建查询 删除_MYSQL数据库查询删除创建企业基本知识
- 速芯科技完成1亿元人民币融资
- c#事件的发布-订阅模型_NET Core 3 WPF MVVM框架 Prism系列之事件聚合器
- ipad 计算机连接网络设置方法,iPad Air怎么设置上网?苹果平板常用的上网方法图解...
- c++ list遍历_List集合就这么简单「源码剖析」
- SpringBoot异常处理机制之自定义404、500错误提示页面
- 通过对比文件md5值,实现对文件的替换
- Oracle优化的几个简单步骤
- geoserver中sld设置
- 从随机生成九宫格至随机生成数独游戏再至用回溯法实现数独的解
- 硬盘的种类及运行原理
- css——font 样式和对照表 颜色格式和颜色渐变
- 英雄之刃显示服务器断开怎么办,英魂之刃手游新手常见问题
- 【转】我的助理辞职了!—给不听话的下属看看
- UVA 1630 Folding
- 使用DRA诊断问题并提出建议
- 如何在Windows上使用PSCP命令?
热门文章
- postgresql_internals-14 学习笔记(五)Buffer Cache
- java单数字随机抽奖特效_js实现简易的单数字随机抽奖(0-9)
- css里面li标签怎么加图片_css 点击ul切换其中li标签内的图片
- 硅谷又出来“唬人”了?改变情绪的可穿戴设备是它最新的骗局
- 如何使用Matrix对bitmap的旋转与镜像水平垂直翻转
- TFLite: flatbuffers
- 【webrtc0419 注册功能】
- android 跳转腾讯地图导航,Android 地图跳转到百度、高德、腾讯导航
- 手机html脚本病毒,自己整的按键精灵脚本也能当成病毒……
- IPC机制(Inter-Process Communucation)