贪吃蛇 第二个C游戏

TC下运行



#include <graphics.h>  

#include <stdlib.h>  #include <stdio.h>  #include<math.h>  #include<dos.h>  #include<alloc.h> 

#define K 10     /* 边框一格的长度 */ #define up 0x4800    /* 下面是定义各个键盘扫描码的宏 用bioskey捕获按键值实现 */ #define down 0x5000  #define left 0x4b00  #define right 0x4d00  #define esc 0x011b  #define Y 0x1579  #define n 0x316e  #define speed 0x1f73  /* 这个是为了调式方便设的调速度用的,即s键的键盘扫描码的*/   typedef struct node  /* 转弯点 */  {      int d;   /* 方向 */      int x;   /* 坐标 */      int y;      struct node *next; /* 下一个转弯点 */  }QueueNode;  typedef struct queue  /* 转向队列 */ {      QueueNode *front;  /* 尾方向节点 */     QueueNode *rear;   /* 头方向节点*/ }LinkQueue;  struct snake  /* 蛇链 */ {      int x1;  /* 蛇头坐标 */      int y1;      int x2;  /* 蛇尾坐标 */      int y2;      int node; /* 蛇长 节点数*/      LinkQueue direction;/* 节点方向 */      int life; /* 生命 是否死亡 */  }snake;  typedef QueueNode  *link;    int x0,y0,k,s,t,max_score;/* x0,y0 随机食物坐标,k控制产生食物,s控制速度,t防止吃到食物没产生新食物之前被打断,max_score保存最高记录 */     /* 点阵字体 是用工具生成,可以略过……*/  char tan48H[]={  0x00,0xE0,0x00,0x00,0x00,0x00,  0x01,0xF0,0x00,0x00,0x00,0x00,  0x03,0x98,0x00,0x00,0x00,0x00,  0x07,0x0C,0x00,0x00,0x00,0x00,  0x0E,0x67,0x00,0x00,0x00,0x00,  0x7C,0x63,0xE0,0x00,0x00,0x00,  0x77,0xFC,0xE0,0x00,0x00,0x00,  0x07,0xFC,0x00,0x00,0x00,0x00,    0x00,0x18,0x00,0x00,0x00,0x00,  0x0F,0xFF,0x00,0x00,0x00,0x00,  0x0F,0xFF,0x00,0x00,0x00,0x00,  0x0C,0x03,0x00,0x00,0x00,0x00,    0x0C,0x63,0x00,0x00,0x00,0x00,  0x0C,0xE3,0x00,0x00,0x00,0x00,  0x0D,0xDB,0x00,0x00,0x00,0x00,  0x03,0x9E,0x00,0x00,0x00,0x00,    0x1F,0x0F,0x80,0x00,0x00,0x00,  0x1E,0x03,0x80,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00  };  char chi48H[]={  0x00,0x18,0x00,0x00,0x00,0x00,  0x00,0x18,0x00,0x00,0x00,0x00,  0x3F,0x18,0x00,0x00,0x00,0x00,  0x3F,0x3F,0xE0,0x00,0x00,0x00,    0x33,0x3F,0xE0,0x00,0x00,0x00,  0x33,0x60,0x00,0x00,0x00,0x00,  0x33,0xC0,0x00,0x00,0x00,0x00,  0x33,0xBF,0x80,0x00,0x00,0x00,    0x33,0x3F,0x80,0x00,0x00,0x00,  0x33,0x06,0x00,0x00,0x00,0x00,  0x33,0x0C,0x00,0x00,0x00,0x00,  0x3F,0x18,0x00,0x00,0x00,0x00,    0x3F,0x30,0x00,0x00,0x00,0x00,  0x33,0x60,0x00,0x00,0x00,0x00,  0x33,0x60,0x60,0x00,0x00,0x00,  0x30,0x60,0x60,0x00,0x00,0x00,    0x00,0x3F,0xE0,0x00,0x00,0x00,  0x00,0x1F,0xC0,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00  };  char she48H[]={  0x0C,0x0C,0x00,0x00,0x00,0x00,  0x0C,0x0E,0x00,0x00,0x00,0x00,  0x0C,0x06,0x00,0x00,0x00,0x00,  0x0C,0x7F,0xE0,0x00,0x00,0x00,    0x7F,0xFF,0xE0,0x00,0x00,0x00,  0x7F,0xE0,0x60,0x00,0x00,0x00,  0x6D,0xE0,0x60,0x00,0x00,0x00,  0x6D,0x8C,0x00,0x00,0x00,0x00,    0x6D,0x8C,0x00,0x00,0x00,0x00,  0x7F,0x8C,0xC0,0x00,0x00,0x00,  0x7F,0x8F,0xC0,0x00,0x00,0x00,  0x6D,0x8F,0x00,0x00,0x00,0x00,    0x6C,0x0C,0x00,0x00,0x00,0x00,  0x0D,0x8C,0x00,0x00,0x00,0x00,  0x0F,0xCC,0x60,0x00,0x00,0x00,  0x7F,0xCC,0x60,0x00,0x00,0x00,    0x78,0xCF,0xE0,0x00,0x00,0x00,  0x00,0x07,0xC0,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,    0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00,  0x00,0x00,0x00,0x00,0x00,0x00  };    char zuo16H[]={    0x18,0xC0,0x18,0xC0,0x19,0x80,0x31,0xFE,    0x33,0xFE,0x76,0xC0,0xF0,0xFC,0xB0,0xFC,    0x30,0xC0,0x30,0xC0,0x30,0xFE,0x30,0xFE,    0x30,0xC0,0x30,0xC0,0x30,0xC0,0x00,0x00,  };  char zhe16H[]={    0x03,0x00,0x03,0x0C,0x1F,0xCC,0x1F,0xD8,    0x03,0x30,0xFF,0xFE,0xFF,0xFE,0x03,0x00,    0x0F,0xF8,0x3F,0xF8,0xEC,0x18,0xCF,0xF8,    0x0C,0x18,0x0F,0xF8,0x0F,0xF8,0x00,0x00,  };  char mh16H[]={  0x00,0x00,  0x00,0x00,  0x00,0x00,  0x00,0x00,    0x00,0x00,  0x00,0x00,  0x00,0x00,  0x00,0x00,    0x30,0x00,  0x30,0x00,  0x00,0x00,  0x00,0x00,    0x30,0x00,  0x30,0x00,  0x00,0x00,  0x00,0x00  };    char zhao16H[]={  0x0C,0x00,  0x0C,0x0C,  0x7F,0x8C,  0x7F,0xCC,    0x0C,0x6C,  0x0C,0x38,  0xFF,0x98,  0xFF,0xB8,    0x0C,0x38,  0x6F,0x6C,  0x6F,0xCC,  0x7C,0x84,    0x7C,0x00,  0xCF,0xFE,  0x87,0xFE,  0x00,0x00  };  char peng16H[]={  0x00,0x30,  0x77,0x7C,  0x77,0x7C,  0x55,0x64,    0x55,0x7C,  0x77,0x64,  0x55,0x6C,  0x55,0x60,    0x77,0x7E,  0x77,0x7E,  0x55,0x06,  0x55,0x76,    0x55,0x06,  0xD5,0x1E,  0xAB,0x0C,  0x00,0x00  };    /* 链队操作 */  void Initial(LinkQueue *Q)  {         Q->front=Q->rear=NULL;  }   int IsEmpty(LinkQueue *Q)  {      return Q->front==NULL&&Q->rear==NULL;  }  void Push(LinkQueue *Q,int direction,int x1,int y1)  {      QueueNode *p=(QueueNode *)malloc(sizeof(QueueNode));/*申请新结点*/      p->d=direction;      p->x=x1;      p->y=y1;      p->next=NULL;      if(IsEmpty(Q))          Q->front=Q->rear=p;   /*将x插入空队列*/      else       {                           /*x插入非空队列的尾*/          Q->rear->next=p;      /*p链到原队尾结点后*/          Q->rear=p;               /*队尾指针指向新的尾*/      }  }  void Pop(LinkQueue *Q)  {      QueueNode *p;      if(IsEmpty(Q))      {          printf("队列为空");/*下溢*/          exit(1);      }      p=Q->front;          /*指向对头结点*/      Q->front=p->next;    /*将对头结点从链上摘下*/      if(Q->rear==p)       /*原队中只有一个结点,删去后队列变空,此时队头指针已为空*/          Q->rear=NULL;      free(p);             /*释放被删队头结点*/  }    /* 图形与数据初始化 */  void init(void)  {      int gdriver = DETECT, gmode, errorcode;       initgraph(&gdriver, &gmode,"" );     errorcode = graphresult();      if (errorcode != grOk)      {          printf("Graphics error: %s",grapherrormsg(errorcode));          printf("\nPress any key to halt:");    getch();    exit(1);      }   s=5,k=0,t=0,max_score=2;     snake.x1=25*K;      snake.y1=25*K;      snake.x2=23*K;      snake.y2=25*K;      snake.node=2;      snake.life=1;      Initial(&snake.direction);      Push(&snake.direction,0,snake.x1,snake.y1);  }  /* 点阵字体输出算法 */  void draw_mat(char *mat,int matsize,int x,int y,int color) /*显示点阵字体 */  {       int i,j,k,m;       m=(matsize-1)/8+1;       for(j=0;j<matsize;j++)            for(i=0;i<m;i++)                 for(k=0;k<8;k++)                      if(mat[j*m+i]&(0x80>>k))                           putpixel(x+i*8+k,y+j,color);  }  /* 画边框 */  void draw_frame()  {      int i;      setcolor(3);      rectangle(K,4*K,63*K,46*K);  /* 先画两个大框框 */     rectangle(2*K,5*K,62*K,45*K);      for(i=2;i<=62;i++)     /* 在两框中画线 */     {          line(i*K,4*K,i*K,5*K);          line(i*K,45*K,i*K,46*K);          if(i<45)          {              line(K,(i+2)*K,2*K,(i+2)*K);              line(62*K,(i+2)*K,63*K,(i+2)*K);          }      }      }  /* 调用汉字点阵输出程序,显示标题和作者信息 */  void show_word(void)  {       draw_mat(tan48H,48,229,5,7);       draw_mat(chi48H,48,309,5,7);       draw_mat(she48H,48,389,5,7);         draw_mat(tan48H,48,230,4,4);       draw_mat(chi48H,48,310,4,4);       draw_mat(she48H,48,390,4,4);         draw_mat(zuo16H,16,500,465,15);       draw_mat(zhe16H,16,518,465,15);       draw_mat(mh16H,16,536,465,15);              draw_mat(zhao16H,16,550,465,15);       draw_mat(peng16H,16,572,465,15);  }  /* 显示分数 */  void show_score(void)  {       char str[10];       sprintf(str,"score:%d",snake.node);      /* 显示分数 */   bar(10,5,180,35);       setcolor(14);       settextstyle(0,0,2);          outtextxy(20,12,str);   setcolor(15); }  /* 画蛇节 */  void _rectangle(int x,int y)  {      rectangle(x-4,y-4,x+4,y+4);  }  /* 记录最高分 */  void record()  {      FILE *fp;         char str[20];      if((fp=fopen("RECORD.FIL","r"))==NULL)  /* 如果是第一次打开,就执行里面的建立保存最高记录文件 */     {                    if((fp=fopen("RECORD.FIL","w"))!=NULL)              fprintf(fp,"%3d",max_score);  /* 读默认的最大值2  */         fclose(fp);           }      else      {                 fscanf(fp,"%3d",&max_score);          fclose(fp);          if(max_score<snake.node)  /* 读出保存的最高记录和现在结束时的记录 进行比较 更大的话,就重新覆盖写入文件 */         {              if((fp=fopen("RECORD.FIL","w"))!=NULL)                  fprintf(fp,"%3d",snake.node);                 fclose(fp);          }             }  sprintf(str,"record:%d",max_score);      setfillstyle(1,3);  /* 下面是用来游戏开始时显示最高记录用的 */     bar(getmaxx()-170,5,getmaxx()-10,35);      setcolor(4);      settextstyle(0,0,2);      outtextxy(getmaxx()-170,12,str);  setcolor(15);          /* 提示信息 */     settextstyle(0,0,0);      outtextxy(10,470,"UP     LEFT     RIGHT     DOWN     ESC     S(Speed:1~7)");  } /* 遍历查找是否有相同坐标元素 */  int search(int x,int y)  /* 这里x,y为产生食物坐标,或蛇头坐标,即都是x,y不能在蛇身上 */ {      int i,j;      link p,q;      p=snake.direction.front;      q=snake.direction.rear;  /* 下面的两个if是为了遍历蛇头到第一个节点所有蛇身上的坐标元素 */  switch(p->d) /* 先把现在尾坐标最后一个方向坐标,因为,最后个尾坐标是移动的,最后一个结点方向应该总是跟尾坐标一至,从倒数第二个开始算起 */  {   case 0:p->x=snake.x2+K;p->y=snake.y2;break;   case 1:p->x=snake.x2-K;p->y=snake.y2;break;   case 2:p->x=snake.x2;p->y=snake.y2-K;break;   case 3:p->x=snake.x2;p->y=snake.y2+K;break;  }          if(snake.x1==q->x)  /* 如果蛇头x坐标写第一个方向结点x坐标相同,说明蛇是上下移动的,只要变更y坐标就可以……*/     {          i=snake.y1<q->y?snake.y1:q->y;  /* 把头和第一个方向节点中更小值赋给i */         j=snake.y1>q->y?snake.y1:q->y;  /* 把更大的赋给j ……*/         for(;i<j;i+=K)              if(x==q->x&&y==i+1)                  return 1;       }      if(snake.y1==q->y)      {          i=snake.x1<q->x?snake.x1:q->x;          j=snake.x1>q->x?snake.x1:q->x;          for(;i<j;i+=K)               if(x==i+1&&y==q->y)                   return 1;      }      for(;p!=NULL;p=p->next)/* 是为了遍历第一个节点到尾结点的所有蛇上坐标元素 */     {                 if(p->x==p->next->x)          {              i=p->y<p->next->y?p->y:p->next->y;              j=p->y>p->next->y?p->y:p->next->y;              for(;i<=j;i+=K)                  if(x==p->x&&y==i)                                         return 1;                            }          if(p->y==p->next->y)          {                         i=p->x<p->next->x?p->x:p->next->x;              j=p->x>p->next->x?p->x:p->next->x;              for(;i<=j;i+=K)                                 if(x==i&&y==p->y)                      return 1;           }      }      return 0;  }    /* 判断蛇是否死亡 游戏是否结束 */  void game_over_(void)  {      int i;        if(snake.x1>61*K||snake.x1<3*K||snake.y1>44*K||snake.y1<6*K)  /* 判断是否超出边界 */         snake.life=0;      i=search(snake.x1,snake.y1);  /* 看蛇头是否移移到蛇身上去了,到了的话,说明咬到自己了,结束*/     if(i==1)          snake.life=0;  }  /* 蛇移动 随机生成食物 */  int move(int *x,int r)  {      int i=0,j=0;      if(r==0||r==2)  /* 如何移动 ,这里的r表示方向,0,1是用来控制蛇头,2,3是用来控制蛇尾 */          *x+=K;      if(r==1||r==3)          *x-=K;        if(k==0)  /* k为0说明食物被吃了,或没有食物,产生食物 */      {          i=1;    /* 控制蛇尾暂停用的 */         k=1;    /* 控制产生食物,产生食物没吃到前是1,吃到后置0*/   t=0;  /* 蛇完成一步移动,即允许方向键控制*/         randomize();          while(1)  /* 随机产生食物 */         {                                 x0=(random(58)+3)*K;              y0=(random(38)+6)*K;              j=search(x0,y0);  /* 产生食物不能在蛇上 */             if(j==0)                  break;          }                 _rectangle(x0,y0);          show_score();      /* 产生了食物,说明已经吃到了食物,得加分,更新分数 */     }             if(snake.x1==x0&&snake.y1==y0)/* 吃到食物增加长度 即尾部暂停移动一步,根据方向来操作首尾的x,y的值 */      {          k=0;   /* 吃到食物k置0*/         snake.node+=1;                _rectangle(snake.x1,snake.y1);            if(snake.direction.front->d==0)              snake.x2-=K;         if(snake.direction.front->d==1)              snake.x2+=K;         if(snake.direction.front->d==2)              snake.y2+=K;         if(snake.direction.front->d==3)              snake.y2-=K;     }      if(r==0||r==1)  /* 0,1是表示蛇头,下面即是蛇头向前移动一格,画出,再判断是否结束了 具体看结束函数 */     {          t=1; /* 蛇未完成一步移动,即不允许方向键控制*/   game_over_();   _rectangle(snake.x1,snake.y1);      }      if((r==2||r==3)&&i==0)  /* 如果i==0,说明吃到食物,暂停一下 */     {    t=0; /* 蛇完成一步移动,即允许方向键控制*/   /* 蛇的最后个节点的x,y如果与蛇尾的下一个转弯点的x,y坐标相同的,且蛇不是只有一个转弯点时(即蛇不是一条直线时),就销毁最后个个转弯节点*/         if(snake.direction.front->next->x==snake.x2&&snake.direction.front->next->y==snake.y2&&snake.direction.front!=snake.direction.rear)             Pop(&snake.direction);          /* 蛇尾转向 销毁队列头元素 */          _rectangle(snake.x2,snake.y2);          for(j=1;j<=s;j++)              delay(5000);    /* 延时用的,能过改s的值可以控制速度 */     }      return 0;        }  /* 是否退出 */ void exit_(int x) {  int key;  while(1)  {    key=bioskey(0);    if(key==Y||key==n)   break;  }    if(x==key)  {   record();   exit(1);  } } /* 游戏操作 */  void game_play()  {      int key,q=0,i;  /* key用来保存捕获键值,q用来控制是否结束程序,0为不结束,i用来保证你按方向键之前,蛇有移动过,不然这个点上可能有好几个方向值了,但我们要的是一个点最多只能保存一个方向值*/     setcolor(15);             _rectangle(snake.x2+K,snake.y2);  /* 画出开始的头两节蛇节 */     _rectangle(snake.x2+2*K,snake.y2);      while(1)      {          i=1; /* 每次按方向键后,最少移动一次后才能允许方向键控制 */          while(!(kbhit()&&t!=1||snake.life!=1))  /* 检查是否按键,没按一直循环,按了的话就跳出循环 且蛇未完成一步移动,不允许按键控制*/         {        if(snake.direction.rear->d==0)move(&snake.x1,0); /* 头右移 */              if(snake.direction.rear->d==1)move(&snake.x1,1); /* 头左移 */              if(snake.direction.rear->d==2)move(&snake.y1,1); /* 头上移 */              if(snake.direction.rear->d==3)move(&snake.y1,0); /* 头下移 */             if(snake.direction.front->d==0){i=move(&snake.x2,2);continue;} /* 尾右移 ,返回i(0)说明移动过,才可以执行转向操作,下同*/              if(snake.direction.front->d==1){i=move(&snake.x2,3);continue;} /* 尾左移 */               if(snake.direction.front->d==2){i=move(&snake.y2,3);continue;} /* 尾上移 */               if(snake.direction.front->d==3){i=move(&snake.y2,2);continue;} /* 尾下移 */                    }                 if(snake.life==1) /* 蛇没死 */          {              key=bioskey(0);              switch(key) /* 键盘控制蛇移动 */     {      case right:       if(snake.direction.rear->d!=1&&snake.direction.rear->d!=0&&i==0)/* 不能反向或按原方向移动,i控制每一次按方向键 之前必须至少移动一次 */        Push(&snake.direction,0,snake.x1,snake.y1);    /* 按方向键则将按方向键时的头节点推入方向队列中 下同 */      break;      case left:       if(snake.direction.rear->d!=1&&snake.direction.rear->d!=0&&i==0)        Push(&snake.direction,1,snake.x1,snake.y1);       break;      case up:       if(snake.direction.rear->d!=2&&snake.direction.rear->d!=3&&i==0)        Push(&snake.direction,2,snake.x1,snake.y1);       break;      case down:       if(snake.direction.rear->d!=2&&snake.direction.rear->d!=3&&i==0)        Push(&snake.direction,3,snake.x1,snake.y1);       break;      case speed:  /* 调速用的,按s就可以蛇会停下来,进入调速模式,可调1-5的值*/      while(1)       {         int ss=0;       switch(getch())       {        case '1':s=7;ss=1;break;        case '2':s=6;ss=1; break;        case '3':s=5;ss=1; break;        case '4':s=4;ss=1; break;        case '5':s=3;ss=1; break;        case '6':s=2;ss=1; break;        case '7':s=1;ss=1; break;       }       if(ss==1)        break;      }       sleep(1);       break;      case esc:       q=1;  /* 控制是否退出用的 */      break;     }         }         if(snake.life==0) /* 游戏结束,是否继续? */          {              setcolor(4);              settextstyle(0,0,2);              settextjustify(1,1);              outtextxy(getmaxx()/2,getmaxy()/2,"GAME OVER!");              setcolor(15);              settextstyle(0,0,0);              outtextxy(getmaxx()/2-5,getmaxy()/2+35,"CONTINUE ?(Y/N)");                        exit_(n);  /* 按n退出 */    record();             break;          }         if(q==1)   /* 退出否 并显示提示信息 */          {              setcolor(15);    settextstyle(0,0,0);             settextjustify(1,1);              outtextxy(getmaxx()/2,getmaxy()/2+35,"QUIT ?(Y/N)");              exit_(Y);    /* 按y退出 */    q=0;     /* 不退出重新初始化 */             setcolor(0);    settextstyle(0,0,0);             outtextxy(getmaxx()/2,getmaxy()/2+35,"QUIT ?(Y/N)");              setcolor(15);                     }                             }     }    void main(void)  {      int errorcode;  errorcode=registerbgidriver(EGAVGA_driver);      if(errorcode<0)     {         printf("Graphics error: %s", grapherrormsg(errorcode));         printf("Press any key to halt:");         getch();         exit(1);     }  while(1)      {          init();               draw_frame();    /* 画边框 */         show_word();    /* 显示中文信息 */         record();     /* 显示最高记录 */         setwritemode(1);   /* 设置成异或画图模式,即一个图形,你画一次显示,再在同一位置,再画一次就异或掉,就很从没画过一样 */         game_play();        /* 进行游戏 */   cleardevice();  /* 清除屏幕显示 */     }      closegraph();  }

  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
前言 Java最初被命名为Oak,目标设定在家用电器等小型系统的编程语言,来解决诸如电 视机、、闹钟、烤面包机等家用电器的控制和通讯问题。由于这些智能化家电的市场需 求没有预期的高,Sun放弃了该项计划。就在Oak几近失败之时,随着互联网的发展,Su n看到了Oak在计算机网络上的广阔应用前景。于是改造了Oak,以"Java"的名称正式发布 。   Java 编程语言的风格十分接近C、C++语言。Java是一个纯的面向对象的程序设计语言,它继 承了 C++ 语言面向对象技术的核心。Java舍弃了C ++语言中容易引起错误的指针(以引用取代)、运算符重载(operator overloading)、多重继承(以接口取代)等特性,增加了垃圾回收器功能用于回收不再 被引用的对象所占据的存空间,使得程序员不用再为存管理而担忧。在 Java SE 1.5 版本中,Java 又引入了泛型编程(Generic Programming)、类型安全的枚举、不定长参数和自动装/拆箱等语言特性。   Java 不同于一般的编译执行计算机语言和解释执行计算机语言。它首先将源代码编译成二进 制字节码(bytecode),然后依赖各种不同平台上的虚拟机来解释执行字节码。从而实 现了"一次编译、到处执行"的跨平台特性。不过,每次的编译执行需要消耗一定的时间 ,这同时也在一定程度上降低了 Java 程序的运行效率。但在 J2SE 1.4.2 发布后,Java 的执行速度有了大幅提升。   与传统程序不同,Sun 公司在推出 Java 之际就将其作为一种开放的技术。全球数以万计的 Java 开发公司被要求所设计的 Java 软件必须相互兼容。"Java 语言靠群体的力量而非公司的力量"是 Sun 公司的口号之一,并获得了广大软件开发商的认同。这与微软公司所倡导的注重精英和 封闭式的模式完全不同。   Sun 公司对 Java 编程语言的解释是:Java 编程语言是个简单、面向对象、分布式、解释性、健壮、安全与系统无关、可移植、高 性能、多线程和动态的语言。 正文 1.1课程设计目的 《JAVA程序设计》是计算机相关专业的必修专业基础课程,其实践性、应用性很强。实 践教学环节是必不可少的一个重要环节。本课程的程序设计专题实际是计算机相关专业 学生学习完《JAVA程序设计》课程后,进行的一次全面的综合训练,JAVA程序设计的设计 目的是加深对理论教学容的理解和掌握,使学生较系统地掌握程序设计及其在网络开发 中的广泛应用,基本方法及技巧,为学生综合运用所学知识,利用软件工程为基础进行 软件开发、并在实践应用方面打下一定基础。 2.1工程概况 2.1.1案例提出及工程用时 经过两天在图书馆以及网络上查阅的资料,然后提出这次课程设计的目标《贪吃蛇游 戏》的设计。然后接下来就是查阅更多的资料,制定接下来的详细计划,最终计划用两周 的时间完成此次课程设计提出的案例。 2.1.2开发环境 硬件环境: CPU:Intel Pentium(R)4 主频:2.40GHz 存:256MB 软件环境: 操作系统:Windows *P 编程环境: JDK 1.6 开发工具:Eclipse jdk 3.1设计方案论证 3.1.1设计思路 贪吃蛇游戏设计与实现,主要分为以下二个模块:游戏主界面模块和游戏控制模块。 在此只实现游戏游戏主界面模块、游戏控制模块。并且只是实现移动速度、暂停、重 新开始等功能。 游戏主界面模块: 游戏的主界面是进入游戏后,能够给玩家第一感官的部分,主要包括游戏图形区域界 面、游戏的速度选择更新界面、新生方块的预览、暂停游戏按钮、重新开始游戏按钮。 从很大程度上决定了玩家对游戏的兴趣问题,因此,游戏的主界面应该力求美观,爽心 悦目。 游戏控制模块: 这个模块是游戏的中心环节,主要完成控制游戏的开始、暂停、重新开始等功能。为 了能够给玩家一个很好的游戏环境,这部分应该做到易懂、易操作。 本设计所开发的是基于Java的一个贪吃蛇游戏软件,主要实现游戏的速度控制、游戏 的暂停、游戏的退出等功能,分为: 游戏主界面模块、游戏控制模块以二个模块。 3.1.2程序概述 本程序是一个利用Java应用软件制作的贪食游戏。在游戏过程中,用户通过点击 小键盘区的方向键来控制的运行方向;游戏运行过程中,如果想暂停,只需要按F3键 即可。重新开始游戏的按键为F2。当没有吃到食物且碰到墙壁或自己的身体时游戏结 束。 本程序的另一个功能是在程序运行窗口的左上角显示,用户在游戏过程中的移动和长 度。 3.1.3程序流程图 本次游戏设计的处理流程如图1所示。 3.1.4 总设计模块的划分 根据游戏需求中游戏所要实现的功能,整个游戏分为二个模块进行具体的设计,如图 2所示。 游戏控制模块的主
用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 } ...

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值