C语言版贪食蛇游戏源代码(我自己写的)

#include <stdio.h>
#include <windows.h>
#include <conio.h>
#include <string.h>

#define UP 0
#define DOWN 1
#define LEFT 2
#define RIGHT 3//宏定义,定义四个方向--0 1 2 3分别代表上下左右

#define TURN_NUM 1000//可以保存的最多转弯次数,一条蛇同时最多只能有1000次的弯曲
#define INIT_LENGTH 8

#define UP_EDGE 0
#define DOWN_EDGE 24
#define LEFT_EDGE 0
#define RIGHT_EDGE 79//定义上下左右四个边界

#define X 0//初始状态下蛇的身体坐标(LEFT_EDGE+X,UP_EDGE+Y)
#define Y 0//决定初始状态下蛇的身体相对于游戏界面原点(LEFT_EDGE,UP_EDGE)的位置

/*定义全局变量*/
char buf[1000]="@*******";//决定初始的snake_length的值:必须与INIT_LENGTH保持同步
char *snake=buf;//蛇的身体,最长有1000个环节
char FOOD='$';//记录食物的形状
int food_num=0;//记录已经吃下的食物数量
int score=0;//记录当前的得分,由food_num决定
int snake_length=INIT_LENGTH;//initializer is not a constant:strlen(snake);
int cursor[2]={LEFT_EDGE+20+INIT_LENGTH,UP_EDGE+10};//记录当前光标所指位置
int head[2]={LEFT_EDGE+20+INIT_LENGTH-1,UP_EDGE+10};//记录头部的坐标
int tail[2]={0,0};//记录尾巴的坐标
int old_tail[2];//记录上一步尾巴所在位置
int food[2]={0,0};//记录食物的坐标
int init_position[2]={LEFT_EDGE+X,UP_EDGE+Y};//蛇的初始位置
int direction=RIGHT;//记录当前蛇的头部的运动方向
int turn_point[TURN_NUM][2];
int head_turn_num=0;//记录头部的转弯次数
int tail_turn_num=0;//记录尾巴的转弯次数
int game_over=0;//判断游戏是否结束

/*主方法*/
void main(){
 //函数声名
 void gotoxy(int x,int y);//移动光标的位置
 void cur_state();//测试游戏的当前状态参数
 void print_introduction();//打印游戏规则
 void init();//初始化游戏
 void control();//接收键盘控制命令
 void move();//控制身体的运动
 void move_up();//向上运动
 void move_down();//向下运动
 void move_left();//向左运动
 void move_right();//向右运动
 void update_tail_position();//更新尾巴的坐标
 void generate_food();//随机产生食物
 void eat_food();//吃下食物

 char ch;

 while(!game_over){
  print_introduction();
  printf("/t/t按任意键开始游戏");
  getch();
  system("cls");
  //cur_state();
  init();
  control();
  system("cls");
  gotoxy(0,10);
  printf("/t/t您的当前得分是%d/n",score);
  printf("/t/t这条蛇共转了%d次弯,它的身体长度是%d/n",head_turn_num,strlen(snake));
  printf("/t/t游戏结束,您要再玩一局吗?(y/n)");
  scanf("%c",&ch);
  getchar();
  if(ch=='y'||ch=='Y'){
   continue;
  }else{
   system("cls");
   printf("/n/n/n/t/t/t谢谢您的使用,再见!");
   _sleep(3000);
   game_over=1;
  }
 }
}

/*打印游戏规则*/
void print_introduction(){
 int i=0;
 int rule_num;
 char *rule[4];
 rule[i++]="/n/n/t/t/t欢迎您来玩贪食蛇游戏/n";
 rule[i++]="/t/t游戏规则如下:/n";
 rule[i++]="/t/t1.按上下左右键控制蛇的运动方向/n";
 rule[i++]="/t/t2.按Ctrl+C结束当前游戏/n";
 rule_num=i;
 system("cls");
 for(i=0;i<rule_num;i++){
  puts(rule[i]);
 }
}

/*移动光标的位置*/
void gotoxy(int x,int y){
 COORD coord={x,y};
 SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE),coord);
}

/*测试游戏的当前状态参数*/
void cur_state(){
 printf("游戏的当前状态参数如下:/n");
 printf("snake=%s/n",snake);
 printf("snake_body_length=%d/n",strlen(snake));
 printf("head=(%d,%d)/n",head[0],head[1]);
 printf("tail=(%d,%d)/n",tail[0],tail[1]);
 printf("direction=%d/n",direction);
 printf("game_over=%d/n",game_over);
}

/*游戏进入初始状态*/
void init(){
 int i;

 /*初始化游戏参数*/
 food_num=0;//记录已经吃下的食物数量
 score=0;//记录当前的得分,由food_num决定
 snake_length=INIT_LENGTH;
 cursor[0]=init_position[0]+INIT_LENGTH;
 cursor[1]=init_position[1];//记录当前光标所指位置
 head[0]=init_position[0]+INIT_LENGTH-1;
 head[1]=init_position[1];//记录头部的坐标
 tail[0]=init_position[0];
 tail[1]=init_position[1];//记录尾巴的坐标
 direction=RIGHT;//记录当前蛇的头部的运动方向
 head_turn_num=0;//记录头部的转弯次数
 tail_turn_num=0;//记录尾巴的转弯次数
 game_over=0;//判断游戏是否结束
 turn_point[0][0]=RIGHT_EDGE;
 turn_point[0][1]=0;
 /*游戏参数初始化完毕*/

 generate_food();//投下第一粒食物
 gotoxy(init_position[0],init_position[1]);//将光标移动到到初始化位置
 for(i=snake_length;i>0;i--){
  putchar(snake[i-1]);
 }
}

/*接收键盘控制命令*/
void control(){
 char command;//存放接收到命令
 while(1){
  command=getch();
  if(command==-32){
   //F11,F12:-123,-122
   command=getch();
   if(command=='H' && (direction==LEFT || direction==RIGHT)){//光标上移
    direction=UP;
    turn_point[head_turn_num%TURN_NUM][0]=head[0];
    turn_point[head_turn_num%TURN_NUM][1]=head[1];
    head_turn_num++;
   }else if(command=='P' && (direction==LEFT || direction==RIGHT)){//光标下移
    direction=DOWN;
    turn_point[head_turn_num%TURN_NUM][0]=head[0];
    turn_point[head_turn_num%TURN_NUM][1]=head[1];
    head_turn_num++;
   }else if(command=='K' && (direction==UP || direction==DOWN)){//光标左移
    direction=LEFT;
    turn_point[head_turn_num%TURN_NUM][0]=head[0];
    turn_point[head_turn_num%TURN_NUM][1]=head[1];
    head_turn_num++;
   }else if(command=='M' && (direction==UP || direction==DOWN)){//光标右移
    direction=RIGHT;
    turn_point[head_turn_num%TURN_NUM][0]=head[0];
    turn_point[head_turn_num%TURN_NUM][1]=head[1];
    head_turn_num++;
   }else if(command==-122 || command==-123);
   
  }else if(command==0){
   command=getch();//接收Fn的下一个字符
   //F1~F10:59~68
  }else if(command>=1&&command<=26){
   //Ctrl+a~z:1~26
   if(command==3){
    break;
   }
  }else{
   //do nothing!
  }
  move();
  if(head[0]==food[0] && head[1]==food[1]){
   eat_food();//吃掉一粒事物
   generate_food();//投下新食物
  }
 }
}

/*蛇的身体运动*/
void move(){
 if(direction==UP){
  //printf("Moving up!/n");
  move_up();
 }else if(direction==DOWN){
  //printf("Moving down!/n");
  move_down();
 }else if(direction==LEFT){
  //printf("Moving left!/n");
  move_left();
 }else if(direction==RIGHT){
  //printf("Moving right!/n");
  move_right();
 }
}

/*向上运动*/
void move_up(){
 if(cursor[1]>=UP_EDGE){
  gotoxy(head[0],head[1]);
  putchar('*');
  gotoxy(head[0],head[1]-1);
  putchar(snake[0]);
  gotoxy(tail[0],tail[1]);
  //_sleep(1000);//查看尾部光标
  putchar(0);
  update_tail_position();
  head[1]-=1;
  cursor[0]=head[0];
  cursor[1]=head[1]-1; 
  gotoxy(cursor[0],cursor[1]);
 }else{
  gotoxy(head[0],head[1]);
 }
}

/*向下运动*/
void move_down(){
 if(cursor[1]<=DOWN_EDGE){
  gotoxy(head[0],head[1]);
  putchar('*');
  gotoxy(head[0],head[1]+1);
  putchar(snake[0]);
  gotoxy(tail[0],tail[1]);
  //_sleep(1000);//查看尾部光标
  putchar(0);
  update_tail_position();
  head[1]+=1;
  cursor[0]=head[0];
  cursor[1]=head[1]+1;
  gotoxy(cursor[0],cursor[1]);
 }else{
  gotoxy(head[0],head[1]);
 }
}

/*向左运动*/
void move_left(){
 if(cursor[0]>=LEFT_EDGE){
  gotoxy(head[0],head[1]);
  putchar('*');
  gotoxy(head[0]-1,head[1]);
  putchar(snake[0]);
  gotoxy(tail[0],tail[1]);
  //_sleep(1000);//查看尾部光标
  putchar(0);
  update_tail_position();
  head[0]-=1;
  cursor[0]=head[0]-1;
  cursor[1]=head[1];
  gotoxy(cursor[0],cursor[1]);
 }else{
  gotoxy(head[0],head[1]);
 }
}

/*向右运动*/
void move_right(){
 if(cursor[0]<=RIGHT_EDGE){
  gotoxy(head[0],head[1]);
  putchar('*');
  putchar(snake[0]);
  gotoxy(tail[0],tail[1]);
  //_sleep(1000);//查看尾部光标
  putchar(0);
  update_tail_position();
  head[0]+=1;
  cursor[0]=head[0]+1;
  cursor[1]=head[1];
  gotoxy(cursor[0],cursor[1]);
 }else{
  gotoxy(head[0],head[1]);
 }
}

/*更新尾巴的坐标*/
void update_tail_position(){
 old_tail[0]=tail[0];
 old_tail[1]=tail[1];//保存上次尾巴的位置
 if(tail[0]==food[0] && tail[1]==food[1]){
  gotoxy(tail[0],tail[1]);
  putchar(FOOD);
 }
 if(tail_turn_num<head_turn_num){
  if(tail[0]<turn_point[tail_turn_num%TURN_NUM][0]){
   tail[0]+=1;
  }else if(tail[0]>turn_point[tail_turn_num%TURN_NUM][0]){
   tail[0]-=1;
  }else if(tail[1]<turn_point[tail_turn_num%TURN_NUM][1]){
   tail[1]+=1;
  }else if(tail[1]>turn_point[tail_turn_num%TURN_NUM][1]){
   tail[1]-=1;
  }else if(tail[0]==turn_point[(tail_turn_num-1)%TURN_NUM][0] && tail[1]==turn_point[(tail_turn_num-1)%TURN_NUM][1]){
   if(tail[0]<turn_point[tail_turn_num%TURN_NUM][0]){
    tail[0]+=1;
   }else if(tail[0]>turn_point[tail_turn_num%TURN_NUM][0]){
    tail[0]-=1;
   }else if(tail[1]<turn_point[tail_turn_num%TURN_NUM][1]){
    tail[1]+=1;
   }else if(tail[1]>turn_point[tail_turn_num%TURN_NUM][1]){
    tail[1]-=1;
   }
  }
  if(tail[0]==turn_point[tail_turn_num%TURN_NUM][0] && tail[1]==turn_point[tail_turn_num%TURN_NUM][1]){
   tail_turn_num+=1;
  }
 }else if(tail_turn_num==head_turn_num){
  if(tail[0]<head[0]){
   tail[0]+=1;
  }else if(tail[0]>head[0]){
   tail[0]-=1;
  }else if(tail[1]<head[1]){
   tail[1]+=1;
  }else if(tail[1]>head[1]){
   tail[1]-=1;
  }
 }
}

void generate_food(){
 int i=0,j=0;
 do{
  i=rand()%DOWN_EDGE;
 }while(i<UP_EDGE || i>DOWN_EDGE);

 do{
  j=rand()%DOWN_EDGE;
 }while(j<LEFT_EDGE || j>RIGHT_EDGE);
 food[0]=i;
 food[1]=j;
 gotoxy(food[0],food[1]);//抵达食物投放点
 putchar(FOOD);//放置食物
 gotoxy(cursor[0],cursor[1]);//返回光标当前位置
}

void eat_food(){
 if(tail[0]==turn_point[(tail_turn_num-1)%TURN_NUM][0] && tail[1]==turn_point[(tail_turn_num-1)%TURN_NUM][1]){
  tail_turn_num-=1;
 }
 snake[snake_length++]=snake[1];
 tail[0]=old_tail[0];
 tail[1]=old_tail[1];//将尾巴回退到上一步所在的位置
 gotoxy(tail[0],tail[1]);
 putchar(snake[1]);
 food_num++;
 score=food_num;
 gotoxy(cursor[0],cursor[1]);
}

用windows api 做的贪吃蛇 #include #include"resource.h" #include"Node.h" #include #include TCHAR szAppname[] = TEXT("Snack_eat"); #define SIDE (x_Client/80) #define x_Client 800 #define y_Client 800 #define X_MAX 800-20-SIDE //点x的范围 #define Y_MAX 800-60-SIDE //点y的范围 #define TIME_ID 1 #define SECOND 100 #define NUM_POINT 10 //点的总个数 #define ADD_SCORE 10 LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM); int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, PSTR szCmdLine, int iCmdShow) { HWND hwnd; //窗口句柄 MSG msg; //消息 WNDCLASS wndclass; //窗口类 HACCEL hAccel;//加速键句柄 wndclass.style = CS_HREDRAW | CS_VREDRAW; //窗口的水平和垂直尺寸被改变时,窗口被重绘 wndclass.lpfnWndProc = WndProc; //窗口过程为WndProc函数 wndclass.cbClsExtra = 0; //预留额外空间 wndclass.cbWndExtra = 0; //预留额外空间 wndclass.hInstance = hInstance; //应用程序的实例句柄,WinMain的第一个参数 wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION); //设置图标 wndclass.hCursor = LoadCursor(NULL, IDC_ARROW); //载入预定义的鼠标指针 wndclass.hbrBackground = (HBRUSH)GetStockObject(WHITE_BRUSH); //设置画刷 wndclass.lpszMenuName = szAppname; //设置菜单 wndclass.lpszClassName = szAppname; //设置窗口类的名字 if (!RegisterClass(&wndclass))//注册窗口类 { MessageBox(NULL, TEXT("这个程序需要windows NT!"), szAppname, MB_ICONERROR); return 0; } hwnd = CreateWindow(szAppname, TEXT("Snack_eat"),//CreateWindow函数调用时,WndProc将受到WM_CREATE WS_OVERLAPPEDWINDOW&~WS_THICKFRAME& ~WS_MAXIMIZEBOX,//普通的层叠窗口&禁止改变大小&禁止最大化 CW_USEDEFAULT, //初始x坐标(默认) CW_USEDEFAULT, //初始y坐标 x_Client, //初始x方向尺寸 770 y_Client, //初始y方向尺寸 750 NULL, //父窗口句柄 NULL, //窗口菜单句柄 hInstance, //程序实例句柄 WinMain函数第二个参数 NULL); //创建参数 ShowWindow(hwnd, iCmdShow);//显示窗口,iCmdShow是WinMain的第四个参数,决定窗口在屏幕的初始化显示形式,例:SW_SHOWNORMAL表示正常显示 UpdateWindow(hwnd);//使窗口客户区重绘,通过向WndProc发送一条WM_PAINT消息而完成的 hAccel = LoadAccelerators(hInstance, szAppname);//加载加速键 while (GetMessage(&msg, NULL, 0, 0)) { if (!TranslateAccelerator(hwnd, hAccel, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } }/* while (GetMessage(&msg, NULL, 0, 0))//GetMessage函数从消息队列得到消息,填充msg。如果msg.message等于WM_QUIT,返回0,否则返回非0 { TranslateMessage(&msg);//将msg返回给windows已进行某些键盘消息的转换 DispatchMessage(&msg);//将msg再次返回给windows }*/ return msg.wParam;//msg.wParam是PostQuitMessage函数的参数值,通常是0 } ...
评论 34
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值