每天一个c语言小项目,提升你的编程能力!
贪吃蛇游戏大家应该都不陌生了,要说没玩过的话,可能你是15后吧?
贪吃蛇游戏最初为单机模式,后续又陆续推出团战模式、赏金模式、挑战模式等多种玩法。
用游戏把子上下左右控制蛇的方向,寻找吃的东西,每吃一口就能得到一定的积分,而且蛇的身子会越吃越长,身子越长玩的难度就越大,不能碰墙,不能咬到自己的身体,更不能咬自己的尾巴,等到了一定的分数,就能过关,然后继续玩下一关。
贪吃蛇的唯一的目标就是长成最长的一条蛇!滑动摇杆控制小蛇走位,吃掉地图上彩色的小圆点,就会变长。
效果展示:
改变此款游戏的特别多。比如在蛋的方面,可能放上带道具的蛋,使蛇吃完后具有保护,穿墙等特种功能,而且难度逐渐变难。如果有编程技术比较强大的伙伴也可以去尝试一下哦!做出一个趋近完美的贪吃蛇那可就是能力的展现啦~
本项目编译环境:visual studio 2019/2022,easyx插件
代码展示:
#include #include #include #include #define up 1#define down 2#define left 3#define right 4//////////////////////////////////////////////格子类,定义一个格子的属性及行为////////////////////////////////////////////class cell{public: friend class gamearea; //设置友元函数 void setxy(short x, short y) //设置格子左上角坐标{ m_x = x, m_y = y; } void setfull(short full) //设置格子属性,0为空,1为障碍,2为食物{ m_full = full; } void display(colorref color) //设置格子颜色并显示{ m_color = color; setfillstyle(m_color); bar(m_x, m_y, m_x+7, m_y+7); } void laserdisplay() //显示镭射状态的格子{ image image(10,10); setworkingimage(&image); dword* pmem = getimagebuffer(&image); for(int i = 0; i < 10 * 10; i++) pmem[i] = bgr(rgb(0, 0, i * 256 / (10*10) )); setworkingimage(null); putimage(m_x,m_y,&image); } short returnfull() //返回格子状态{ return m_full; } cell() //构造函数 { m_x = 0,m_y = 0,m_full = 0; m_color = black; }private: short m_x; //格子的左上角x坐标 short m_y; //格子的左上角y坐标 short m_full; //0为空,1为阻挡,2为食物 colorref m_color; //格子颜色};//////////////////////////////////////////////游戏区类,编写有关游戏区的一些操作////////////////////////////////////////////class gamearea //游戏区域{public: cell m_game[60][60]; //定义游戏区域(由360个格子组成) friend void messagedispose(); //设置友元函数 bool creatfood() //产生随机食物{ srand(time(null)); //初始化随机数种子 m_random1 = rand()%58+1; //随机生成一个0 - 58的整数 m_random2 = rand()%58+1; //随机一个0 - 58的整数 if(m_game[m_random2][m_random2].m_full == 0) //检查生成的食物坐标是否在障碍上 { m_game[m_random1][m_random2].display(green); m_game[m_random1][m_random2].m_full = 2; return true; } //如果随机的食物正好出现在蛇身上,则进入下面的循环寻找可以生成食物的地方 for(m_random1 = 1;m_random1 < 59;m_random1++) { for(m_random2 = 1;m_random2 < 59;m_random2++) { if(m_game[m_random2][m_random2].m_full == 0) { m_game[m_random1][m_random2].display(green); m_game[m_random1][m_random2].m_full = 2; return true; } } } //如果没有找到可以生成食物的地方,则通关 return false; //返回false即表示通关 } void delfood() //删除食物{ m_game[m_random1][m_random2].m_full = 0; //设置为0即代表格子属性为空 } void changecolor(int flag1,int flag2,colorref color) //设置指定格子的颜色{ m_game[flag1][flag2].display(color); } void init() //初始化game区域{ int flag1,flag2; //标识变量 beginbatchdraw(); //开始批量绘图 setfillstyle(black); //设置当前颜色 bar(0,0,600,600); //画无边框填充矩形(在这里的用途是用黑色清空游戏区域) for(flag1 = 0;flag1 next != null;now = now->next) { free(now->prior); } } head = (struct node*)malloc(sizeof(struct node)); //为蛇头分配内存 head->prior = null; head->m_x = 300; head->m_y = 300; now = (struct node*)malloc(sizeof(struct node)); head->next = now; now->prior = head; now->next = null; now->m_x = 300; now->m_y = 290; last = now; toward = down; } void snakeadd(){ now = head; //当前指向蛇头 now->prior = (struct node*)malloc(sizeof(struct node)); //为新增的结点分配内存 now = now->prior; //让当前指向新分配的结点 now->prior = null; //置空当前结点的前趋 now->next = head; //让当前结点的后继指向蛇头 switch(toward) //根据当前蛇头方向确定新增部分的坐标 { case up: now->m_x = head->m_x; now->m_y = head->m_y -10; break; case down: now->m_x = head->m_x; now->m_y = head->m_y + 10; break; case left: now->m_x = head->m_x - 10; now->m_y = head->m_y; break; case right: now->m_x = head->m_x + 10; now->m_y = head->m_y; break; } head = now; //设置当前结点为蛇头 } void snakedel() //释放蛇尾结点(删除蛇尾){ last = last->prior; free(last->next); last->next = null; } void snakemove() //蛇身移动一格{ snakeadd(); //增加蛇头 snakedel(); //删除蛇尾 }private: struct node //蛇身链表 { int m_x; int m_y; struct node *next; //下个结点 struct node *prior; //上个结点 }; struct node *head; struct node *last; struct node *now;};//////////////////////////////////////////////游戏类,用来初始化游戏的参数,及实现其他游戏操作////////////////////////////////////////////class game{public: void init(){ closegraph(); initgraph(800,600); setbkmode(transparent); //设置输出文字背景为透明 logfont f; getfont(&f); // 获取当前字体设置 f.lfheight = 50; // 设置字体高度为 48(包含行距) _tcscpy(f.lffacename, _t(黑体)); // 设置字体为“黑体” f.lfquality = antialiased_quality; // 设置输出效果为抗锯齿 setfont(&f); // 设置字体样式 } void failgame() //游戏失败显示的画面{ setcolor(red); setfont(70, 0, _t(微软雅黑)); outtextxy(150, 265, _t(you lose!)); } void wingame() //游戏胜利时显示的画面{ setcolor(red); setfont(70, 0, _t(微软雅黑)); outtextxy(150, 265, _t(you win!)); flushbatchdraw(); sleep(10000); exit(0); }};//////////////////////////////////////////////管理区类,定义管理区域的相关操作////////////////////////////////////////////class managearea {public: friend void messagedispose(); void timeadd(double add) //增加时间(可在类外直接调用实现动态刷新时间){ m_time += add; displaytime(); } void scoreadd(short add) //增加分数(可在类外直接调用实现动态刷新分数){ m_score += add; displayscore(); } void displaypause() //显示暂停或者开始{ beginbatchdraw(); _stprintf(m_str_score, _t(%d), m_score); setfont(25, 0, _t(微软雅黑)); setfillstyle(m_bgcolor); bar(625,490,800,515); setcolor(blue); if(m_pause) outtextxy(625, 490, _t(开始(p键))); else outtextxy(625, 490, _t(暂停(p键))); endbatchdraw(); } void init() //初始化管理界面{ m_time = 0.0; m_score = 0; m_leave = 1; m_pause = false; _stprintf(m_str_score, _t(%d), m_score); //格式化转换类型 _stprintf(m_str_time, _t(%.1lf), m_time); m_bgcolor = black; beginbatchdraw(); setfillstyle(black); bar(601,0,800,600); setfont(60, 0, _t(微软雅黑)); setcolor(green); outtextxy(625, 30, _t(贪吃蛇)); setfont(30, 0, _t(微软雅黑)); setcolor(rgb(128,0,255)); outtextxy(625, 140, _t(制作:轻雨漫步)); setfont(25, 0, _t(微软雅黑)); setcolor(blue); outtextxy(625, 430, _t(时间:)); outtextxy(625, 460, _t(分数:)); outtextxy(625, 490, _t(暂停(p键))); outtextxy(625, 520, _t(重新游戏(r键))); setcolor(red); outtextxy(720, 400, m_str_leave); outtextxy(680, 460, m_str_score); outtextxy(680, 430, m_str_time); endbatchdraw(); } private: double m_time; short m_score; short m_leave; bool m_pause; tchar m_str_leave[2], m_str_time[33], m_str_score[5]; colorref m_bgcolor; void displaytime() //显示当前耗时{ beginbatchdraw(); _stprintf(m_str_time, _t(%.1lf), m_time); setfont(25, 0, _t(微软雅黑)); setfillstyle(m_bgcolor); bar(680,430,800,455); setcolor(red); outtextxy(680,430,m_str_time); endbatchdraw(); } void displayscore() //显示当前分数{ beginbatchdraw(); _stprintf(m_str_score, _t(%d), m_score); setfont(25, 0, _t(微软雅黑)); setfillstyle(m_bgcolor); bar(680,460,800,485); setcolor(red); outtextxy(680,460,m_str_score); endbatchdraw(); }};//////////////////////////////////////////////声明游戏需要的类////////////////////////////////////////////game game; //用于初始化游戏、设置游戏相关参数gamearea a; //用于初始化游戏区域,设置,改变游戏区域相关参数managearea manager; //用于初始化管理区域,设置管理区相关参数snake s; //用于初始化蛇,数据化蛇,操作蛇//////////////////////////////////////////////游戏的消息控制,流程控制函数////////////////////////////////////////////void messagedispose() //消息处理函数{ char c; s.now = null; bool keepdown = false; while(true) { keepdown = false; //是否持续按w a s d 中的一个按键 if(kbhit()) { switch(c = getch()) //处理按键消息(w a s d) { case 'w': case 'w': if(s.toward == up)keepdown = true; else if(s.toward != down&&s.toward != up)s.toward = up; break; case 's': case 's': if(s.toward == down)keepdown = true; else if(s.toward != up&&s.toward != down)s.toward = down; break; case 'a': case 'a': if(s.toward == left)keepdown = true; else if(s.toward != right&&s.toward != left)s.toward = left; break; case 'd': case 'd': if(s.toward == right)keepdown = true; else if(s.toward != left&&s.toward != right)s.toward = right; break; case 'p': case 'p': manager.m_pause = !manager.m_pause; //设置暂停或开始 manager.displaypause(); //显示暂停或开始 break; case 'r': case 'r': reinit(); break; } } if(true == manager.m_pause) //如果暂停,直接进行下次循环 { continue; } beginbatchdraw(); switch(a.m_game[s.head->m_x/10][s.head->m_y/10].returnfull()) //检测蛇头遇到的情况 { case 2: //遇到食物,蛇身加长 a.changecolor(s.head->m_x/10,s.head->m_y/10,blue); s.snakeadd(); //蛇增长 a.changecolor(s.head->m_x/10,s.head->m_y/10,blue); a.delfood(); //删除食物 if(a.creatfood() == false) //创建新食物,并检查是否通关 { game.wingame(); //游戏通关(当地图没地方创建食物时) } manager.scoreadd(1); //加一分 break; case 0: a.m_game[s.last->m_x/10][s.last->m_y/10].setfull(0); //设置蛇尾经过处无障碍 a.changecolor(s.last->m_x/10,s.last->m_y/10,black); s.snakemove(); //蛇移动一次 a.changecolor(s.head->m_x/10,s.head->m_y/10,blue); a.m_game[s.head->next->m_x/10][s.head->next->m_y/10].setfull(1); //设置蛇头经过处有障碍 break; case 1: //遇到障碍物 game.failgame(); a.changecolor(s.head->m_x/10,s.head->m_y/10,rgb(255,127,39)); flushbatchdraw(); { char c = ' '; while(c != 'r' && c != 'r') //当游戏失败时,按r键可重新进行游戏 { if(kbhit()) { c = getch(); } sleep(10); } } reinit(); //重新开始游戏 break; } endbatchdraw(); if(keepdown==false) { sleep(100); manager.timeadd(0.1); //增加时间 } else //当持续按下按方向键时 { sleep(40); //适当休眠可以增加游戏流畅性 manager.timeadd(0.04); //增加时间 } }}//////////////////////////////////////////////游戏初始化函数////////////////////////////////////////////void reinit(){ a.init(); //初始化游戏区 s.init(); //初始化蛇 manager.init(); //初始化管理区 //绘制蛇的开始状态 s.now = s.head; a.changecolor(s.now->m_x/10,s.now->m_y/10,blue); s.now = s.last; a.changecolor(s.now->m_x/10,s.now->m_y/10,blue);}//////////////////////////////////////////////main函数,程序入口////////////////////////////////////////////int main(void){ game.init(); //初始化游戏参数、设置 reinit(); //初始化其他 messagedispose(); //消息处理函数 return 0;}
大家赶紧去动手试试吧!
单项冠军企业和“小巨人”企业向产业和创新高峰发起“猛攻”
瑞典研发新技术可让WiFi每秒传输2.5TB数据
LoRa模块LoRa1262和LoRa1268的区别是什么
三星Exynos芯片将进军PC市场
如何在远程桌面中使用USB 设备
C语言零基础项目:贪吃蛇!详细思路+源码分享
MEMS产品的封装选择和设计
关于霍尔效应传感器的原理及特点性能介绍
2nm芯片一片多少钱
WMC2017新机汇总:诺基亚3/诺基亚5/诺基亚3310/LGG6/华为P10
浅谈Perl在IC设计中的运用
智能家居中的数字鸿沟是怎么一回事
为什么变频挂机会出现多故障代码的情况呢
功率放大器的主要指标参数有哪些
成就客户,成就同路人!国仪量子量子计算与测控事业部2023年度合作伙伴大会成功举行
人工智能可以完完全全代替掉人工服务吗
关于中欧半导体产业平台的发展分析
探照灯自动/手动控制报警电路,Searchlight alarm
售罄!华为开发者大会全通票已全线沽清
可穿戴软压力传感器有着怎样的作用