C++貪喫蛇代碼的閱讀筆記(二):Startinterface開始動畫的實現

1. 原理解釋

先來看下頭文件中包含哪些東西,包括容器deque、vector,以及之前介紹過的Point類,Point聲明的對象,主要就是負責控制檯上點信息的打印和清除,後面的具體實現部分中也會使用其Print()和Clear()成員函數,沒看過的小夥伴,可以先去瀏覽下面這個地址:

https://blog.csdn.net/AnDiXL/article/details/105148754

開頭動畫整體分爲兩大部分,第一部分是蛇移動的動畫,第二部分是SNAKE文字進入的動畫,動畫示意圖如下:

開始動畫

其中第一部分用deque實現,分爲如下三個階段:

1). deque是一個雙端隊列,用它存儲點的對象,這些點組成完整的蛇身,用一個for-loop將其中的點依次打印,每打印一個點停頓一會兒,實現動態效果,全部打印完之後,蛇的整個身體出現,接下來進入第二階段;

2). 蛇開始從左邊界移動至右邊界,這部分蛇每次移動都要計算其下一個點的座標,然後將其打印出來,同時還要將蛇尾即deque的首元素去掉,並清除對應座標的圖像信息;

3). 第三階段,從deque的隊尾開始依次擦除圖像信息即可完成蛇消失的過程。

第二部分SNAKE文字的移動過程與第一部分類似,但最後只需SNAKE停到屏幕中央,因此不需要同時對首尾對象進行操作,選用vector存儲其中的點。

其頭文件代碼如下,聲明對象時就在初始化列表中完成了點的存儲:

#ifndef STRATINTERFACE_H
#define STARTINTERFACE_H

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

class StartInterface
{
public:
    StartInterface() : speed(35) {
        startsnake.emplace_back(Point(0,14));//蛇的形狀
        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));
        
        //下面是SNAKE五個字母的實現
        textsnake.emplace_back(Point(-26, 14));//S
        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();
    void PrintSecond();
    void PrintThird();
    void PrintText();
    void ClearText();
    void Action();
private:
    std::deque<Point> startsnake;//開始動畫中的蛇
    std::vector<Point> textsnake;//開始動畫中的文字
    int speed;//動畫的速度
};
#endif // STRATINTERFACE_H

 

2. 具體實現

第一部分:

1). 一個for循環遍歷打印,每打印一個點停頓一下,這裏使用包含在window.h中的Sleep()實現停頓,具體代碼如下:

void StartInterface::PrintFirst()//蛇從左邊出現到完全出現的過程
{
    for (auto& point : startsnake)
    {
        point.Print();
        Sleep(speed);
    }
}

2). 由於控制檯大小設置的寬度爲40,整個蛇身出現佔據了0~9列,因此第二階段移動是從第10列移動至39列,每次移動只需要計算出蛇頭要前進的下一個位置即可,而由於是從左向右移動,因此列座標 i 的增加是線性的,只需要計算下個位置的橫座標 j 即可,具體代碼如下:

void StartInterface::PrintSecond()//蛇從左向右移動的過程
{
    for (int i = 10; i != 40; ++i) //蛇頭需要從10移動到40
    {
        /*計算蛇頭的下一個位置,並將其壓入startsnake中,繪製出來,將蛇尾去掉*/
        int j = ( ((i-2)%8) < 4 )?( 15 + (i-2)%8 ) : ( 21 - (i-2)%8 );
        startsnake.emplace_back( Point(i, j) );
        startsnake.back().Print();
        startsnake.front().Clear();
        startsnake.pop_front();
        Sleep(speed);
    }
}

3). 用於實現第一部分的第三階段,以及第二部分的文字平移階段,即在蛇身消失的同時,SNAKE文字開始向右平移,具體代碼如下:

void StartInterface::PrintThird()//蛇從接觸右邊到消失的過程
{
    while ( !startsnake.empty() || textsnake.back().GetX() < 33 ) //當蛇還沒消失或文字沒移動到指定位置
    {
        if ( !startsnake.empty() ) //如果蛇還沒消失,繼續移動
        {
            startsnake.front().Clear();
            startsnake.pop_front();
        }
        ClearText();//清除已有文字
        PrintText();//繪製更新位置後的文字
        Sleep(speed);
    }
}

第二部分:

SNAKE的平移過程即上段代碼中的 ClearText() 和 PrintText(),需要注意的是,GetX() 函數是獲取點的縱座標而不是橫座標,具體實現如下:

void StartInterface::PrintText()
{
    for (auto& point : textsnake)
    {
        if (point.GetX() >= 0)
            point.Print();
    }
}

void StartInterface::ClearText()
{
    for (auto& point : textsnake) //清除的同時將文字整體向右移動一格
    {
        if (point.GetX() >= 0)
            point.Clear();
        point.ChangePosition(point.GetX() + 1, point.GetY());
    }
}

因此,整個打印流程,只需創建一個StartInterface對象後,執行下面的 Action() 函數即可完成:

void StartInterface::Action()
{
    PrintFirst();
    PrintSecond();
    PrintThird();
}

 

最後,附上原作者的代碼鏈接:

https://github.com/silence1772/GreedySnake/blob/master/startinterface.cpp

https://github.com/silence1772/GreedySnake/blob/master/startinterface.h

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章