【2017-2-11】贪吃蛇C++

#include<iostream>
#include<cstring>
#include<cstdio>
#include<cstdlib>
#include<ctime>
#include<conio.h>
using namespace std;
#define Size 22
#define Max_snake_length 400
typedef struct{
int x,y;
}Point;


char map[Size][Size];
Point snake[Max_snake_length],food,Next;   //定义蛇,食物,下一步蛇头的位置的变量
int head,tail;                             //在snake[]中的蛇头,蛇尾的下标
int grade,length,autotime;                 //游戏难度等级,蛇长度,蛇前进时间间隔
char direction;
double start_time=clock()/CLOCKS_PER_SEC;


inline void Update(char map[][Size],int grade,int length,int autotime){
//地图刷新
//inline内联函数,可以减少程序运行时间和内存开销
system("cls");
double now_time=clock()/CLOCKS_PER_SEC;
int i,j;
printf("\n");
for(i=0;i<Size;i++){
printf("\n");
for(j=0;j<Size;j++)printf("%c ",map[i][j]);
if(i==0) printf("\t等级为: %d",grade);
if(i==2) printf("\t长度为: %d",length);
if(i==6) printf("\t游戏进行时间: %f 秒",(double)(now_time-start_time));
if(i==8) printf("\t前进间隔为: %d ms",autotime);
printf("\n");
}
}


//欢迎界面
inline void hello(){
    system("cls");
puts("\n\n\n\t\t\t贪吃蛇即将开始!");
double start;
for(int i=3;i>=0;i--){
start=(double)clock()/CLOCKS_PER_SEC;
while((double)clock()/CLOCKS_PER_SEC-start<=1);  //经过1秒以后
if(i>0){
system("cls");
printf("\n\n\n\t\t\t进入倒计时: %d\n",i);  //倒计时
}else{
Update(map,grade,length,autotime);
}
}
}
//随机生成食物位置
inline void create_food(){
srand(int(time(0)));        //种子函数,后面生成随机数
do{
food.x=rand()%20+1;
food.y=rand()%20+1;
}while(map[food.x][food.y]!=' ');    //该位置不为空则可以生成食物
map[food.x][food.y]='!';
}
//初始化
inline void init(){
int i,j;
for(i=1;i<=20;i++){
for(j=1;j<=20;j++){
map[i][j]=' ';
}
}
for(i=0;i<=21;i++){
map[0][i]=map[21][i]=map[i][0]=map[i][21]='*';   //地图边界
}
map[1][1]=map[1][2]='0';      //蛇的出生点,蛇身的位置
map[1][3]='@';
head=2;                       //蛇头位置在snake[]中的下标
tail=0;  //蛇尾在snake[]下标
snake[head].x=1;              //蛇出生点的头尾的X,Y坐标
snake[head].y=3;
snake[tail].x=1;
snake[tail].y=1;
snake[1].x=1;    //出生点蛇头,尾的X,Y坐标
snake[1].y=2;
create_food();
grade=1;length=3;autotime=500;
direction=77;                 //初始时方向
}
//预前进
inline int GO(){
bool timeover=true;
double start=(double)clock()/CLOCKS_PER_SEC;         //获取一个时间戳
//自动经过1秒,或等待1秒内的键盘输入
while((timeover=((double)clock()/CLOCKS_PER_SEC-start<=autotime/1000.0))&&!_kbhit());
if(timeover){   //键盘输入
_getch();
direction=_getch();    //获取输入的方向
}
switch(direction){
case 72:             //上方向键,ASCII码为72
Next.x=snake[head].x-1;
Next.y=snake[head].y;
break;
case 80: //下方向键,ASCII码为80
Next.x=snake[head].x+1;
Next.y=snake[head].y;
break;
case 75:            //左方向键,ASCII码为75
Next.x=snake[head].x;
Next.y=snake[head].y-1;
break;
case 77: //右方向键,ASCII码为77
Next.x=snake[head].x;
Next.y=snake[head].y+1;
break;
default:
puts("\tGame over!");
return 0;
}
//触碰边界
if(Next.x==0||Next.x==21||Next.y==0||Next.y==21){
puts("\tGame over!");
return 0;
}
//吃到自己
if(map[Next.x][Next.y]!=' '&&!(Next.x==food.x&&Next.y==food.y)){
puts("\tGame over!");
return 0;
}
//吃到最大长度,显示通关
if(length==Max_snake_length){
puts("\tGame over!");
return 0;
}
return 1;
}
//成功吃到食物
inline void eating_food(){
length++;
int _grade=length/10+1;
if(_grade!=grade){
grade=_grade;
if(autotime>=100){
autotime=550-grade*50;        //游戏难度每升一级,前进间隔就缩减50ms
}
}
map[Next.x][Next.y]='@';              //蛇头位置移动到下一格
map[snake[head].x][snake[head].y]='O';    //原来蛇头处变为蛇身
head=(head+1)%400;            //蛇头下标加1
snake[head].x=Next.x;         //蛇头在snake[]中的下标变化
snake[head].y=Next.y;
create_food();
Update(map,grade,length,autotime);    //刷新地图
}
//没有吃到食物
inline void eating_failed(){
map[snake[tail].x][snake[tail].y]=' ';   //蛇尾原来的位置变成空格
tail=(tail+1)%Max_snake_length;          //蛇尾下标加1
map[Next.x][Next.y]='@';                 //显示蛇头位置
map[snake[head].x][snake[head].y]='O';     //原蛇头位置变化为蛇身
head=(head+1)%Max_snake_length;          //蛇头下标加1
snake[head].x=Next.x;                    //蛇头下标变化
snake[head].y=Next.y;
Update(map,grade,length,autotime);       //刷新地图
}


int main(){
start_pos:    init();
    hello();
char ch='Y';   //是否继续?Y/N
while(ch=='Y'){
if(GO()){
if(Next.x==food.x&&Next.y==food.y){
eating_food();
}else{
eating_failed();
}
}else{
puts("\n\t继续游戏?(Y/N)");
cin>>ch;
if(ch=='Y')goto start_pos;
else return 0;
}
}
system("pause");
return 0;

}


运行截图:


  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
以下是使用Dev-C++编写贪吃蛇的基本步骤: 1. 创建一个新的C++项目,并命名为“贪吃蛇”。 2. 在项目中创建一个新的C++源文件,并将其命名为“main.cpp”。 3. 在“main.cpp”文件中,包含必要的头文件和命名空间: ``` #include <iostream> #include <conio.h> #include <windows.h> using namespace std; ``` 4. 定义贪吃蛇和食物的结构体: ``` struct Snake{ int x, y; }; struct Food{ int x, y; }; ``` 5. 定义全局变量和常量: ``` const int mapWidth = 20; const int mapHeight = 20; const int snakeMaxLen = 100; const int interval = 100; int direction = 0; int score = 0; int snakeLen = 3; Snake snake[snakeMaxLen]; Food food; ``` 6. 初始化游戏窗口和贪吃蛇的初始位置: ``` void init(){ system("mode con cols=40 lines=25");//设置窗口大小 srand((unsigned)time(NULL));//初始化随机数种子 snake[0].x = 10; snake[0].y = 10; snake[1].x = 9; snake[1].y = 10; snake[2].x = 8; snake[2].y = 10; food.x = rand() % mapWidth; food.y = rand() % mapHeight; } ``` 7. 定义绘制函数,用于绘制游戏界面: ``` void draw(){ system("cls");//清屏 for(int i = 0; i < mapHeight; i++){ for(int j = 0; j < mapWidth; j++){ if(i == 0 || i == mapHeight - 1 || j == 0 || j == mapWidth - 1){ cout << "#";//绘制边框 }else if(i == snake[0].y && j == snake[0].x){ cout << "H";//绘制蛇头 }else if(i == food.y && j == food.x){ cout << "*";//绘制食物 }else{ bool isBody = false; for(int k = 1; k < snakeLen; k++){ if(i == snake[k].y && j == snake[k].x){ cout << "o";//绘制蛇身 isBody = true; break; } } if(!isBody){ cout << " ";//绘制空格 } } } cout << endl; } cout << "Score: " << score << endl;//显示得分 } ``` 8. 定义移动函数,用于控制贪吃蛇的移动: ``` void move(){ for(int i = snakeLen - 1; i > 0; i--){ snake[i].x = snake[i - 1].x; snake[i].y = snake[i - 1].y; } switch(direction){ case 0://向上移动 snake[0].y--; break; case 1://向下移动 snake[0].y++; break; case 2://向左移动 snake[0].x--; break; case 3://向右移动 snake[0].x++; break; } } ``` 9. 定义碰撞检测函数: ``` bool check(){ if(snake[0].x == 0 || snake[0].x == mapWidth - 1 || snake[0].y == 0 || snake[0].y == mapHeight - 1){ return true;//撞到边界 } for(int i = 1; i < snakeLen; i++){ if(snake[0].x == snake[i].x && snake[0].y == snake[i].y){ return true;//撞到自己 } } if(snake[0].x == food.x && snake[0].y == food.y){ score += 10;//吃到食物 snakeLen++; food.x = rand() % mapWidth; food.y = rand() % mapHeight; } return false; } ``` 10. 在主函数中,循环执行绘制、移动和碰撞检测等操作: ``` int main(){ init(); while(true){ if(_kbhit()){ char ch = _getch(); switch(ch){ case 'w'://向上移动 if(direction != 1){ direction = 0; } break; case 's'://向下移动 if(direction != 0){ direction = 1; } break; case 'a'://向左移动 if(direction != 3){ direction = 2; } break; case 'd'://向右移动 if(direction != 2){ direction = 3; } break; } } move(); if(check()){ cout << "Game Over!" << endl; break; } draw(); Sleep(interval);//延迟 } return 0; } ``` 11. 编译并运行程序,即可开始游戏。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值