当前位置导航:炫浪网>>网络学院>>编程开发>>C++教程>>C++进阶与实例

利用C++实现的贪吃蛇游戏

  在tc 3.0下调试通过,因为tc 3.0不支持bool 类型,所以程序中自定义了个枚举类型变量bool
  如果在vc或者bc中运行,可以把这个bool类型注释掉.
  贪吃蛇的核心算法时如何实现移动和吃掉食物.
  没有碰到食物的时候,把当前运动方向上的下个节点入队,并以蛇节点的颜色重绘这个节点.
  然后把头指针所指的节点出队,并以游戏框架内部背景色重绘出队的节点,这样就可以达到移动的效果.
  而在吃到食物的时候,则只需把食物入队即可.
   // greedsnake.cpp
  #include <bios.h>
  #include <conio.h>
  #include <dos.h>
  #include <graphics.h>
  #include <stdlib.h>
  #include <time.h>
  #include "conf.h"
  typedef struct node
  {
  int x,y;
  struct node *next;
  }Node;

  typedef struct
  {
  Node *head,*tail;
  int length;
  }Snake;
  typedef struct
  {
  int left,top,right,bottom;
  }Frame;

  typedef enum                    //四个方向
  {
  up,down,left,right
  }Direction;
  typedef enum
  {
  false,true
  }bool;

  void InitGraphMode();                     //初始化图形驱动
  void CloseGraphMode();
  void Foot(int,int);
  void Head(int,int);
  void CreateFrame();                    //完成整个游戏框架的绘制
  void CreateSnake();                    //创建一条两个节点的蛇,蛇的每一节是队列中的一个节点
  bool PlayGame();                        //游戏的主体函数,
  int Hit(int,int);                               //判断是否越界,或者撞到自身,两个参数分别是新的头接点的x,y坐标
  bool GameOver();                        //绘制游戏结束时弹出的对话框
  void Enqueue(Node);                    //入队函数
  Node Dequeue();                        //出队函数
  void ClearKeyBuf();                       //清除键盘缓冲,此函数可以消除不停的按无效键的影响

   Snake snake;
  Frame frame;
  void main()
  {
  InitGraphMode();
  do
  {
  CreateFrame();
  }while(PlayGame());
  CloseGraphMode();
  }
  void InitGraphMode()
  {
  int gdriver=DETECT,gmode;
  initgraph(&gdriver,&gmode,"../bgi/");
  cleardevice();
  }
  void CloseGraphMode()
  {
  cleardevice();
  closegraph();
  }
  void CreateFrame()
  {
  setbkcolor(CYAN);
  //下面的四行代码用于计算主框架的左上角和右下角的坐标
  frame.left=(getmaxx()+1-BlockWidth*RowOfFrame)/2;
  frame.top=(getmaxy()+1-BlockHeight*ColumnOfFrame)/2;
  frame.right=frame.left+BlockWidth*RowOfFrame;
  frame.bottom=frame.top+BlockHeight*ColumnOfFrame;
  Head(frame.left+100,frame.top-20);
  setfillstyle(SOLID_FILL,LIGHTGRAY);
  bar(frame.left,frame.top,frame.right,frame.bottom);
  setlinestyle(SOLID_LINE,1,1);
  setcolor(DARKGRAY);
  line(frame.left,frame.top,frame.right,frame.top);
  line(frame.left,frame.top,frame.left,frame.bottom);
  setlinestyle(SOLID_LINE,1,1);
  setcolor(WHITE);
  line(frame.left,frame.bottom,frame.right,frame.bottom);
  line(frame.right,frame.top,frame.right,frame.bottom);
  setlinestyle(DOTTED_LINE,1,1);
  setcolor(BLUE);
  for(int row=1;row<RowOfFrame;row++)
  line(frame.left+row*BlockWidth,frame.top,frame.left+row*BlockWidth,frame.bottom);
  for(int column=1;column<ColumnOfFrame;column++)
  line(frame.left,frame.top+column*BlockHeight,frame.right,frame.top+column*BlockHeight);
  Foot(frame.left,frame.bottom+20);
  }

   void CreateSnake()
  {
  Node *node1=new Node;
  Node *node2=new Node;
  node1->x=frame.left+BlockWidth;
  node1->y=frame.top;
  node1->next=NULL;
  snake.tail=node1;
  node2->x=frame.left;
  node2->y=frame.top;
  node2->next=snake.tail;
  snake.head=node2;
  snake.length=2;
  setfillstyle(SOLID_FILL,BLUE);
  bar(snake.head->x+1,snake.head->y+1,snake.head->x+BlockWidth-1,snake.head->y+BlockHeight-1);
  bar(snake.tail->x+1,snake.tail->y+1,snake.tail->x+BlockWidth-1,snake.tail->y+BlockHeight-1);
  }
  bool PlayGame()
  {
  int speed=300,key;
  Direction CurrentDirection=right;
  Node randomNode;
  Node newNode,outNode;
  bool neednode=true;
  bool overlap=false;
  int randx,randy;
  CreateSnake();

  while(true)
  {
  if(neednode==true)
  {
  randomize();
  do
  {
  randx=frame.left+rand()%RowOfFrame*BlockWidth;
  randy=frame.top+rand()%ColumnOfFrame*BlockHeight;
  for(Node *p=snake.head;p!=NULL;p=p->next)//hit itself
  if(randx==p->x&&randy==p->y)
  {overlap=true;break;}
  }
  while(overlap==true);
  randomNode.x=randx;
  randomNode.y=randy;
  randomNode.next=NULL;
  setfillstyle(SOLID_FILL,RED);
  bar(randomNode.x+1,randomNode.y+1,randomNode.x+BlockWidth-1,randomNode.y+BlockHeight-1);
  neednode=false;
  }
   if((key=bioskey(1))!=0)
  {
  switch(key)
  {
  case ESC:  return false;
  case UP:
  if(CurrentDirection!=down)
  CurrentDirection=up;
  ClearKeyBuf();
  break;
  case DOWN:
  if(CurrentDirection!=up)
  CurrentDirection=down;
  ClearKeyBuf();
  break;
  case LEFT:

共2页 首页 上一页 1 2 下一页 尾页 跳转到
相关内容
赞助商链接