天天看点

【项目实战】轻松实现C/C++大作业:贪吃蛇大作战游戏!

这是一个贪吃蛇大作战类游戏,修改特性为 AI 不互杀;

该程序有四个类:蛇基类 SnakeBase,玩家类 Player,AI 类,Game 类;SnakeBase 和 AI 均继承自 SnakeBase,SnakeBase 提供基础接口;

Game 提供数据初始化以及游戏主循环。

程序设计之初,采用“实运行”方式,即所有动画均在地图 imgMap 上真实绘制,这样却有一些严重的问题,需要不断地记录节点背景以恢复节点经过的地方等。

后修改为“虚运行”方式,判断位置是否可视后直接绘至窗口内,这样大大降低时间开销,同时不会因为蛇靠近而产生不可擦除的颜色。

至于蛇运行,采用位置继承,即节点下一个位置为上一个节点的位置,但是会发现跨度太大,解决办法是在这个跨度中插入适当帧数。

执行效果如下:

【项目实战】轻松实现C/C++大作业:贪吃蛇大作战游戏!

完整的游戏源代码如下:

/*
  程序名称:
      贪吃蛇大作战
  简介:
      简单模拟了游戏 贪吃蛇大作战
      程序运行中可以通过 ESC 直接退出
      左键或右键可以加速移动,加速会消耗长度
  环境:
      VS2019 + EasyX_20190529(beta)
  作者:
      Teternity(QQ:1926594835)
*/
​
​
////////// 头文件 //////////
#include <easyx.h>
#include <conio.h>
#include <cstdio>
#include <ctime>
#include <cmath>
#pragma comment( lib, "MSIMG32.LIB")
​
​
////////// 窗口大小 //////////
const short ScreenWidth = 640;
const short ScreenHeight = 480;
​
​
////////// 全局变量 //////////
long ret = 0;
MOUSEMSG msg;
const short gap = 20;
const short xSide = ScreenWidth / 2 + gap;
const short ySide = ScreenHeight / 2 + gap;
IMAGE* imgMap = new IMAGE(ScreenWidth * 4, ScreenHeight * 4);
const double PI = 3.1415926;
const short nodeSize = 17;
const short nodeGap = 16;
const short stepLen = 4;
const short frame = 4;
const short snakeSpecies = 20;
int killCount = 0;
int mapX = 0;
int mapY = 0;
typedef struct _FOOD
{
  int x;
  int y;
  int r;
  COLORREF c;
}Food;
Food* food;
short nFood = 520;
IMAGE imgFood(nodeSize, nodeSize);
const COLORREF mapMainColor = WHITE;
const COLORREF playerColor0 = RGB(120, 0, 0);
const COLORREF playerColor1 = RGB(200, 0, 0);
const COLORREF playerColor2 = RGB(255, 255, 0);
const COLORREF mapLineColor = RGB(225, 225, 225);
​
​
// 透明贴图函数:(更多内容请参考官网)
// 参数:
//    x, y:  目标贴图位置
//    srcimg: 源 IMAGE 对象指针。NULL 表示默认窗体
//    dstimg: 目标 IMAGE 对象指针。NULL 表示默认窗体
//    transparentcolor: 透明色。srcimg 的该颜色并不会复制到 dstimg 上,从而实现透明贴图
void putTimage(int x, int y, IMAGE* srcimg, IMAGE* dstimg = NULL, UINT transparentcolor = 0)
{
  HDC dstDC = GetImageHDC(dstimg);
  HDC srcDC = GetImageHDC(srcimg);
  int w = srcimg->getwidth();
  int h = srcimg->getheight();
​
  // 使用 Windows GDI 函数实现透明位图
  TransparentBlt(dstDC, x, y, w, h, srcDC, 0, 0, w, h, transparentcolor);
}
​
​
////////// 蛇基类 //////////
class SnakeBase
{
public:
  // 构造函数
  SnakeBase()
  {
    Count++;
    isDead = false;
    length = 50 + rand() % 50;
    nNode = length / 5;
    maxNode = 9999;
    imgHead = imgNode = imgTail = nullptr;
    headNode = tailNode = nullptr;
    nodeMsg = nullptr;
  }
​
  // 析构函数
  virtual ~SnakeBase()
  {
    Count--;
    Node* temp = headNode;
    while (temp != nullptr)
    {
      headNode = headNode->nextNode;
      delete temp;
      temp = headNode;
    }
    delete imgHead, imgNode, imgTail;
    if (nodeMsg != nullptr)
      delete[] nodeMsg;
  }
​
  // 设置image
  void SetImage(COLORREF headColor, COLORREF nodeColor, COLORREF tailColor)
{
    imgHead = new IMAGE(nodeSize, nodeSize);
    imgNode = new IMAGE(nodeSize, nodeSize);
    imgTail = new IMAGE(nodeSize, nodeSize);
    SetWorkingImage(imgHead);
    setfillcolor(headColor);
    solidcircle(nodeSize / 2, nodeSize / 2, nodeSize / 2);
    setfillcolor(tailColor);
    solidcircle(nodeSize / 2, nodeSize / 2, 2);
    SetWorkingImage(imgNode);
    setfillcolor(nodeColor);
    solidcircle(nodeSize / 2, nodeSize / 2, nodeSize / 2);
    SetWorkingImage(imgTail);
    setfillcolor(tailColor);
    solidcircle(nodeSize / 2, nodeSize / 2, nodeSize / 2);
    SetWorkingImage();
  }
​
  // 创建各节点
  void Creat(int headX, int headY)
{
    headNode = new Node;
    headNode->lastNode = nullptr;
    headNode->nextNode = nullptr;
    headNode->x = headX;
    headNode->y = headY;
    Node* temp = headNode;
    for (int i = 0; i < nNode - 1; i++)
    {
      Node* newNode = new Node;
      newNode->lastNode = temp;
      newNode->x = temp->x;
      newNode->y = temp->y;
      temp->nextNode = newNode;
      temp = newNode;
    }
    temp->nextNode = nullptr;
    tailNode = temp;
    temp = nullptr;
  }
​
  // 绘制蛇身
  void ShowBody()
{
    int n = nNode % 2;
    Node* temp = tailNode;
    while (temp != headNode)
    {
      if (temp->x - nodeSize / 2 + mapX >= nodeSize * -1 && temp->x - nodeSize / 2 + mapX <= ScreenWidth
        && temp->y - nodeSize / 2 + mapY >= nodeSize / -2 && temp->y - nodeSize / 2 + mapY <= ScreenHeight)
        putTimage(temp->x - nodeSize / 2 + mapX, temp->y - nodeSize / 2 + mapY, n % 2 == 0 ? imgNode : imgTail);
      temp = temp->lastNode;
      n++;
    }
    if (temp->x - nodeSize / 2 + mapX >= nodeSize * -1 && temp->x - nodeSize / 2 + mapX <= ScreenWidth
      && temp->y - nodeSize / 2 + mapY >= nodeSize / -2 && temp->y - nodeSize / 2 + mapY <= ScreenHeight)
      putTimage(temp->x - nodeSize / 2 + mapX, temp->y - nodeSize / 2 + mapY, imgHead);
    temp = nullptr;
  }
​
  // 刷新数据
  void FlushData(short& n, int& dx, int& dy)
{
    if (n == frame)
    {
      nodeMsg = new POINT[nNode];
      Node* temp = headNode;
      int i = 0;
      while (temp != nullptr)
      {
        nodeMsg[i].x = temp->x;
        nodeMsg[i].y = temp->y;
        temp = temp->nextNode;
        i++;
      }
    }
​
    Node* temp = tailNode;
    int i = nNode - 2;
    while (temp != headNode)
    {
      if (n == 1)
      {
        temp->x = nodeMsg[i].x;
        temp->y = nodeMsg[i].y;
      }
      else
      {
        temp->x += int(stepLen * cos(atan2(nodeMsg[i].y - temp->y, nodeMsg[i].x - temp->x)));
        temp->y += int(stepLen * sin(atan2(nodeMsg[i].y - temp->y, nodeMsg[i].x - temp->x)));
      }
      temp = temp->lastNode;
      i--;
    }
    temp = nullptr;
    headNode->x += dx;
    headNode->y += dy;
​
    if (n == 1)
    {
      delete[] nodeMsg;
      nodeMsg = nullptr;
    }
  }
​
  // 据长度添加节点
  void SetNode(int ex = 0)
{
    int n = nNode;
    length += ex;
    n = length / 5 - n;
    if (n > 0)
    {
      while (nNode < maxNode && n != 0)
      {
        n--;
        nNode++;
        Node* newNode = new Node;
        newNode->lastNode = tailNode;
        newNode->nextNode = nullptr;
        newNode->x = tailNode->x;
        newNode->y = tailNode->y;
        tailNode->nextNode = newNode;
        tailNode = newNode;
        newNode = nullptr;
      }
    }
    else if (n < 0)
    {
      while (nNode > 10 && n != 0)
      {
        n++;
        nNode--;
        Node* temp = tailNode;
        tailNode = tailNode->lastNode;
        tailNode->nextNode = nullptr;
        delete temp;
        temp = nullptr;
      }
      if (nNode == 10)
        length = 50;
    }
  }
​
  // 吃到食物
  bool GetFood(int k, int x, int y)
{
    int len = nodeGap + 5;
    if (x - headNode->x < len && headNode->x - x < len && y - headNode->y < len && headNode->y - y < len)
    {
      food[k].x = rand() % (imgMap->getwidth() - xSide * 2) + xSide;
      food[k].y = rand() % (imgMap->getheight() - ySide * 2) + ySide;
      food[k].r = rand() % 2 + 3;
      food[k].c = HSVtoRGB(float(rand() % 360), rand() % 1000 / 2000.0f + 0.5f, rand() % 1000 / 2000.0f + 0.5f);
      return true;
    }
    return false;
  }
​
protected:
  long length;
  int nNode;
  int maxNode;
  IMAGE* imgHead, * imgNode, * imgTail;
  POINT* nodeMsg;
​
public:
  // 蛇节点
  typedef struct _NODE
  {
    int x;
    int y;
    struct _NODE* lastNode;
    struct _NODE* nextNode;
  }Node;
  bool isDead;
  static int Count;
  Node* headNode, * tailNode;
};
int SnakeBase::Count = 0;
​
​
////////// Player 类 //////////
class Player :public SnakeBase
{
public:
  // 构造函数
  Player() :SnakeBase()
  {
    SetImage(playerColor0, playerColor1, playerColor2);
    int headX = rand() % (imgMap->getwidth() - xSide * 2 - nodeSize * 10) + xSide + nodeSize;
    int headY = rand() % (imgMap->getheight() - ySide * 2 - nodeSize * 12) + ySide + nodeSize;
    Creat(headX, headY);
    nt = frame;
  }
​
  // 是否死亡
  void IsDead()
{
    if (headNode->x <= xSide || headNode->x >= imgMap->getwidth() - 1 - xSide || headNode->y <= ySide || headNode->y >= imgMap->getheight() - 1 - ySide)
      isDead = true;
    else
    {
      double radian = atan2(headNode->y - headNode->nextNode->y, headNode->x - headNode->nextNode->x);
      int x = ScreenWidth / 2 + int(nodeSize / 2 * cos(radian));
      int y = ScreenHeight / 2 + int(nodeSize / 2 * sin(radian));
      COLORREF c = getpixel(x, y);
      if (!(c == mapLineColor || c == mapMainColor))
        isDead = true;
      else
      {
        for (int i = 1; i < 8; i++)
        {
          x = ScreenWidth / 2 + int(nodeSize / 2 * cos(radian));
          y = ScreenHeight / 2 + int(nodeSize / 2 * sin(radian));
          c = getpixel(x, y);
          if (!(c == mapLineColor || c == mapMainColor))
          {
            isDead = true;
            break;
          }
          x = ScreenWidth / 2 + int(nodeSize / 2 * cos(radian));
          y = ScreenHeight / 2 + int(nodeSize / 2 * sin(radian));
          c = getpixel(x, y);
          if (!(c == mapLineColor || c == mapMainColor))
          {
            isDead = true;
            break;
          }
        }
      }
    }
  }
​
  // 移动
  void Move(int& ex, int& mapX, int& mapY, short& ddx, short& ddy)
{
    int dx = int(stepLen * cos(atan2(ddy, ddx)));
    int dy = int(stepLen * sin(atan2(ddy, ddx)));
    mapX -= dx;
    mapY -= dy;
    FlushData(nt, dx, dy);
    for (int k = 0; k < nFood; k++)
      if (GetFood(k, food[k].x, food[k].y))
        ex += food[k].r / 2;
    nt--;
    if (nt <= 0)
    {
      nt = frame;
      while (MouseHit())
        msg = GetMouseMsg();
      ddx = msg.x - ScreenWidth / 2;
      ddy = msg.y - ScreenHeight / 2;
      SetNode(ex);
      ex = 0;
    }
  }
​
  // 打印成绩
  void Print()
{
    settextcolor(BLACK);
    settextstyle(20, 0, _T("微软雅黑"));
    TCHAR str[32] = { 0 };
    _stprintf_s(str, _T("长度:%d"), length);
    outtextxy(5, 5, str);
    _stprintf_s(str, _T("节点:%d"), nNode);
    outtextxy(5, 25, str);
    _stprintf_s(str, _T("击杀:%d"), killCount);
    outtextxy(5, 45, str);
  }
​
public:
  short nt;
};
​
​
////////// AI 类 //////////
class AI :public SnakeBase
{
public:
  // 构造函数
  AI(Player* player)
  {
    p = player;
    COLORREF c0 = HSVtoRGB(float(rand() % 360), 1.0f, 0.4f);
    COLORREF c1 = HSVtoRGB(float(rand() % 360), 1.0f, 0.8f);
    COLORREF c2 = HSVtoRGB(float(rand() % 360), 1.0f, 1.0f);
    SetImage(c0, c1, c2);
    int headX = 0;
    int headY = 0;
    do
    {
      headX = rand() % (imgMap->getwidth() - xSide * 2 - nodeSize * 3) + xSide + nodeSize;
      headY = rand() % (imgMap->getheight() - ySide * 2 - nodeSize * 5) + ySide + nodeSize;
    } while (IsInPlayer(headX, headY));
    Creat(headX, headY);
    nt = frame;
    minLine = 3 * frame;
    curLine = minLine + (rand() % 12) * frame;
    ddx = (rand() % ScreenWidth) * (rand() % 1000 < 500 ? 1 : -1);
    ddy = (rand() % ScreenHeight) * (rand() % 1000 < 500 ? 1 : -1);
    dx = int(stepLen * cos(atan2(ddy, ddx)));
    dy = int(stepLen * sin(atan2(ddy, ddx)));
    isFast = false;
    ct = 0;
    exp = 0;
  }
​
  // 是否死亡
  bool IsDead(int& ex)
{
    if (headNode->x <= xSide || headNode->x >= imgMap->getwidth() - 1 - xSide || headNode->y <= ySide || headNode->y >= imgMap->getheight() - 1 - ySide)
      return true;
    else
    {
      bool is_dead = IsInPlayer(headNode->x, headNode->y);
      if (is_dead)
      {
        killCount++;
        ex += nNode;
      }
      return is_dead;
    }
  }
​
  // 位置是否接触 player
  bool IsInPlayer(int headX, int headY)
{
    Node* temp = p->headNode;
    while (temp != nullptr)
    {
      if (headX - temp->x < nodeSize && temp->x - headX < nodeSize && headY - temp->y < nodeSize && temp->y - headY < nodeSize)
        return true;
      temp = temp->nextNode;
    }
    return false;
  }
​
  // 移动
  void Move(int& ex)
{
    if (curLine <= 0)
    {
      double rad = atan2(ddy, ddx);
      isFast = rand() % 1200 < 100 ? true : false;
      curLine = minLine + (rand() % 21) * frame;
      do
      {
        ddx = (rand() % ScreenWidth + 40) * (rand() % 1000 < 500 ? 1 : -1);
        ddy = (rand() % ScreenHeight + 30) * (rand() % 1000 < 500 ? 1 : -1);
      } while (fabs(atan2(ddy, ddx) - rad) > PI / 6 * 5);
      dx = int(stepLen * cos(atan2(ddy, ddx)));
      dy = int(stepLen * sin(atan2(ddy, ddx)));
    }
    FlushData(nt, dx, dy);
    for (int k = 0; k < nFood; k++)
      if (GetFood(k, food[k].x, food[k].y))
        exp += food[k].r / 2;
    nt--;
    curLine--;
    if (nt <= 0)
    {
      nt = frame;
      if (rand() % 1000 < 120)
      {
        SetNode(rand() % 5 + exp);
        exp = 0;
      }
      if (rand() % 1000 < 80)
        curLine = 0;
      if (rand() % 1000 < 900 && curLine > 0)    // 90% 概率避免出界
      {
        int deadX = headNode->x + int((rand() % 50 + nodeGap) * cos(atan2(ddy, ddx)));
        int deadY = headNode->y + int((rand() % 50 + nodeGap) * sin(atan2(ddy, ddx)));
        if (deadX <= xSide || deadX >= imgMap->getwidth() - 1 - xSide)
        {
          ddx *= -1;
          ddy += rand() % 30 + 30;
        }
        if (deadY <= ySide || deadY >= imgMap->getheight() - 1 - ySide)
        {
          ddy *= -1;
          ddx += rand() % 40 + 40;
        }
        dx = int(stepLen * cos(atan2(ddy, ddx)));
        dy = int(stepLen * sin(atan2(ddy, ddx)));
      }
      if (rand() % 1000 < rand() % 400 + 400 && curLine > 0)  // 40%-80%(也可以理解为60%) 概率躲避 player
      {
        int deadX = headNode->x + int((nodeGap + 5) * cos(atan2(ddy, ddx)));
        int deadY = headNode->y + int((nodeGap + 5) * sin(atan2(ddy, ddx)));
        if (IsInPlayer(deadX, deadY))
        {
          ddx = -1 * ddx + rand() % 40 + 40;
          ddy = -1 * ddy + rand() % 30 + 30;
        }
        dx = int(stepLen * cos(atan2(ddy, ddx)));
        dy = int(stepLen * sin(atan2(ddy, ddx)));
      }
    }
    isDead = IsDead(ex);
    if (isDead)
    {
      int n = nNode / 2;
      Node* temp = headNode->nextNode->nextNode;
      while (n--)
      {
        for (int k = 0; k < nFood; k++)
        {
          if (food[k].x < -1 * mapX - nodeSize * 2 || food[k].x > -1 * mapX + nodeSize * 2 + ScreenWidth
            || food[k].y < -1 * mapY - nodeSize * 2 || food[k].y > -1 * mapY + nodeSize * 2 + ScreenHeight)
          {
            food[k].x = temp->x + (rand() % 5 + 3) * (rand() % 100 < 50 ? 1 : -1);
            food[k].y = temp->y + (rand() % 5 + 3) * (rand() % 100 < 50 ? 1 : -1);
            food[k].r = nodeSize / 2;
            food[k].c = HSVtoRGB(float(rand() % 360), rand() % 1000 / 2000.0f + 0.5f, rand() % 1000 / 2000.0f + 0.5f);
            break;
          }
          else if (k == nFood - 1)
          {
            n = 0;
            break;
          }
        }
        temp = temp->nextNode;
      }
      temp = nullptr;
    }
  }
​
private:
  short nt;
  int minLine;
  int curLine;
  int ddx, ddy;
  int dx, dy;
  Player* p;
​
public:
  bool isFast;
  clock_t ct;
  int exp;
};
​
​
////////// 游戏主体类 //////////
class Game
{
public:
  // 构造函数
  Game()
  {
    flushTime = 32;
    setbkmode(TRANSPARENT);
    BeginBatchDraw();
​
    SetWorkingImage(imgMap);
    setlinecolor(mapLineColor);
    setfillcolor(mapMainColor);
    setbkcolor(BROWN);
    cleardevice();
    solidrectangle(xSide, ySide, imgMap->getwidth() - 1 - xSide, imgMap->getheight() - 1 - ySide);
    for (int i = gap + xSide; i < imgMap->getwidth() - xSide; i += gap)
      line(i, ySide, i, imgMap->getheight() - 1 - ySide);
    for (int j = gap + ySide; j < imgMap->getheight() - ySide; j += gap)
      line(xSide, j, imgMap->getwidth() - 1 - xSide, j);
    SetWorkingImage();
​
    player = new Player;
    mapX = -1 * (player->headNode->x - ScreenWidth / 2);
    mapY = -1 * (player->headNode->y - ScreenHeight / 2);
​
    ai = new Ai;
    ai->ais = new AI(player);
    Ai* temp = ai;
    for (int i = 1; i < 15; i++)
    {
      temp->next = new Ai;
      temp = temp->next;
      temp->ais = new AI(player);
    }
    temp->next = ai;
    temp = nullptr;
​
    food = new Food[nFood];
    for (int k = 0; k < nFood; k++)
    {
      food[k].x = rand() % (imgMap->getwidth() - xSide * 2) + xSide;
      food[k].y = rand() % (imgMap->getheight() - ySide * 2) + ySide;
      food[k].r = rand() % 2 + 3;
      food[k].c = HSVtoRGB(float(rand() % 360), rand() % 1000 / 2000.0f + 0.5f, rand() % 1000 / 2000.0f + 0.5f);
    }
​
    Draw();
    outtextxy((ScreenWidth - textwidth(_T("左键或右键加速"))) / 2, ScreenHeight / 4 * 3 + 25, _T("左键或右键加速"));
    outtextxy((ScreenWidth - textwidth(_T("按任意键继续"))) / 2, ScreenHeight / 4 * 3 + 50, _T("按任意键继续"));
    FlushBatchDraw();
    ret = _getwch();
  }
​
  // 析构函数
  ~Game()
  {
    EndBatchDraw();
    delete imgMap;
    delete player;
    if (ai != nullptr)
    {
      Ai* temp = ai->next;
      while (temp != ai)
      {
        delete temp->ais;
        temp = temp->next;
      }
      delete ai->ais;
      delete ai;
    }
  }
​
  // 绘制食物
  void DrawFood()
{
    for (int k = 0; k < nFood; k++)
    {
      if (food[k].x - 9 + mapX >= 0 && food[k].x - 9 + mapX <= ScreenWidth && food[k].y - 9 + mapY >= 0 && food[k].y - 9 + mapY <= ScreenHeight)
      {
        if (food[k].r < 6)
        {
          setfillcolor(food[k].c);
          solidcircle(food[k].x + mapX, food[k].y + mapY, food[k].r);
        }
        else
        {
          SetWorkingImage(&imgFood);
          cleardevice();
          setfillcolor(food[k].c);
          solidcircle(nodeSize / 2, nodeSize / 2, nodeSize / 2);
          setfillcolor(BLACK);
          solidcircle(nodeSize / 2, nodeSize / 2, nodeSize / 5);
          SetWorkingImage();
          putTimage(food[k].x - nodeSize / 2 + mapX, food[k].y - nodeSize / 2 + mapY, &imgFood);
        }
      }
    }
  }
​
  // 绘制界面
  void Draw()
{
    putimage(mapX, mapY, imgMap);
    DrawFood();
    Ai* temp = ai->next;
    while (temp != ai)
    {
      temp->ais->ShowBody();
      temp = temp->next;
    }
    temp->ais->ShowBody();
    player->IsDead();
    player->ShowBody();
    player->Print();
    FlushBatchDraw();
  }
​
  // 运行
  void Running()
{
    short ddx = 0;
    short ddy = 0;
    time_t ct = clock() - time_t(100);
    Ai* temp = ai->next;
    while (temp != ai)
    {
      temp->ais->ct = clock();
      temp = temp->next;
    }
    temp->ais->ct = clock();
    temp = temp->next;
    int ex = 0;
    bool isFast = false;
​
    while (!(GetAsyncKeyState(VK_ESCAPE) & 0x8000) && !player->isDead)
    {
      if (GetAsyncKeyState('P') & 0x8000)
        ret = _getwch();
      if (clock() - ct > flushTime)
      {
        ct = clock();
        isFast = (msg.mkLButton || msg.mkRButton) ? true : false;
        player->Move(ex, mapX, mapY, ddx, ddy);
        if (isFast)
        {
          player->Move(ex, mapX, mapY, ddx, ddy);
          if (rand() % 1000 < 100)
            ex -= 2;
        }
        Draw();
      }
      if (clock() - temp->ais->ct > flushTime && !player->isDead)
      {
        temp->ais->ct = clock();
        temp->ais->Move(ex);
        if (temp->ais->isDead)
        {
          delete temp->ais;
          temp->ais = new AI(player);
          temp->ais->ct = clock();
        }
        else if (temp->ais->isFast)
        {
          temp->ais->Move(ex);
          if (temp->ais->isDead)
          {
            delete temp->ais;
            temp->ais = new AI(player);
            temp->ais->ct = clock();
          }
        }
        ai = ai->next;
        temp = temp->next;
      }
    }
  }
​
private:
  int flushTime;
  Player* player;
  typedef struct _AI
  {
    AI* ais;
    struct _AI* next;
  }Ai;
  Ai* ai;
};
​
​
////////// 主函数 //////////
int main()
{
  initgraph(ScreenWidth, ScreenHeight);
  srand((unsigned)time(NULL));
​
  Game game;
  game.Running();
  settextcolor(BLACK);
  settextstyle(50, 0, _T("微软雅黑"));
  outtextxy((ScreenWidth - textwidth(_T("游戏结束"))) / 2, ScreenHeight / 3, _T("游戏结束"));
  settextstyle(20, 0, _T("微软雅黑"));
  outtextxy((ScreenWidth - textwidth(_T("按任意键退出"))) / 2, ScreenHeight / 4 * 3 + 50, _T("按任意键退出"));
  FlushBatchDraw();
​
  while (_kbhit())
    ret = _getwch();
  ret = _getwch();
  closegraph();
  return 0;
}           

大家赶紧去动手试试吧!

此外,我也给大家分享我收集的其他资源,从最零基础开始的教程到C语言C++项目案例,帮助大家在学习C语言的道路上披荆斩棘!

编程学习书籍分享:

【项目实战】轻松实现C/C++大作业:贪吃蛇大作战游戏!

编程学习视频分享:

【项目实战】轻松实现C/C++大作业:贪吃蛇大作战游戏!

整理分享(多年学习的源码、项目实战视频、项目笔记,基础入门教程)最重要的是你可以在群里面交流提问编程问题哦!

对于C/C++感兴趣可以关注小编在后台私信我:【编程交流】一起来学习哦!可以领取一些C/C++的项目学习视频资料哦!已经设置好了关键词自动回复,自动领取就好了!