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

2016-02-19 21:35 130 1 收藏

下面,图老师小编带您去了解一下利用C++实现的贪吃蛇游戏,生活就是不断的发现新事物,get新技能~

【 tulaoshi.com - 编程语言 】

在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;rowRowOfFrame;row++)
  line(frame.left+row*BlockWidth,frame.top,frame.left+row*BlockWidth,frame.bottom);
  for(int column=1;columnColumnOfFrame;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:
  if(CurrentDirection!=right)
  CurrentDirection=left;
  ClearKeyBuf();
  break;
  case RIGHT:
  if(CurrentDirection!=left)
  CurrentDirection=right;
  ClearKeyBuf();
  break;
  case PAGEUP:speed=speed-100;
  if(speed100)
  speed=100;
  ClearKeyBuf();
  break;
  case PAGEDOWN:speed=speed+100;
  if(speed500)
  speed=500;
  ClearKeyBuf();
  break;
  default :break;
  }
  }
  int headx=snake.tail-x;
  int heady=snake.tail-y;
  switch(CurrentDirection)
  {
  case up: heady-=BlockHeight;break;
  case down: heady+=BlockHeight;break;
  case left: headx-=BlockWidth;break;
  case right: headx+=BlockWidth;break;
  }
  if(Hit(headx,heady))    //whether the snake hit the wall or itself
  return GameOver();
   更多内容请看C/C++技术专题  网络游戏攻略  游戏开发专题,或
  
  else
  {       //eat
  if(headx==randomNode.x&&heady==randomNode.y)
  {
  Enqueue(randomNode);
  setfillstyle(SOLID_FILL,BLUE);
  bar(randomNode.x+1,randomNode.y+1,randomNode.x-1+BlockWidth,randomNode.y-1+BlockHeight);
  neednode=true;
  }
  else     //no eat
  {
  newNode.x=headx;
  newNode.y=heady;
  newNode.next=NULL;
  Enqueue(newNode);
  outNode=Dequeue();
  setfillstyle(SOLID_FILL,LIGHTGRAY);
  bar(outNode.x+1,outNode.y+1,outNode.x+BlockWidth-1,outNode.y+BlockHeight-1);
  setfillstyle(SOLID_FILL,BLUE);
  bar(newNode.x+1,newNode.y+1,newNode.x-1+BlockWidth,newNode.y-1+BlockHeight);
  }
  }
  delay(speed);
  }
  }
  void ClearKeyBuf()
  {
  do
  bioskey(0);
  while(bioskey(1));
  }  void Foot(int x,int y)
  {
  setcolor(BLUE);
  outtextxy(x,y,"writer:[T]RealXL E-MAIL:realgeneral@hotmail.com");
  }
  void Head(int x,int y)
  {
  setcolor(RED);
  
     outtextxy(x,y,"GREEDY SNAKE");
  }
  void Enqueue(Node inNode)
  {
  Node *p=new Node;
  p-x=inNode.x;
  p-y=inNode.y;
  p-next=inNode.next;
  snake.tail-next=p;
  snake.tail=p;
  snake.length++;
  }
  
   更多内容请看C/C++技术专题  网络游戏攻略  游戏开发专题,或
  
  Node Dequeue()
  {
  Node *p=snake.head;
  Node outNode=*p;
  snake.head=p-next;
  snake.length--;
  delete p;
  return outNode;
  }  int Hit(int x,int y)
  {
  if(xframe.leftx=frame.rightyframe.topy=frame.bottom)//hit the wall
  return 1;
  Node *p=snake.head-next;
  for(int i=snake.length-1;i3;i--,p=p-next)//hit itself
  if(x==p-x&&y==p-y)
  return 1;
  return 0;
  }  bool GameOver()
  {
  int x=getmaxx()/2-50;
  int y=getmaxy()/2-20;
  setfillstyle(SOLID_FILL,DARKGRAY);
  bar(x+3,y+3,x+103,y+43);
  setfillstyle(SOLID_FILL,MAGENTA);
  bar(x,y,x+100,y+40);
  setlinestyle(0,3,1);
  setcolor(RED);
  rectangle(x,y,x+100,y+40);
  outtextxy(x+20,y+10,"GAGE OVER!");
  char c;
  while(true)                                        //按q或Q表示退出程序,按r或R表示重新开始游戏
  {
  c=getch();
  if(c=='q'c=='Q')
  return false;
  else if(c=='r'c=='R')
  return true;
  }
  }
  //conf.h                                                          
  #ifndef _conf_h
  #define _conf_h
  #define RowOfFrame    20         //主框架的行数
  #define ColumnOfFrame 20         //主框架的列数
  #define BlockWidth    15        //每个蛇节点的宽度
  #define BlockHeight   15        //每个蛇节点的高度
  #define UP   18432
  #define DOWN  20480
  #define LEFT  19200
  #define RIGHT  19712
  #define ESC   283
  #define ENTER  7181
  #define PAGEUP  18688
  #define PAGEDOWN 20736
  #endif

来源:http://www.tulaoshi.com/n/20160219/1626614.html

延伸阅读
代码如下: # include vector # include iostream # include set using namespace std; int main(int argc, char * argv[]) { vectorint v; //找一些数据来测试 for (int i = 0; i 50; i++) v.push_back(rand() % 25); for (int i = 0; i 50; i++) { cout v[i] '\t'; if ((i + 1) % 10 == 0) cout endl; } cout endl; ...
一、 简介 本文将细致地介绍用C#来实现游戏Reversi的完整过程。游戏界面如下图所示。 二、 背景 我最开始写这个程序是为了作为学习C#和.NET编程的一个练习。Reversi-或Othello一是一个相当有趣且相当流行的游戏,它仅要求几个基本元素和简单的游戏规则。所以,它是学习一个新的编程环境的良好选择。 该程序的第一个...
C++代码如下:  #include algorithm #include vector #include cstdio using namespace std; typedef  unsigned int Type; enum{ BASE_DATA = 10000, MAX_NUM = 100000 , MAX_SIZE = MAX_NUM+1000}; struct MulOpt { Type data1; MulOpt(Type x):data1(x){} inline Type operator()(Type y) { return data1*y; } }; struct Conver...
提要:本文重点讨论开源游戏开发库Allegro(Allegro低级游戏例程),同时涉及到一些深度技术并提供了一个简单的示例程序,帮你进一步确定它是否是适合你的开发平台。 !-- frame contents -- !-- /frame contents -- 一、 一个适于多环境的引擎 Allegro最开始被研发于八十年代后期古老的Atari ST平台上,随后被快速地移植到...
实现LZARI压缩算法的C++类 作者: 阙荣文(querw) 下载源代码 这是一个基于LZARI算法的数据压缩的类.Haruhiko Okumura 于1989年7月4日用c语言写实现了这个算法.但是上面用到了一些全局或静态的变量,在MFC下用起来很不方便.我把它改写成了一个c++类,使它可以方便的压缩和解压缩,更重要的是,我新增加了两个...

经验教程

489

收藏

22
微博分享 QQ分享 QQ空间 手机页面 收藏网站 回到头部