C++实现贪吃蛇游戏

 更新时间:2020年12月27日 12:36:11   作者:RanDoll_  
这篇文章主要为大家详细介绍了C++实现贪吃蛇游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

一、基本思路

制作贪吃蛇游戏,首先必须要有的材料是蛇和得分的食物;其次是游戏逻辑,1.要能使用键盘控制蛇的移动;2.食物被吃掉要能再次生成并且蛇要做出相应变化;3.蛇咬到自己的身体和墙会死亡;最后是图形界面的显示。

二、蛇和食物

蛇和食物使用结构体来储存,代码比较简单。

#include <graphics.h>
#include <stdio.h>
#include <time.h>
#include <conio.h>

#define SIZE 30
#define N 1000 //蛇的长度限制

struct Coor
{
 int x;
 int y;
};

enum Ch{ up = 72,down = 80,left = 75,right = 77,P=112 };//ASCII码 枚举

struct Snake
{
 int n;
 Coor scr[N];
 Ch ch;//蛇的方向
}snake;


struct Food
{
 Coor fsr;//食物坐标
 int flag;//标记食物是否被吃掉
}food;

三、游戏逻辑实现

1. 键盘控制蛇的移动

蛇的移动和方向改变主要是依靠SnakeMove和ChangeSnake两个函数实现,ChangeSnake函数通过键盘输入的ch值来判断用户对蛇方向的控制,从而修改snake.ch(蛇的方向)的值,然后SnakeMove函数通过修改后的snake.ch的值来控制蛇的移动,如果没有新的ch值从键盘输入,蛇会一直保持原来的方向移动到地图边界。

void SnakeMove() {
 for (int i = snake.n - 1; i > 0; i--) {
 snake.scr[i].x = snake.scr[i - 1].x;
 snake.scr[i].y = snake.scr[i - 1].y;

 }
 switch (snake.ch) {
 case up:
 snake.scr[0].y -= SIZE;
 break;
 
 case down:
 snake.scr[0].y += SIZE;
 break;
 
 case left:
 snake.scr[0].x -= SIZE;
 break;
 case right:
 snake.scr[0].x += SIZE;
 break;
 }
}

void ChangeSnake() {
 switch (getch()) {
 case 72:
 if (snake.ch != down) {
 snake.ch = up;
 }
 break;
 case 80:
 if (snake.ch != up) {
 snake.ch = down;
 }
 break;
 case 75:
 if (snake.ch != right) {
 snake.ch = left;
 }
 break;
 case 77:
 if (snake.ch != left) {
 snake.ch = right;
 }
 break;
 case 112:
 system("pause");
 }
}

2. 食物被吃的触发事件

当食物被蛇吃掉(蛇头坐标和食物坐标重合),蛇身长度加一,食物存在标记置0;

void EatFood() {
 if (snake.scr[0].x == food.fsr.x&&snake.scr[0].y == food.fsr.y) {
 snake.n++;
 food.flag = 0;
 }
}

3. 游戏结束事件

当蛇头触碰边界或者自己的身体(蛇头坐标超出地图边界或与蛇身任一坐标重合),窗口打印OverGame函数中预设的界面,并且关闭程序。

void GameBreak() {
 
 //撞墙
 if (snake.scr[0].y < -1 || snake.scr[0].y>706 || snake.scr[0].x < -1 || snake.scr[0].x>946) {
 OverGame();
 }
 //撞身体
 for (int i = snake.n - 1; i > 0; i--) {
 if (snake.scr[0].x == snake.scr[i].x&&snake.scr[0].y == snake.scr[i].y) {
 OverGame();

 }
 }
}


void OverGame() {
 cleardevice();
 settextcolor(RED);
 settextstyle(100, 0, L"黑体");
 outtextxy(400, 250, L"菜");
 Sleep(2000);
 exit(0);
}

四、图形界面的显示

1. 素材准备

需要准备的素材有蛇头的图片(如果不是对称图形,可以准备四个不同方向的图片),蛇身的图片(如果制作蛇头和蛇身一样的话则可以直接使用蛇头的图片),得分果实的图片。

2.背景制作及图片导入

将所有图片放入vs的项目文件夹即可直接在代码中通过loadimage函数对图片名字调用,GameInit函数主要进行游戏初始化,将蛇长度置为一,坐标置为(0,0),食物存在标记置零,打印游戏欢迎界面(GameStart函数)。

IMAGE snakeleft, snakeright, snakedown, snakeup, she, shiwu;
void GameInit() {
 initgraph(960, 720);
 setbkcolor(BLACK);
 cleardevice();

 loadimage(&snakeleft, L"蛇头.jpg", SIZE, SIZE);
 loadimage(&snakeright, L"蛇头.jpg", SIZE, SIZE);
 loadimage(&snakeup, L"蛇头.jpg", SIZE, SIZE);
 loadimage(&snakedown,L"蛇头.jpg", SIZE, SIZE);
 loadimage(&she, L"蛇身1.jpg", SIZE, SIZE);
 loadimage(&shiwu, L"果实.jpg", SIZE, SIZE);

 //蛇初始化
 snake.scr[0].x = 0;
 snake.scr[0].y = 0;
 snake.n = 1;
 snake.ch = P;

 food.flag = 0;

 GameStart();

}

void GameStart() {
 cleardevice();
 settextcolor(WHITE);
 settextstyle(50, 0, L"黑体");
 outtextxy(350, 250, L"游戏开始");
 outtextxy(300, 400, L"按“P”键暂停");
 system("pause");
}

3.蛇和食物的打印

当食物存在标记为0时调用FoodCoor函数,随机重置食物坐标并且将标记置1,图片的打印主要依靠putimage函数,函数用法比较简单,这里就不多说了。

void SnakePaint(IMAGE snakeright, IMAGE snakeleft, IMAGE snakedown, IMAGE snakeup, IMAGE she) {
 switch (snake.ch) {
 case up:
 putimage(snake.scr[0].x, snake.scr[0].y, &snakeup);
 break;

 case down:
 putimage(snake.scr[0].x, snake.scr[0].y, &snakedown);
 break;

 case left:
 putimage(snake.scr[0].x, snake.scr[0].y, &snakeleft);
 break;
 case right:
 putimage(snake.scr[0].x, snake.scr[0].y, &snakeright);
 break;
 }
 for(int i=snake.n-1;i>0;i--){
 putimage(snake.scr[i].x, snake.scr[i].y, &she);
 }

}

void FoodCoor() {
 srand((unsigned int)time(NULL));
 food.fsr.x = (rand() % 31 + 1)*SIZE; 
 food.fsr.y = (rand() % 23 + 1)*SIZE; 
 food.flag = 1; //有食物
}


void FoodPaint(IMAGE shiwu) {
 putimage(food.fsr.x, food.fsr.y, &shiwu);
}

五、游戏的运行

首先调用GameInit函数进行初始化,第一层while保证游戏始终运行,第二层while是保证当没有键盘输入时,游戏会按设计好的逻辑运行和判断,而当有键盘输入时,调用ChangeSnake函数判断用户对蛇的控制,从而进行相应的改变。

int main() {
 GameInit();
 while (1) {
 while (!kbhit()) {
 if (food.flag == 0)
 FoodCoor();
 cleardevice();
 FoodPaint(shiwu); //绘制食物
 SnakeMove();
 SnakePaint(snakeright, snakeleft, snakedown, snakeup, she);
 Sleep(200-snake.n*5);
 EatFood();
 GameBreak();
 }
 ChangeSnake();
 }
 return 0;
}

六、成品演示

游戏开始界面
游戏运行界面
游戏结束界面

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持脚本之家。

相关文章

  • 用位图排序无重复数据集实例代码(C++版)

    用位图排序无重复数据集实例代码(C++版)

    本文讲解如何用位图排序无重复的数据集,我们使用C++实现一下这个方法
    2013-11-11
  • C语言数据结构顺序表中的增删改(尾插尾删)教程示例详解

    C语言数据结构顺序表中的增删改(尾插尾删)教程示例详解

    这篇文章主要为大家介绍了C语言数据结构顺序表中的增删改教程示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步
    2022-02-02
  • C 语言基础之C语言的常见关键字

    C 语言基础之C语言的常见关键字

    C语言中有一些预先定义的字符串,他们本身被赋予了自身的功能。并且我们在定义变量的时候,不能去抢他们的名字来用。他们就是今天的主角:关键字,下面文章将给大家做详细介绍
    2021-09-09
  • OpenCV实现相机标定板

    OpenCV实现相机标定板

    这篇文章主要为大家详细介绍了OpenCV实现相机标定板,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-04-04
  • C++中vector<vector<int> >的基本使用方法

    C++中vector<vector<int> >的基本使用方法

    vector<vector<int> >其实就是容器嵌套容器,外层容器的元素类型是vector<int>,下面这篇文章主要给大家介绍了关于C++中vector<vector<int> >的基本使用方法,文中通过实例代码介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • Cocos2d-x人物动作类实例

    Cocos2d-x人物动作类实例

    这篇文章主要介绍了Cocos2d-x人物动作类实例,本文用大量代码和图片讲解Cocos2d-x中的动作,代码中同时包含大量注释说明,需要的朋友可以参考下
    2014-09-09
  • 深入详解C编写Windows服务程序的五个步骤

    深入详解C编写Windows服务程序的五个步骤

    本篇文章介绍了,使用C编写Windows服务程序的五个步骤的详细概述。需要的朋友参考下
    2013-05-05
  • Qt使用事件与定时器实现字幕滚动效果

    Qt使用事件与定时器实现字幕滚动效果

    我们经常能够在外面看到那种滚动字幕,那么本文就拿Qt来做一个吧,本文将使用事件与定时器实现字幕滚动的效果,感兴趣的小伙伴可以了解一下
    2023-06-06
  • C++数据结构之堆详解

    C++数据结构之堆详解

    本文详细讲解了C++数据结构之堆,文中通过示例代码介绍的非常详细。对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2022-04-04
  • 深入浅析C++多态性与虚函数

    深入浅析C++多态性与虚函数

    多态是指同样的消息被不同的对象接收时导致不同的行为。本文通过实例代码给大家介绍了C++多态性与虚函数的相关知识,感兴趣的朋友一起看看吧
    2020-02-02

最新评论