贪吃蛇游戏C语言源代码详解
创作时间:
作者:
@小白创作中心
贪吃蛇游戏C语言源代码详解
引用
CSDN
1.
https://m.blog.csdn.net/2201_75356540/article/details/140147677
本文分享了一个用C语言编写的贪吃蛇游戏源代码,包含详细的注释和玩法说明。对于C语言编程爱好者和学习者来说,这是一个很好的实践案例,可以帮助读者深入理解C语言的语法和编程逻辑。
玩法:
- 输入速度(毫秒/格)注意:输入越大速度越慢。
- wasd或上下左右控制方向
- E或e退出, R或r再来一次
最后附上源码 :
#include <cstdio>
#include <conio.h>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <iostream>
#include <windows.h>
#include <algorithm>
#define REP(i,a,b) for (int i=(a);i<=(b);i++)
#define PER(i,a,b) for (int i=(a);i>=(b);i--)
#define max(x,y) ((x)<(y)?(y):(x))
#define min(y,x) ((x)<(y)?(x):(y))
#define MEM(a,b) memset(a,(b),sizeof(a))
#define KEY_DOWN(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 1:0)//判断这个键是否按下
#define KEY_UP(VK_NONAME) ((GetAsyncKeyState(VK_NONAME) & 0x8000) ? 0 : 1)//判断这个键是否弹起
#define KEY_EVERY(lpkeyState) GetKeyboardState(lpKeyState)//获得所有的256个键(键盘按键、鼠标按键等等)的状态,lpKeyState是指向一个256bit的数组,存放所有键的状态。
#define KEY_NOW(nVirtKey) GetKeyState(nVirtKey)//用于判断nVirtKey的状态。用返回值的最高位表示,最高位为1表示当前键处于down的状态;最高位为0当前键处于up状态。此函数从消息队列中读取消息进行处理。
#define setcolor(x) SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),x)//设置颜色
#define getkey(x) GetAsyncKeyState(x)
#define GetWindow() GetForegroundWindow();//得到窗口信息
/*
鼠标左键 : MOUSE_MOVED
鼠标右键 :MOUSE_EVENT
鼠标滚轮 : MOUSE_WHEELED
MK_CONTROL当CTRL键按下时。
MK_LBUTTON当鼠标左键按下时。
MK_MBUTTON当鼠标中键按下时。
MK_RBUTTON当鼠标右键按下时.
MK_SHIFT当SHIFT按下时。
*/
using std::cin;
using std::cout;
using std::endl;
int brand();
void GOTO(int x,int y);
int brand(){return (rand()<<16)|(rand()<<1)|(rand()&1);}
void bsrand(){srand(GetTickCount());}
void cls(){system("cls");}
void retr(){//退出程序
HWND hWnd=GetForegroundWindow();
ShowWindow(hWnd,SW_HIDE);
exit(0);
}
void Window_Hide(HWND hWnd){ShowWindow(hWnd,0);}//隐藏窗口
void Window_Show(HWND hWnd){ShowWindow(hWnd,1);}//显示窗口
int getmouse_y(){//获取鼠标在屏幕中x的位置
POINT pt;
GetCursorPos(&pt);
return pt.x;
}
int getmouse_x(){//获取鼠标在屏幕中y的位置
POINT pt;
GetCursorPos(&pt);
return pt.y;
}
void setmouse(int y,int x){SetCursorPos(x,y);}//设置鼠标在屏幕中的位置
void click_left(){//鼠标左键点击
mouse_event(MOUSEEVENTF_LEFTDOWN,0,0,0,0);
Sleep(5);//要留给某些应用的反应时间
mouse_event(MOUSEEVENTF_LEFTUP,0,0,0,0);
}
void click_right(){//鼠标右键点击
mouse_event(MOUSEEVENTF_RIGHTDOWN,0,0,0,0);
Sleep(5);
mouse_event(MOUSEEVENTF_RIGHTUP,0,0,0,0);
}
void GOTO(int x,int y){//将光标移动到屏幕中的位置
CONSOLE_SCREEN_BUFFER_INFO csbiInfo;
HANDLE hConsoleOut;
hConsoleOut = GetStdHandle(STD_OUTPUT_HANDLE);
GetConsoleScreenBufferInfo(hConsoleOut,&csbiInfo);
csbiInfo.dwCursorPosition.Y = x;
csbiInfo.dwCursorPosition.X = y;
SetConsoleCursorPosition(hConsoleOut,csbiInfo.dwCursorPosition);
}
using namespace std;
const int flg[4][2]={{1,0},{0,2},{0,-2},{-1,0}};//下右左上
int n=28,m=76,tim;
struct xcw{int x,y;}tan[1000005];//1头 tot尾
int tot,f,score,food,ground=0;
bool vis[1005][1005];
int main();
//void retr(){
// HWND hWnd=GetForegroundWindow();
// ShowWindow(hWnd,SW_HIDE);//隐藏窗口
// exit(0);
//}
bool check(int x,int y){//是否撞到东西
if(x<1||x>n||y<2||y>m) return 0;
bool t=1;
for(int i=1;i<=tot;i++)
if(x==tan[i].x&&y==tan[i].y){t=0;break;}
return t;
}
void fnd(int x,int y){
if(check(x,y)) return;
setcolor(7+ground);cls();
printf("Lose\n");//游戏结束
printf("分数:%d\n",score);
printf("E键退出,R键重来\n");
char ch=getch();
while(ch!='E'&&ch!='e'&&ch!='R'&&ch!='r') ch=getch();
if(ch=='E'||ch=='e') retr();
else{main();exit(0);}
}
void rand_food(){//随机产生食物,不能重复
setcolor(12+ground);
int x=brand()%(n+1),y=(brand()%m/2)*2;
while(!check(x,y)) x=brand()%(n+1),y=(brand()%m/2)*2;
GOTO(x,y);printf("▇");
if(!vis[x][y]) food++;vis[x][y]=1;
x=brand()%(n+1),y=(brand()%m/2)*2;
while(!check(x,y)) x=brand()%(n+1),y=(brand()%m/2)*2;
GOTO(x,y);printf("▇");
if(!vis[x][y]) food++;vis[x][y]=1;
setcolor(10+ground);
}
void draw(){//画地图
setcolor(14+ground);
for(int i=0;i<=n+1;i++) GOTO(i,m+2),printf("▇"),GOTO(i,0),printf("▇");
for(int i=1;i<=m/2+1;i++) GOTO(n+1,i*2),printf("▇"),GOTO(0,i*2),printf("▇");
setcolor(10+ground);
}
int main(){
system("mode con cols=80 lines=31");//设置窗口大小
cls();//清屏
printf("坑货罗的程序:请设置速度(豪秒/格)(建议100):");
cin>>tim;bsrand();MEM(vis,0);food=0;MEM(tan,0);score=0;
setcolor(10+ground);//设置颜色
cls();
draw();
f=1;tan[1]=(xcw){1,6};tan[2]=(xcw){1,4};tan[tot=3]=(xcw){1,2};//初始化蛇
for(int i=1;i<=tot;i++) GOTO(tan[i].x,tan[i].y),printf("0");//画蛇
while(1){
while(!kbhit()){//判断是否有键按下
Sleep(tim);//延时
if(food==0) rand_food();
int x=tan[1].x,y=tan[1].y;
x+=flg[f][0],y+=flg[f][1];
for(int i=tot;i;i--) tan[i+1]=tan[i];//移动蛇
GOTO(tan[tot+1].x,tan[tot+1].y);
printf(" ");//清除蛇尾
if(vis[x][y]) vis[x][y]=0,score++,food--,++tot,GOTO(tan[tot].x,tan[tot].y),printf("▇");//吃到食物长度加一
fnd(x,y);
tan[1]=(xcw){x,y};
GOTO(tan[1].x,tan[1].y);
printf("▇");//画蛇头
}
char ch=getch();
bool t=0;
if(ch=='E'||ch=='e') retr();
if(ch==-32) ch=getch(),t=1;
if((ch==75&&t||ch=='A'||ch=='a')&&f^1) f=2;//改变方向
if((ch==77&&t||ch=='D'||ch=='d')&&f^2) f=1;
if((ch==80&&t||ch=='S'||ch=='s')&&f^3) f=0;
if((ch==72&&t||ch=='W'||ch=='w')&&f^0) f=3;
}
return 0;
}
本文原文来自CSDN
热门推荐
Xcode 正则表达式实现查找替换
金牛座与十二生肖结合的性格分析
哈登带队能力值得肯定!虽输太阳,只需解决一问题则可重回前四!
音浪太强!不晃会被撞到地上!《Hi-Fi Rush》评测:一波接一波的惊喜
谷氨酰胺——十大生理作用
宝可梦:7种优秀的先制招式,对战中往往能出奇制胜
服务器的功能和作用是什么?
深入解析微服务架构:原理、实现及挑战
如何删除需要使用管理员权限才能删除的文件
柠檬在料理中的应用:掌握烹饪技巧,完整保留营养
报名大学英语四级的必知条件与方法
《红楼梦》精读班:一文读懂四大家族及主要人物关系
Faker和Chovy两年绝境对比!这就是为何永远接不了班
听得见,说不清、说不对怎么办?——听觉辨别及其神经机制
冰箱使用时异响?哪些声音属正常现象?异响声大可能是这6方面出了问题
【中国先秦时期列朝列国志】中山国(上):历史沿革
如何让团队自主运行
《赛博朋克2077》夜之城的背景故事(下)
如何有效观察资金流动趋势?这种观察对投资决策有哪些帮助?
豹猫是几级保护动物?详解豹猫的保护级别与保护现状
解析感冒发冷:原因、阶段与舒缓方法
火影忍者手游:宇智波鼬“无限月读”技能详解与战斗策略
老公做事不和你商量怎么办?这几种方法帮你改善婚姻沟通
车胎型号怎么解读
东莞站至东莞南站新增高铁/动车直达,22分钟可达
半夏厚朴汤:古方今用,解锁身体“异物感”之谜
如何查询审判结果?三种方式快速获取法律信息
龙在古代频频“现身”,且留有“证物”,为何现代科学依旧否定?
禁漫现象:为什么一些动漫作品会被禁止?分析背后的多重原因
ISTJ和ISTP的区别:性格分析与行为对比