c++贪吃蛇游戏-详细解释-非单纯贴代码

本文详细解析了贪吃蛇游戏的实现过程,包括游戏界面、蛇的移动逻辑、食物生成与碰撞检测等核心内容,适合游戏开发初学者学习。

先说明下:本文来源:https://blog.youkuaiyun.com/silence1772/article/details/55005008

写在前面,这个项目,希望大家先下载下来,玩一玩。然后2天左右把代码敲一遍。再花一到两天写个博客,写下自己的理解,这样自己就能比较清楚。

github网址: https://github.com/LLM1602/greedy_snake.git

一:游戏演示

 

二:游戏思路框架介绍

   大体分为以下个步骤

(1)开始界面:蛇的移动,以及SNAKE的移动与呈现。

(2)进入界面:菜单的绘制(难度选择)以及地图(也就是围墙)绘制。

(3)游戏界面:包括食物、蛇的动态出现、移动,以及围墙右侧的文字(分数、难度等的成像)的绘制。

三:游戏代码目录以及代码整个层次关系介绍

(1)项目文件目录:  

         目录分为:.cpp文件和.h文件,是为了方便文件之间的互相调用。

         .h文件:主要是类的函数以及成员变量的声明。

         .cpp文件:主要是相应类的函数的具体实现。

         

(2)项目层次关系图

         这里说明,方框里直接采用类的名称表示相应关系。这幅图大概说了各个类之间的了个调用关系。

         

         

四:各个类的讲解

(1): tools类

        a): tools.h

#ifndef TOOLS_H
#define TOOLS_H


void SetWindowSize(int cols, int lines);//设置游戏窗口的大小
void SetCursorPosition(const int x, const int y);//设置光标位置,用来输出文字或者空格(覆盖)
void SetColor(int colorID);//设置文本颜色
void SetBackColor();//设置文本背景颜色

#endif // TOOLS_H

       b): tools.cpp

         以下几个点需要注意下:

         1)SetWindowSize()里的,system(cmd)是个固定用法,这是一个库函数,另外由于一个图形■占两个字符,故宽度乘以2。

         2)SetCursorPosition()里的,COORD 是个结构体,含有两个成员变量x,y,刚好用来表示光标的位置。再调用   

              SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), position);库函数,也就把光标移到position的位置

         3)同理也是一个库函数,SetConsoleTextAttribute():设置文本颜色。

#include "tools.h"
#include <windows.h>
#include <stdio.h>

void SetWindowSize(int cols, int lines)//设置窗口大小
{
    system("title 贪吃蛇");//设置窗口标题,黑款左上角会显示贪吃蛇,固定的“title+....."
    char cmd[30];
    sprintf(cmd, "mode con cols=%d lines=%d", cols * 2, lines);//一个图形■占两个字符,故宽度乘以2
    system(cmd);//system(mode con cols=88 lines=88):设置窗口宽度和高度,固定的库函数以及写法
}

void SetCursorPosition(const int x, const int y)//设置光标位置,相当于是个接口,还要调用windows里 的函数,SetConsoleCursorPosition
{
    //懂了
    COORD position;//COORD:固定的结构体变量,有两个成员X,Y
    position.X = x * 2 ;//一个图形■占两个字符,故宽度乘以2
    position.Y = y;
    SetConsoleCursorPosition(GetStdHandle(STD_OUTPUT_HANDLE), position);
    //可直接记住即可。
    //GetStdHandle(STD_OUTPUT_HANDLE):标准输出程序的句柄
    //SetConsoleCursorPosition:在写入输出之前将光标移动到所需位置,即(x,y)的位置m
}

void SetColor(int colorID)//设置文本颜色
{
    //懂了
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE), colorID);
    //GetStdHandle(STD_OUTPUT_HANDLE):固定输出句柄
    //
}

void SetBackColor()//设置文本背景色
{
    //懂了
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
                            FOREGROUND_BLUE |
                            BACKGROUND_BLUE |
                            BACKGROUND_GREEN |
                            BACKGROUND_RED );
}

 

(2): point类

     a): point.h

#ifndef POINT_H
#define POINT_H
class Point
{
public:
    Point(){};
    Point(const int x,const int y) :x(x),y(y){};//构造函数
    void Print();//打印地图需要用到的正方形方块
    void PrintCircular();//打印蛇需要的圆形块
    void Clear();//打印空格,用以覆盖蛇的尾部,就是蛇在移动过程中,其实是把尾部的图形用空格覆盖,在头部重新加入一个point的点进去,再绘制这条蛇
    void ChangePosition(const int x,const int y);//改变坐标
    bool operator == (const Point& point ){ return (point.x == this->x) &&(point.y == this->y) ;};//重载 == 运算符
    int GetX(){return this->x;};//得到坐标
    int GetY(){return this->y;};
private:
    int x,y;
};
#endif // POINT_H

    b): point.cpp

         注意下:

         1)Clear()函数是通过打印空格来覆盖掉原来的方块,

#include "point.h"
#include "tools.h"
#include <iostream>


void Point::Print()//输出方块
{
    //懂了
    SetCursorPosition(x,y);
    std::cout<<"■" ;//Alt+41462,一个方块占2个字节,
}

void Point::PrintCircular()//输出图形
{
    //懂啦,打印蛇
    SetCursorPosition(x,y);
    std::cout<<"●";//●
}
void Point::Clear()//清除输出
{
    //懂了,
    SetCursorPosition(x,y);//清除(x,y)这个点,不是真正清除,是通过覆盖,用空格来覆盖原来的点
    std::cout<<"  ";//此处是两个空格,因为都是占了2个字节的
}
void Point::ChangePosition(const int x,const int y)//改变坐标
{
    //懂啦
    this->x = x;
    this->y = y;
}


(3): startinterface类:

      a): startinterface.h

           需要说明下:

           1) speed是动画显示的速度

           2)其次看两个双端队列,startsnake(存储开始动画中那个v字形一样的蛇),starttext(SNAKE的那个文字)

           3)这里其实是把屏幕左上角当作坐标系的原点,横轴向右是X轴正方向,竖轴向下是y轴正方向。自己可以试着把这些点在纸上描绘以下,就能明白了,尤其是那个v字形的蛇。本人的草稿这在里给大家看看,字丑哈。

 

 

代码:

#ifndef STRATINTERFACE_H
#define STARTINTERFACE_H

#include <deque>
#include <vector>
#include "point.h"

class StartInterface
{
public:
    StartInterface() : speed(500) {
        startsnake.emplace_back(Point(0,14));//Éß,蛇刚开始的像v字形一样
        startsnake.emplace_back(Point(1,14));
        startsnake.emplace_back(Point(2,15));
        startsnake.emplace_back(Point(3,16));
        startsnake.emplace_back(Point(4,17));
        startsnake.emplace_back(Point(5,18));
        startsnake.emplace_back(Point(6,17));
        startsnake.emplace_back(Point(7,16));
        startsnake.emplace_back(Point(8,15));
        startsnake.emplace_back(Point(9,14));

        textsnake.emplace_back(Point(-26, 14));//S,刚开始SNAKE的点在X轴的负半轴
        textsnake.emplace_back(Point(-25, 14));
        textsnake.emplace_back(Point(-27, 15));
        textsnake.emplace_back(Point(-26, 16));
        textsnake.emplace_back(Point(-25, 17));
        textsnake.emplace_back(Point(-27, 18));
        textsnake.emplace_back(Point(-26, 18));

        textsnake.emplace_back(Point(-23, 14));//N
        textsnake.emplace_back(Point(-23, 15));
        textsnake.emplace_back(Point(-23, 16));
        textsnake.emplace_back(Point(-23, 17));
        textsnake.emplace_back(Point(-23, 18));
        textsnake.emplace_back(Point(-22, 15));
        textsnake.emplace_back(Point(-21, 16));
        textsnake.emplace_back(Point(-20, 17));
        textsnake.emplace_back(Point(-19, 14));
        textsnake.emplace_back(Point(-19, 15));
        textsnake.emplace_back(Point(-19, 16));
        textsnake.emplace_back(Point(-19, 17));
        textsnake.emplace_back(Point(-19, 18));

        textsnake.emplace_back(Point(-17, 18));//A
        textsnake.emplace_back(Point(-16, 17));
        textsnake.emplace_back(Point(-15, 16));
        textsnake.emplace_back(Point(-14, 15));
        textsnake.emplace_back(Point(-14, 16));
        textsnake.emplace_back(Point(-13, 14));
        textsnake.emplace_back(Point(-13, 16));
        textsnake.emplace_back(Point(-12, 15));
        textsnake.emplace_back(Point(-12, 16));
        textsnake.emplace_back(Point(-11, 16));
        textsnake.emplace_back(Point(-10, 17));
        textsnake.emplace_back(Point(-9, 18));

        textsnake.emplace_back(Point(-7, 14));//K
        textsnake.emplace_back(Point(-7, 15));
        textsnake.emplace_back(Point(-7, 16));
        textsnake.emplace_back(Point(-7, 17));
        textsnake.emplace_back(Point(-7, 18));
        textsnake.emplace_back(Point(-6, 16));
        textsnake.emplace_back(Point(-5, 15));
        textsnake.emplace_back(Point(-5, 17));
        textsnake.emplace_back(Point(-4, 14));
        textsnake.emplace_back(Point(-4, 18));

        textsnake.emplace_back(Point(-2, 14));//E
        textsnake.emplace_back(Point(-2, 15));
        textsnake.emplace_back(Point(-2, 16));
        textsnake.emplace_back(Point(-2, 17));
        textsnake.emplace_back(Point(-2, 18));
        textsnake.emplace_back(Point(-1, 14));
        textsnake.emplace_back(Point(-1, 16));
        textsnake.emplace_back(Point(-1, 18));
        textsnake.emplace_back(Point(0, 14));
        textsnake.emplace_back(Point(0, 16));
        textsnake.emplace_back(Point(0, 18));
    }
    void PrintFirst();//蛇(v字形)出现再界面上
    void PrintSecond();//蛇从左移动到右,
    void PrintThird();//蛇逐渐消失
    void PrintText();//SNAKE文字的移动
    void ClearText();//SNAKE文字的消失
    void Action();
private:
    std::deque<Point> startsnake;//开始动画中的蛇
    std::vector<Point> textsnake;//开始动画中的文字
    int speed;//动画的速度
};
#endif // STRATINTERFACE_H



       b): start

评论 10
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值