c语言实现贪吃蛇


#include<conio.h>
#include<stdio.h>
#include<stdlib.h>
#include<time.h>
#include<windows.h>
#define R 24
#define H 24
#define W 48
#define UP 'w'  //上
#define DOWN 's'  //下
#define LEFT 'a'  //左
#define RIGHT 'd'  //右
void getfood();//产生食物 
void start();//初始界面 
void gameover();//游戏结束 
void play();//游戏过程 
void gotoxy(int ,int);//定位坐标 
void wall();//墙;
void gamerule();
void menu();//游戏菜单 
void chushihua();//初始化蛇 
void move();
void print();//打印蛇 
void HideCursor();//隐藏光标 
void turn(char );//改变方向 
void getfood();//随机获取食物 
void eatfood();//吃食物 
int die();//判断是否死亡 
struct Snake
 {
  int x[100];//x[0]表示蛇尾的横坐标 
  int y[100];//y[0]表示蛇尾的纵坐标
  int length;//蛇的长度 
  int speed;//蛇的速度 
  int count;//蛇吃的食物数量 
 }snake;
struct Food
{
 int x;
 int y;
}food;
 int i,j;
    int a[2];//a[1]储存蛇尾的纵坐标,a[0]储存蛇尾的横坐标 
void HideCursor()//隐藏光标
{
 CONSOLE_CURSOR_INFO cursor_info = {1, 0}; 
 SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}
void toxy(int x, int y)//将光标移动到X,Y坐标处
{
COORD pos = { x , y };
HANDLE Out = GetStdHandle(STD_OUTPUT_HANDLE);
SetConsoleCursorPosition(Out, pos); 
}
void start()//特效
{
 int x,y,i,j;
 system("color 72");
 for (i=0;i<10;i++)  
    {  
        x=i;  
        for (y=x;y<24-x;y++)  
        {  
            toxy(2*x,y);
            printf("0 ");  
        }  
        x=(23-i);  
        for (y=i;y<=x;y++)  
        {  
            toxy(2*x,y);
            printf("0 ");   
        }  
        x=i;  
        for (y=x;y<24-x;y++)  
        {  
            toxy(2*y,x);
            printf("0 ");  
        }  
        x=(23-i);  
        for (y=i;y<=x;y++)  
        {  
            toxy(2*y,x);
            printf("0 ");  
        }  
        Sleep(100);  
    }  
    for (i=0;i<10;i++)  
    {  
        x=i;  
        for (y=x;y<R-x;y++)  
        {  
            toxy(2*x,y);
            printf("  ");  
        }  
        x=(23-i);  
        for (y=i;y<=x;y++)  
        {  
            toxy(2*x,y);
            printf("  ");   
        }  
        x=i;  
        for (y=x;y<R-x;y++)  
        {  
            toxy(2*y,x);
            printf("  ");  
        }  
        x=(23-i);  
        for (y=i;y<=x;y++)  
        {  
            toxy(2*y,x);
            printf("  ");  
        }  
        Sleep(100);  
    }  
        
}
void wall()//边界
{
 system("color 74");
 system("cls");
 int i,j,map[H][W];
 for(i=0;i<H;i++)
 {
  for(j=0;j<W;j++)
  {
   if(i==0||i==H-1||j==0||j==W-1)
   {
    map[i][j]='0';
   }
   else
   {
    map[i][j]=' ';
   }
  }
 }
 for(i=0;i<H;i++)
 {
  for(j=0;j<W;j++)
  {
   //toxy(j,i);
   printf("%c",map[i][j]);
  }
  printf("\n");
 }
}
void menu()//菜单
{
 toxy(20,5);
 printf("贪吃蛇");
 toxy(19,7);
 printf("1.开始游戏");
 toxy(19,9);
 printf("2.游戏规则");
 toxy(19,11);
 printf("3.退出游戏");
 toxy(19,13);
 printf("By---Sriven");
}
void gamerule()
{
 system("cls");
 toxy(20,11);
 printf("游戏规则");
 start();
 system("cls");
 wall();
 toxy(1,1);
 printf("1.用w,s,a,d控制贪吃蛇的方向");
 toxy(1,3);
 printf("2.当贪吃蛇吃到食物后,\n贪吃蛇身子变长");
 toxy(1,5); 
 printf("3.如果贪吃蛇的头部碰到墙壁或者碰到自己的身体,\n则游戏结束");
 getch();
 toxy(20,11);
 printf("贪吃蛇");
 start();
}
void gameover()
{
 system("cls");
 system("color 71");
 wall();
 toxy(20,11);
 printf("BY-BY");
 start(); 
 exit(0);
 getch();
}
void chushihua()//初始化蛇 
{
 snake.length=3;
 snake.speed=500;
 snake.count=0; 
 snake.x[0]=8;
 snake.y[0]=10;
 for(i=1;i<snake.length;i++)
 {
  snake.x[i]=snake.x[i-1]+1;
  snake.y[i]=snake.y[i-1];
 }
}
void move()
{
 toxy(snake.x[0],snake.y[0]);
 printf(" ");
 for(i=1;i<snake.length;i++)//将蛇的前一节坐标赋给后一节 
 {
  snake.x[i-1]=snake.x[i];
  snake.y[i-1]=snake.y[i];
 }
 //snake.x[snake.length-1]=snake.x[snake.length-2]+2;
 //snake.y[snake.length-1]=snake.y[snake.length-2];
}
void print()//打印蛇 
{
 for(i=0;i<snake.length;i++)
 {
  toxy(snake.x[i],snake.y[i]);
  if(i==0)
  {
   printf("+");
  }
  else if(i==snake.length-1)
  {
   printf("+");
  }
  else
  {
   printf("+");
  }
 }
 system("color 71");
 toxy(50,11);
 printf("按0结束游戏");
 toxy(50,0);
 printf("分数:%d",10*snake.count);
 toxy(50,2);
 printf("当前速度为:%d",snake.speed);
 toxy(50,5);
 printf("1.用w,s,a,d控制贪吃蛇的方向");
 toxy(50,7);
 printf("2.当贪吃蛇吃到食物后,贪吃蛇身子变长,每吃5个食物,速度增加");
 toxy(50,9);
 printf("3.如果贪吃蛇的头部碰到墙壁或者碰到自己的身体,则游戏结束");
 toxy(60,15);
 printf("By---Sriven");
}
void turn(char direction )//获取方向 
{
 if(direction=='w')
 {
  snake.y[snake.length-1]--;
 }
 else if(direction=='s')
 {
  snake.y[snake.length-1]++;
 }
 else if(direction=='a')
 {
  snake.x[snake.length-1]-=1;
 }
 else if(direction=='d')
 {
  snake.x[snake.length-1]+=1;
 }
}
void getfood()
{
 //wall();
 srand(time(NULL));
 while(1)
 {
  food.x=rand()%44+2;
  food.y=rand()%21+2;
  for(i=0;i<snake.length;i++)
  {
   if(food.x==snake.x[i]&&food.y==snake.y[i])
   {
    break;
   }
  }
  if(i==snake.length)
  {
   toxy(food.x,food.y);
   printf("*");break;
  }
 }
}
void eatfood()
{
 if(food.x==snake.x[snake.length-1]&&food.y==snake.y[snake.length-1])
 {
  snake.length++;
  snake.count++;
  for(i=snake.length-1;i>=1;i--)
  {
   snake.x[i]=snake.x[i-1];
   snake.y[i]=snake.y[i-1];
  }
  snake.x[0]=a[0];
  snake.y[0]=a[1];
  if(snake.count%5==0)
  {
   if(snake.count>=40)
   {
    snake.speed=100;
   }
   else
   snake.speed-=50;
  }
     getfood();
 } 
}
int die()
{
 int flag=0;
 for(i=0;i<snake.length-1;i++)
 {
  if(snake.x[snake.length-1]==snake.x[i]&&snake.y[snake.length-1]==snake.y[i])
  {
   flag=1;
  }
 }
 if(snake.x[snake.length-1]==0||snake.x[snake.length-1]==W-1||snake.y[snake.length-1]==0||snake.y[snake.length-1]==H-1)
 {
  flag=1;
 }
 return(flag);
}
void play()
{
 toxy(20,11);
 printf("开始游戏");
 start();
 system("cls");
 char t='d';
 wall();
 chushihua(); 
 getfood();
 while(1)
 {
  a[0]=snake.x[0];
  a[1]=snake.y[0];
  if(kbhit())//判断是否有按键 
   {
    t=getch();
   }
   if(t=='0')break;
   move();
   turn(t);
   eatfood();
   print();
   if(die())
   {
    toxy(20,12);
    printf("Game over!");
    Sleep(2000);
    break;
   }
   Sleep(snake.speed);
   }
}
main()
{
 system("color 72");
 HideCursor();//隐藏光标 
 toxy(20,11);
 printf("贪吃蛇");
 start();
 system("color 70");
  
 do
 {
  system("cls");
  HideCursor();
  char n;
  wall();
  menu();
  n=getch();
  switch(n)
  {
   case '1':play();break;
   case '2':gamerule();break;
   case '3':gameover();break;
   default:printf("Please input 1~3:");break;
  }
 }while(1);//永远为真 
}


#define N 200<br>#include <graphics.h><br>#include <stdlib.h><br>#include <dos.h><br>#define LEFT 0x4b00<br>#define RIGHT 0x4d00<br>#define DOWN 0x5000<br>#define UP 0x4800<br>#define ESC 0x011b<br>int i,key;<br>int score=0;/*得分*/<br>int gamespeed=50000;/*游戏速度自己调整*/<br>struct Food<br>{<br> int x;/*食物的横坐标*/<br> int y;/*食物的纵坐标*/<br> int yes;/*判断是否要出现食物的变量*/<br>}food;/*食物的结构体*/<br>struct Snake<br>{<br> int x[N];<br> int y[N];<br> int node;/*蛇的节数*/<br> int direction;/*蛇移动方向*/<br> int life;/* 蛇的生命,0活着,1死亡*/<br>}snake;<br>void Init(void);/*图形驱动*/<br>void Close(void);/*图形结束*/<br>void DrawK(void);/*开始画面*/<br>void GameOver(void);/*结束游戏*/<br>void GamePlay(void);/*玩游戏具体过程*/<br>void PrScore(void);/*输出成绩*/<br>/*主函数*/<br>void main(void)<br>{<br> Init();/*图形驱动*/<br> DrawK();/*开始画面*/<br> GamePlay();/*玩游戏具体过程*/<br> Close();/*图形结束*/<br>}<br>/*图形驱动*/<br>void Init(void)<br>{<br> int gd=DETECT,gm;<br> initgraph(&gd,&gm,"c:\\tc");<br> cleardevice();<br>}<br>/*开始画面,左上角坐标为(50,40),右下角坐标为(610,460)的围墙*/<br>void DrawK(void)<br>{<br>/*setbkcolor(LIGHTGREEN);*/<br> setcolor(11);<br> setlinestyle(SOLID_LINE,0,THICK_WIDTH);/*设置线型*/<br> for(i=50;i<=600;i+=10)/*画围墙*/<br> {<br> rectangle(i,40,i+10,49); /*上边*/<br> rectangle(i,451,i+10,460);/*下边*/<br> }<br> for(i=40;i<=450;i+=10)<br> {<br> rectangle(50,i,59,i+10); /*左边*/<br> rectangle(601,i,610,i+10);/*右边*/<br> }<br>}<br>/*玩游戏具体过程*/<br>void GamePlay(void)<br>{<br> randomize();/*随机数发生器*/<br> food.yes=1;/*1表示需要出现新食物,0表示已经存在食物*/<br> snake.life=0;/*活着*/<br> snake.direction=1;/*方向往右*/<br> snake.x[0]=100;snake.y[0]=100;/*蛇头*/<br> snake.x[1]=110;snake.y[1]=100;<br> snake.node=2;/*节数*/<br> PrScore();/*输出得分*/<br> while(1)/*可以重复玩游戏,压ESC键结束*/<br> {<br> while(!kbhit())/*在没有按键的情况下,蛇自己移动身体*/<br> {<br> if(food.yes==1)/*需要出现新食物*/<br> {<br> food.x=rand()%400+60;<br> food.y=rand()%350+60;<br> while(food.x%10!=0)/*食物随机出现后必须让食物能够在整格内,这样才可以让蛇吃到*/<br> food.x++;<br> while(food.y%10!=0)<br> food.y++;<br> food.yes=0;/*画面上有食物了*/<br> }<br> if(food.yes==0)/*画面上有食物了就要显示*/<br> {<br> setcolor(GREEN);<br> rectangle(food.x,food.y,food.x+10,food.y-10);<br> }<br> for(i=snake.node-1;i>0;i--)/*蛇的每个环节往前移动,也就是贪吃蛇的关键算法*/<br> {<br> snake.x[i]=snake.x[i-1];<br> snake.y[i]=snake.y[i-1];<br> }<br> /*1,2,3,4表示右,左,上,下四个方向,通过这个判断来移动蛇头*/<br> switch(snake.direction)<br> {<br> case 1:snake.x[0]+=10;break;<br> case 2: snake.x[0]-=10;break;<br> case 3: snake.y[0]-=10;break;<br> case 4: snake.y[0]+=10;break;<br> }<br> for(i=3;i<snake.node;i++)/*从蛇的第四节开始判断是否撞到自己了,因为蛇头为两节,第三节不可能拐过来*/<br> {<br> if(snake.x[i]==snake.x[0]&&snake.y[i]==snake.y[0])<br> {<br> GameOver();/*显示失败*/<br> snake.life=1;<br> break;<br> }<br> }<br> if(snake.x[0]<55||snake.x[0]>595||snake.y[0]<55||<br> snake.y[0]>455)/*蛇是否撞到墙壁*/<br> {<br> GameOver();/*本次游戏结束*/<br> snake.life=1; /*蛇死*/<br> }<br> if(snake.life==1)/*以上两种判断以后,如果蛇死就跳出内循环,重新开始*/<br> break;<br> if(snake.x[0]==food.x&&snake.y[0]==food.y)/*吃到食物以后*/<br> {<br> setcolor(0);/*把画面上的食物东西去掉*/<br> rectangle(food.x,food.y,food.x+10,food.y-10);<br> snake.x[snake.node]=-20;snake.y[snake.node]=-20;<br> /*新的一节先放在看不见的位置,下次循环就取前一节的位置*/<br> snake.node++;/*蛇的身体长一节*/<br> food.yes=1;/*画面上需要出现新的食物*/<br> score+=10;<br> PrScore();/*输出新得分*/<br> }<br> setcolor(4);/*画出蛇*/<br> for(i=0;i<snake.node;i++)<br> rectangle(snake.x[i],snake.y[i],snake.x[i]+10,<br> snake.y[i]-10);<br> delay(gamespeed);<br> setcolor(0);/*用黑色去除蛇的的最后一节*/<br> rectangle(snake.x[snake.node-1],snake.y[snake.node-1],<br> snake.x[snake.node-1]+10,snake.y[snake.node-1]-10);<br> } /*endwhile(!kbhit)*/<br> if(snake.life==1)/*如果蛇死就跳出循环*/<br> break;<br> key=bioskey(0);/*接收按键*/<br> if(key==ESC)/*按ESC键退出*/<br> break;<br> else<br> if(key==UP&&snake.direction!=4)<br>/*判断是否往相反的方向移动*/<br> snake.direction=3;<br> else<br> if(key==RIGHT&&snake.direction!=2)<br> snake.direction=1;<br> else<br> if(key==LEFT&&snake.direction!=1)<br> snake.direction=2;<br> else<br> if(key==DOWN&&snake.direction!=3)<br> snake.direction=4;<br> }/*endwhile(1)*/<br>}<br>/*游戏结束*/<br>void GameOver(void)<br>{<br> cleardevice(); <br> PrScore();<br> setcolor(RED);<br> settextstyle(0,0,4);<br> outtextxy(200,200,"GAME OVER");<br> getch();<br>}<br>/*输出成绩*/<br>void PrScore(void)<br>{ <br> char str[10];<br> setfillstyle(SOLID_FILL,YELLOW);<br> bar(50,15,220,35);<br> setcolor(6);<br> settextstyle(0,0,2);<br> sprintf(str,"score:%d",score);<br> outtextxy(55,20,str);<br>}<br>/*图形结束*/<br>void Close(void)<br>{ <br> getch();<br> closegraph();<br>}<br>
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值