亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

利用C/C++實(shí)現(xiàn)貪吃蛇游戲

 更新時(shí)間:2021年10月21日 17:10:31   作者:what how when why  
這篇文章主要為大家詳細(xì)介紹了利用C/C++實(shí)現(xiàn)貪吃蛇游戲,文中示例代碼介紹的非常詳細(xì),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下

利用C/C++實(shí)現(xiàn)貪吃蛇

(注意:本文章僅供參考,第一次寫博客還請(qǐng)多多指教。理解本文章需要easyx和c++等基礎(chǔ)知識(shí),并且需要了解貪吃蛇游戲機(jī)制

貪吃蛇機(jī)制介紹

相信絕大多數(shù)人都曾玩過或者了解過貪吃蛇這款經(jīng)典的游戲。貪吃蛇顧名思義,就是讓蛇盡可能的吃食物。玩家可通過方向鍵或自定義鍵來控制蛇頭的方向,使它吃到地圖出現(xiàn)的隨機(jī)食物。蛇每吃到一個(gè)食物,自身便會(huì)增長(zhǎng)。當(dāng)蛇碰到地圖的邊界或是蛇碰到自身,蛇便會(huì)死亡,游戲便結(jié)束。

機(jī)制大概了解過后,我們將考慮如何實(shí)現(xiàn)這類游戲。

設(shè)計(jì)與分析

首先,我們分析游戲整體結(jié)構(gòu)大概由四個(gè)部分構(gòu)成——界面、地圖、蛇、食物。
1、界面:界面能夠方便玩家的使用,可讓玩家自行選擇游戲的開始或結(jié)束;通過界面,我們可以設(shè)定一些有趣的東西來增加玩家的游戲體驗(yàn),例如:讓玩家選擇蛇的速度,以靈活調(diào)節(jié)游戲難度。
2、地圖:地圖能為蛇提供活動(dòng)空間,同時(shí)也是蛇位置的坐標(biāo)軸,方便定位。
3、蛇:蛇是游戲的靈魂。蛇可以定義如下屬性:坐標(biāo)、方向、速度、長(zhǎng)度。蛇。蛇的行為有:移動(dòng)、吃食物、死亡。
4、食物:食物在地圖中隨機(jī)分布,具有坐標(biāo)(可以嘗試去增加顏色屬性、大小屬性,本文章由于篇幅有限,暫不提供)。

思維導(dǎo)圖如下

首先設(shè)計(jì)用戶界面

//部分函數(shù)可以暫時(shí)不用考慮
void menu()
{
 initgraph(640, 480);
 int flag = 1;
 while (flag)
 {
  cleardevice();
  outtextxy(280, 180, "貪吃蛇游戲");
  outtextxy(280, 200, "按1開始游戲");
  outtextxy(280, 220, "按2結(jié)束游戲");
  //接受輸入指令0、1
  char ch = _getch();
  switch (ch)
  {
  //開始
  case '1':
  {
   food F;
   Initfood(F);//食物初始化

   Snake S;
   hatch(S);//蛇初始化
   control_speed(S.speed);//蛇速度控制函數(shù)
   drawsnake(S, F);//開始繪制游戲面板
   break;
  }  
  //結(jié)束
  case '2':
   flag = 0;
   break;
  default :
   break;
  }
 }
 closegraph();
}

接下來可以通過結(jié)構(gòu)體來定義蛇和食物

typedef struct Snake {
 int speed = 0;//速度
 pair<int, int> coor[MAXSIZE]={};//坐標(biāo)(x, y)
 int dir;//方向
 int length;//長(zhǎng)度
};

typedef struct food {
 pair<int, int> place[MAXSIZE] = {};//坐標(biāo)
 int score;//分?jǐn)?shù)
};

接下來將食物和蛇進(jìn)行初始化

void Initfood(food& F)
{
 F.score = 0;
 srand(time(NULL));
 //將食物坐標(biāo)隨機(jī)設(shè)置
 for (int i = 0; i < 100; i++)
 {
  F.place[i].first = rand() % (640 - R) + R;
  F.place[i].second = rand() % (480 - R) + R;
 }
}

void hatch(Snake &S)
{
 S.length = 3;
 S.dir = 2;
 S.speed = 0;
 //先給出3節(jié)身體
 for (int i = 0; i < 3; i++)
 {
  S.coor[i].first = 40 - i * 10;
  S.coor[i].second = 30;
 }
}

再接著設(shè)計(jì)蛇速度控制函數(shù)

void control_speed(int &speed)
{
 cleardevice();
 outtextxy(280, 180, "請(qǐng)選擇蛇的速度1-5");
 char ch = _getch();
 speed = ch - '0';
}

最關(guān)鍵的蛇運(yùn)動(dòng)機(jī)制設(shè)計(jì)來了,我將分段講解

1、繪制蛇(蛇將有一系列正方體塊組成)

for (int i = 0; i < S.length; i++)
  {
   int x = S.coor[i].first;
   int y = S.coor[i].second;
   //蛇頭設(shè)為綠色,方便區(qū)分
   if (i == 0)
   {
    setfillcolor(GREEN);
    solidrectangle(x - R, y - R, x + R, y + R);
   }
    
   else
   {
    setcolor(WHITE);
    rectangle(x - R, y - R, x + R, y + R);
   }

2、繪制食物(食物由單個(gè)正方體組成)

int m = F.place[F.score].first;
int n = F.place[F.score].second;
setfillcolor(WHITE);
solidrectangle(m-R, n-R, m+R, n+R);

3、蛇的運(yùn)動(dòng)

像人的運(yùn)動(dòng)是通過腳向前邁步來制動(dòng)整個(gè)軀干一樣,蛇頭同樣驅(qū)動(dòng)整個(gè)身體。也就是說我們只要控制蛇頭的運(yùn)動(dòng)方向及前進(jìn),軀干便會(huì)跟著蛇頭一起移動(dòng)。蛇軀干的每個(gè)節(jié)點(diǎn)只需要繼承上一個(gè)節(jié)點(diǎn)的位置即可。

void movesnake(Snake& S)
{
//繼承坐標(biāo)
 for (int i = S.length - 1; i > 0; i--)
 {
  S.coor[i].first = S.coor[i - 1].first;
  S.coor[i].second = S.coor[i - 1].second;
 }
 switch (S.dir)
 {
 case 1:
  S.coor[0].second-= 10;
  break;
 case 2:
  S.coor[0].first+=10;
  break;
 case 3:
  S.coor[0].second+=10;
  break;
 case 4:
  S.coor[0].first-=10;
  break;
 default:
  break;
 }
}

4、蛇運(yùn)動(dòng)控制

使用方向鍵改變蛇頭的運(yùn)動(dòng)方向即可

void control_dir(int& DIR)
{
 char ch = _getch();
 switch (ch)
 {
 case 72:
 case 'W':
 case 'w':
 //這里用if主要是因?yàn)樯哌\(yùn)動(dòng)的機(jī)制:當(dāng)蛇在一某方向運(yùn)動(dòng)的途中,不能直接往反方向運(yùn)動(dòng)(這樣會(huì)導(dǎo)致蛇身體重疊),只能通過以當(dāng)前運(yùn)動(dòng)方向?yàn)檎较?,進(jìn)行左右移動(dòng)來改變方向。
  if (DIR != 3)
   DIR = 1;
  break;
 case 77:
 case 'D':
 case 'd':
  if (DIR != 4)
   DIR = 2;
  break;
 case 80:
 case 'S':
 case 's':
  if (DIR != 1)
   DIR = 3;
  break;
 case 75:
 case 'A':
 case 'a':
  if (DIR != 2)
   DIR = 4;
  break;
 default:
  break;
 }
}

4、吃食物

吃完食物的結(jié)果:出現(xiàn)下一個(gè)食物、蛇變長(zhǎng)

void Eating(Snake& S, food& F)
{
 if (S.coor[0].first >= F.place[F.score].first - R&& S.coor[0].first <= F.place[F.score].first + R
  && S.coor[0].second >= F.place[F.score].second -R&& S.coor[0].second <= F.place[F.score].second+R)
 {
  F.score++;
  S.length++;
 }
}

5、判斷是否死亡

死亡判斷有兩種結(jié)果:1、碰壁。2、自身形成回路(自己咬自己)

int isdead(Snake S)
{
 if (S.coor[0].first > 640-R || S.coor[0].first < R || S.coor[0].second>480-R || S.coor[0].second<=R)
  return 1;
 else
 {
  for (int i = 4; i < S.length; i++)
  {
   if (S.coor[0].first >= S.coor[i].first-R&& S.coor[0].first <= S.coor[i].first + R
    && S.coor[0].second >= S.coor[i].second-R&& S.coor[0].second <= S.coor[i].second+R)
    return 1;
  }
  return 0;
 }
}

蛇的運(yùn)動(dòng)機(jī)制設(shè)計(jì)基本大功告成,可以自行在地圖上進(jìn)行修飾,像加入分?jǐn)?shù)欄

void control_dir(int& DIR)
{
 char ch = _getch();
 switch (ch)
 {
 case 72:
 case 'W':
 case 'w':
  if (DIR != 3)
   DIR = 1;
  break;
 case 77:
 case 'D':
 case 'd':
  if (DIR != 4)
   DIR = 2;
  break;
 case 80:
 case 'S':
 case 's':
  if (DIR != 1)
   DIR = 3;
  break;
 case 75:
 case 'A':
 case 'a':
  if (DIR != 2)
   DIR = 4;
  break;
 default:
  break;
 }
}

void movesnake(Snake& S)
{
 for (int i = S.length - 1; i > 0; i--)
 {
  S.coor[i].first = S.coor[i - 1].first;
  S.coor[i].second = S.coor[i - 1].second;
 }
 switch (S.dir)
 {
 case 1:
  S.coor[0].second-= 10;
  break;
 case 2:
  S.coor[0].first+=10;
  break;
 case 3:
  S.coor[0].second+=10;
  break;
 case 4:
  S.coor[0].first-=10;
  break;
 default:
  break;
 }
 
}

int isdead(Snake S)
{
 if (S.coor[0].first > 640-R || S.coor[0].first < R || S.coor[0].second>480-R || S.coor[0].second<=R)
  return 1;
 else
 {
  for (int i = 4; i < S.length; i++)
  {
   if (S.coor[0].first >= S.coor[i].first-R&& S.coor[0].first <= S.coor[i].first + R
    && S.coor[0].second >= S.coor[i].second-R&& S.coor[0].second <= S.coor[i].second+R)
    return 1;
  }
  return 0;
 }
}

void Eating(Snake& S, food& F)
{
 if (S.coor[0].first >= F.place[F.score].first - R&& S.coor[0].first <= F.place[F.score].first + R
  && S.coor[0].second >= F.place[F.score].second -R&& S.coor[0].second <= F.place[F.score].second+R)
 {
  F.score++;
  S.length++;
 }
}

void drawsnake(Snake& S, food F)
{
 char out[3] = {};

 BeginBatchDraw();
 while (1)
 {
  cleardevice();
  for (int i = 0; i < S.length; i++)
  {
   int x = S.coor[i].first;
   int y = S.coor[i].second;
   if (i == 0)
   {
    setfillcolor(GREEN);
    solidrectangle(x - R, y - R, x + R, y + R);
   }
    
   else
   {
    setcolor(WHITE);
    rectangle(x - R, y - R, x + R, y + R);
   }
   
  }
  int m = F.place[F.score].first;
  int n = F.place[F.score].second;
  setfillcolor(WHITE);
  solidrectangle(m-R, n-R, m+R, n+R);

  sprintf_s(out, "%d", F.score * S.speed);
  setbkmode(0);
  outtextxy(570, 20, "得分");
  outtextxy(620, 20, out);

  FlushBatchDraw();
  Sleep(200-S.speed*30);

  while(_kbhit())
  {
   control_dir(S.dir);
  }

  movesnake(S);

  Eating(S, F);
  if (isdead(S))
   break;
 }
 cleardevice();
 sprintf_s(out, "%d", F.score * S.speed);
 outtextxy(280, 180, "得分");
 outtextxy(320, 180, out);
 outtextxy(280, 200, "按Enter鍵繼續(xù)");

 FlushBatchDraw();
 getchar();
 EndBatchDraw();
}

完整代碼如下

#include <iostream>
#include <graphics.h>
#include <conio.h>
#include <time.h>
using namespace std;

#define MAXSIZE 100
#define R 5
typedef struct Snake {
 int speed = 0;//速度
 pair<int, int> coor[MAXSIZE]={};
 int dir = 2;
 int length = 3;
};

typedef struct food {
 pair<int, int> place[MAXSIZE] = {};
 int score;
};

void Initfood(food& F)
{
 F.score = 0;
 srand(time(NULL));
 for (int i = 0; i < 100; i++)
 {
  F.place[i].first = rand() % (640 - R) + R;
  F.place[i].second = rand() % (480 - R) + R;
 }
}

void hatch(Snake &S)
{
 S.length = 3;
 S.dir = 2;
 S.speed = 0;
 for (int i = 0; i < 3; i++)
 {
  S.coor[i].first = 40 - i * 10;
  S.coor[i].second = 30;
 }
}

void control_speed(int &speed)
{
 cleardevice();
 outtextxy(280, 180, "請(qǐng)選擇蛇的速度1-5");
 char ch = _getch();
 speed = ch - '0';
}

void control_dir(int& DIR)
{
 char ch = _getch();
 switch (ch)
 {
 case 72:
 case 'W':
 case 'w':
  if (DIR != 3)
   DIR = 1;
  break;
 case 77:
 case 'D':
 case 'd':
  if (DIR != 4)
   DIR = 2;
  break;
 case 80:
 case 'S':
 case 's':
  if (DIR != 1)
   DIR = 3;
  break;
 case 75:
 case 'A':
 case 'a':
  if (DIR != 2)
   DIR = 4;
  break;
 default:
  break;
 }
}

void movesnake(Snake& S)
{
 for (int i = S.length - 1; i > 0; i--)
 {
  S.coor[i].first = S.coor[i - 1].first;
  S.coor[i].second = S.coor[i - 1].second;
 }
 switch (S.dir)
 {
 case 1:
  S.coor[0].second-= 10;
  break;
 case 2:
  S.coor[0].first+=10;
  break;
 case 3:
  S.coor[0].second+=10;
  break;
 case 4:
  S.coor[0].first-=10;
  break;
 default:
  break;
 }
 
}

int isdead(Snake S)
{
 if (S.coor[0].first > 640-R || S.coor[0].first < R || S.coor[0].second>480-R || S.coor[0].second<=R)
  return 1;
 else
 {
  for (int i = 4; i < S.length; i++)
  {
   if (S.coor[0].first >= S.coor[i].first-R&& S.coor[0].first <= S.coor[i].first + R
    && S.coor[0].second >= S.coor[i].second-R&& S.coor[0].second <= S.coor[i].second+R)
    return 1;
  }
  return 0;
 }
}

void Eating(Snake& S, food& F)
{
 if (S.coor[0].first >= F.place[F.score].first - R&& S.coor[0].first <= F.place[F.score].first + R
  && S.coor[0].second >= F.place[F.score].second -R&& S.coor[0].second <= F.place[F.score].second+R)
 {
  F.score++;
  S.length++;
 }
}

void drawsnake(Snake& S, food F)
{
 char out[3] = {};

 BeginBatchDraw();
 while (1)
 {
  cleardevice();
  for (int i = 0; i < S.length; i++)
  {
   int x = S.coor[i].first;
   int y = S.coor[i].second;
   if (i == 0)
   {
    setfillcolor(GREEN);
    solidrectangle(x - R, y - R, x + R, y + R);
   }
    
   else
   {
    setcolor(WHITE);
    rectangle(x - R, y - R, x + R, y + R);
   }
   
  }
  int m = F.place[F.score].first;
  int n = F.place[F.score].second;
  setfillcolor(WHITE);
  solidrectangle(m-R, n-R, m+R, n+R);

  sprintf_s(out, "%d", F.score * S.speed);
  setbkmode(0);
  outtextxy(570, 20, "得分");
  outtextxy(620, 20, out);

  FlushBatchDraw();
  Sleep(200-S.speed*30);

  while(_kbhit())
  {
   control_dir(S.dir);
  }

  movesnake(S);

  Eating(S, F);
  if (isdead(S))
   break;
 }
 cleardevice();
 sprintf_s(out, "%d", F.score * S.speed);
 outtextxy(280, 180, "得分");
 outtextxy(320, 180, out);
 outtextxy(280, 200, "按Enter鍵繼續(xù)");

 FlushBatchDraw();
 getchar();
 EndBatchDraw();
}

void menu()
{
 initgraph(640, 480);
 int flag = 1;
 while (flag)
 {
  cleardevice();
  outtextxy(280, 180, "貪吃蛇游戲");
  outtextxy(280, 200, "按1開始游戲");
  outtextxy(280, 220, "按2結(jié)束游戲");
  char ch = _getch();
  switch (ch)
  {
  case '1':
  {
   food F;
   Initfood(F);

   Snake S;
   hatch(S);
   control_speed(S.speed);
   drawsnake(S, F);
   break;
  }  
  case '2':
   flag = 0;
   break;
  default :
   break;
  }
 }
 closegraph();
}

int main(void)
{
 menu();
 return 0;
}

以上就是本文的全部?jī)?nèi)容,希望對(duì)大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。

相關(guān)文章

最新評(píng)論