21xrx.com
2024-11-05 19:32:25 Tuesday
登录
文章检索 我的文章 写文章
C++贪吃蛇代码完整版
2023-07-07 09:47:35 深夜i     --     --
C++程序设计 贪吃蛇游戏 代码完整版

贪吃蛇是一款经典的游戏,随着技术的不断进步,现在可以在电脑上玩贪吃蛇游戏。而C++是一种流行的编程语言,可以用来开发游戏。下面展示一个完整的C++贪吃蛇代码,让大家学习和了解游戏开发的流程。

贝叶斯定理游戏架构:

·组成部分:主函数、画布、蛇类、食物类;

·主函数:建立窗口、初始化游戏、实时控制;

·画布:控制游戏显示;

·蛇类:控制蛇的运动、身体长度等;

·食物类:控制当前食物的位置、随机产生等。

主函数部分的代码如下:

#include

#include

#include

#include"head.h"

#define DIRECTION_SLIDES 8

#define DIRECTION_UP 0

#define DIRECTION_DOWN 1

#define DIRECTION_LEFT 2

#define DIRECTION_RIGHT 3

bool DirecSlides[DIRECTION_SLIDES];

int main() {

  HINSTANCE hInstance = GetModuleHandle(NULL);

  HWND hwnd = CreateWindow(L"Static",L"贪吃蛇",WS_POPUP,0,0,MAX_WIDTH,MAX_HEIGHT,NULL,NULL,hInstance,NULL);

  ShowWindow(hwnd,SW_SHOWNORMAL);

  UpdateWindow(hwnd);

  GameCanvas* canvas = new GameCanvas(hwnd);

  Snake* snake = new Snake(canvas);

  Food* food = new Food(canvas);

  if(!snake->isValid() || !food->isValid()) {

    delete snake;

    delete food;

    delete canvas;

    MessageBox(hwnd,L"错误!无法初始化!",L"错误",MB_ICONERROR);

    return -1;

  }

  canvas->draw(snake,food);

  srand(time(NULL));

  while(true) {

    MSG msg;

    if(!DirecSlides[DIRECTION_UP] && GetAsyncKeyState(VK_UP) < 0) {

      DirecSlides[DIRECTION_UP] = true;

      if(snake->getDirection() != DIRECTION_DOWN)

        snake->setDirection(DIRECTION_UP);

    }

    if(!DirecSlides[DIRECTION_DOWN] && GetAsyncKeyState(VK_DOWN) < 0) {

      DirecSlides[DIRECTION_DOWN] = true;

      if(snake->getDirection() != DIRECTION_UP)

        snake->setDirection(DIRECTION_DOWN);

    }

    if(!DirecSlides[DIRECTION_LEFT] && GetAsyncKeyState(VK_LEFT) < 0) {

      DirecSlides[DIRECTION_LEFT] = true;

      if(snake->getDirection() != DIRECTION_RIGHT)

        snake->setDirection(DIRECTION_LEFT);

    }

    if(!DirecSlides[DIRECTION_RIGHT] && GetAsyncKeyState(VK_RIGHT) < 0) {

      DirecSlides[DIRECTION_RIGHT] = true;

      if(snake->getDirection() != DIRECTION_LEFT)

        snake->setDirection(DIRECTION_RIGHT);

    }

    if(GetAsyncKeyState(VK_ESCAPE) < 0)

      break;

    if(snake->isAte(food)) {

      snake->addLength(food->getType());

      food->next();

    }

    if(snake->move()) {

      canvas->draw(snake,food);

      Sleep(snake->getSpeed());

      continue;

    }

    canvas->draw(snake,food);

    MessageBox(hwnd,L"游戏结束!",L"提示",MB_ICONINFORMATION);

    break;

  }

  delete snake;

  delete food;

  delete canvas;

  return 0;

}

这段代码主要负责游戏的初始化和实时控制,包括创建窗口,初始化游戏和实时控制用户的输入等。同时,它还会调用画布、蛇类和食物类的函数来绘制游戏画面。

画布类的代码如下:

class GameCanvas {

public:

  GameCanvas(HWND hwnd) {

    HDC hDC = GetDC(hwnd);

    m_memDC = CreateCompatibleDC(hDC);

    m_bitMap = CreateCompatibleBitmap(hDC,MAX_WIDTH,MAX_HEIGHT);

    ReleaseDC(hwnd,hDC);

    m_oldBitMap = (HBITMAP)SelectObject(m_memDC,m_bitMap);

  }

  ~GameCanvas() {

    SelectObject(m_memDC,m_oldBitMap);

    DeleteObject(m_bitMap);

    DeleteDC(m_memDC);

  }

  HDC get() const

    return m_memDC;

  void draw(Snake* snake,Food* food) {

    FillRect(m_memDC,&m_rc,BLACK_BRUSH);

    snake->draw(m_memDC);

    food->draw(m_memDC);

    StretchBlt(GetDC(m_hwnd),0,0,MAX_WIDTH,MAX_HEIGHT,m_memDC,0,0,MAX_WIDTH,MAX_HEIGHT,SRCCOPY);

  }

  void setRect(RECT& rc)

    m_rc = rc;

private:

  HDC m_memDC;

  HBITMAP m_bitMap;

  HBITMAP m_oldBitMap;

  RECT m_rc;

};

该代码负责绘制游戏画面,包括绘制蛇、食物以及背景等元素。它使用了窗口句柄和HDC等系统变量,能够控制游戏画面的呈现。

蛇类的代码如下:

class Snake {

public:

  Snake(GameCanvas* canvas) :

      m_canvas(canvas),

      m_headX(canvas->getWidth()/2),

      m_headY(canvas->getHeight()/2),

      m_length(5),

      m_direction(DIRECTION_DOWN),

      m_speed(100),

      m_step(10) {

    m_bodyArray = new BodyElement[m_length];

    for(int i=0; i

      m_bodyArray[i].x = m_headX;

      m_bodyArray[i].y = m_headY-i*m_step;

      if(i == 0)

        m_bodyArray[i].type = BODY_TYPE_HEAD;

      else if(i == m_length-1)

        m_bodyArray[i].type = BODY_TYPE_TAIL;

      else

        m_bodyArray[i].type = BODY_TYPE_NORMAL;

    }

  }

  ~Snake() {

    delete[] m_bodyArray;

  }

  bool isValid() {

    return m_canvas->getWidth()/m_step > 0 && m_canvas->getHeight()/m_step > 0;

  }

  int getDirection() const {

    return m_direction;

  }

  void setDirection(int direction) {

    m_direction = direction;

  }

  int getSpeed() const {

    return m_speed;

  }

  bool isAte(Food* food) {

    return m_headX == food->getX() && m_headY == food->getY();

  }

  bool move() {

    int newX = m_headX;

    int newY = m_headY;

    switch(m_direction) {

    case DIRECTION_UP:

      newY -= m_step;

      break;

    case DIRECTION_DOWN:

      newY += m_step;

      break;

    case DIRECTION_LEFT:

      newX -= m_step;

      break;

    case DIRECTION_RIGHT:

      newX += m_step;

      break;

    }

    if(newX < 0 || newX > m_canvas->getWidth() || newY < 0 || newY > m_canvas->getHeight())

      return false;

    if(isOverlap(newX,newY))

      return false;

    int oldX = m_headX;

    int oldY = m_headY;

    m_headX = newX;

    m_headY = newY;

    if(m_bodyArray[m_length-1].type == BODY_TYPE_TAIL) {

      m_bodyArray[m_length-1].x = oldX;

      m_bodyArray[m_length-1].y = oldY;

      m_bodyArray[m_length-1].type = BODY_TYPE_NORMAL;

    }

    for(int i=m_length-2; i>=0; --i) {

      m_bodyArray[i+1].x = m_bodyArray[i].x;

      m_bodyArray[i+1].y = m_bodyArray[i].y;

      m_bodyArray[i+1].type = m_bodyArray[i].type;

    }

    m_bodyArray[0].x = m_headX;

    m_bodyArray[0].y = m_headY;

    m_bodyArray[0].type = BODY_TYPE_HEAD;

    return true;

  }

  void addLength(int type) {

    if(m_length < MAX_LENGTH) {

      ++m_length;

      m_bodyArray[m_length-1].type = (type == FOOD_TYPE_BIG) ? BODY_TYPE_BIG : BODY_TYPE_NORMAL;

    }

    if(m_speed > MIN_SPEED)

      m_speed -= SPEED_LEVEL;

  }

  void draw(HDC hdc) const {

    for(int i=0; i

      HPEN Hpen;

      if(m_bodyArray[i].type == BODY_TYPE_BIG)

        Hpen = CreatePen(PS_SOLID,10,RGB(0,255,0));

      else if(m_bodyArray[i].type == BODY_TYPE_HEAD)

        Hpen = CreatePen(PS_SOLID,10,RGB(255,0,0));

      else if(m_bodyArray[i].type == BODY_TYPE_TAIL)

        Hpen = CreatePen(PS_SOLID,10,RGB(0,0,255));

      else

        Hpen = CreatePen(PS_SOLID,10,RGB(255,255,255));

      HPEN oldPen = (HPEN)SelectObject(hdc,Hpen);

      MoveToEx(hdc,m_bodyArray[i].x,m_bodyArray[i].y,NULL);

      if(i != m_length-1)

        LineTo(hdc,m_bodyArray[i+1].x,m_bodyArray[i+1].y);

      SelectObject(hdc,oldPen);

      DeleteObject(Hpen);

    }

  }

private:

  bool isOverlap(int x,int y) {

    for(int i=1; i

      if(m_bodyArray[i].x == x && m_bodyArray[i].y == y)

        return true;

    }

    return false;

  }

private:

  GameCanvas* m_canvas;

  int m_headX;

  int m_headY;

  BodyElement* m_bodyArray;

  int m_length;

  int m_direction;

  int m_speed;

  int m_step;

};

该代码主要负责控制蛇的运动、身体长度等属性。它使用了游戏画布的指针以及窗口句柄等系统变量,能够控制蛇的状态和显示。

食物类的代码如下:

class Food {

public:

  Food(GameCanvas* canvas) :

      m_canvas(canvas),

      m_size(10),

      m_type(FOOD_TYPE_NORMAL) {

    int wCount = canvas->getWidth() / m_size;

    int hCount = canvas->getHeight() / m_size;

    m_maxX = wCount * m_size;

    m_maxY = hCount * m_size;

    next();

  }

  bool isValid() const {

    return m_maxX > m_size && m_maxY > m_size;

  }

  void next() {

    m_x = m_size * (rand() % (m_maxX/m_size));

    m_y = m_size * (rand() % (m_maxY/m_size));

    m_type = (rand() % 100) < BIG_FOOD_PROB ? FOOD_TYPE_BIG : FOOD_TYPE_NORMAL;

  }

  void draw(HDC hdc) const {

    HPEN Hpen;

    if(m_type == FOOD_TYPE_BIG)

      Hpen = CreatePen(PS_SOLID,10,RGB(0,255,0));

    else

      Hpen = CreatePen(PS_SOLID,10,RGB(255,255,0));

    HPEN oldPen = (HPEN)SelectObject(hdc,Hpen);

    Ellipse(hdc,m_x,m_y,m_x+m_size,m_y+m_size);

    SelectObject(hdc,oldPen);

    DeleteObject(Hpen);

  }

  int getX() const {

    return m_x;

  }

  int getY() const {

    return m_y;

  }

  int getType() const {

    return m_type;

  }

private:

  GameCanvas* m_canvas;

  int m_x;

  int m_y;

  int m_maxX;

  int m_maxY;

  int m_size;

  int m_type;

  static const int BIG_FOOD_PROB = 20;

};

该代码主要负责控制食物的位置和类型等属性。它同样使用了游戏画布的指针等系统变量,能够控制食物的类型和显示。需要注意的是,它使用了rand()函数来生成随机数,需要包含cstdlib和ctime头文件。

这是一个完整的C++贪吃蛇代码,包括了游戏的基本组成部分,可以通过学习和修改来深入了解游戏开发的流程。同时,可能还有一些细节需要优化,比如添加计分板和游戏结束后的操作等,读者们可以根据自己的需求进行扩展。

  
  

评论区

{{item['qq_nickname']}}
()
回复
回复