自制C++ 貪喫蛇



VS2013,把代碼複製過去應該可以直接編譯運行




#include<windows.h>
#include<conio.h>
#include<time.h>
#include<string>
using namespace std;

/*=============== all the structures ===============*/

typedef struct Frame
{
    COORD position[2];//位置
    int flag;
}Frame;//幀


/*=============== all the functions ===============*/

void SetPos(COORD a)// set cursor 設置光標
{
    HANDLE out = GetStdHandle(STD_OUTPUT_HANDLE);
    SetConsoleCursorPosition(out, a);
}

/* set cursor設置光標*/void SetPos(int i, int j)
{
    COORD pos = { i, j };
    SetPos(pos);
}

void HideCursor()
{
    CONSOLE_CURSOR_INFO cursor_info = { 1, 0 };
    SetConsoleCursorInfo(GetStdHandle(STD_OUTPUT_HANDLE), &cursor_info);
}

//把第y行,[x1, x2) 之間的座標填充爲 ch
void drawRow(int y, int x1, int x2, char ch)
{
    SetPos(x1, y);
    for (int i = 0; i <= (x2 - x1); i++)
        cout << ch;
}

//在a, b 縱座標相同的前提下,把座標 [a, b] 之間填充爲 ch
void drawRow(COORD a, COORD b, char ch)
{
    if (a.Y == b.Y)
        drawRow(a.Y, a.X, b.X, ch);
    else
    {
        SetPos(0, 25);
        cout << "error code 01:無法填充行,因爲兩個座標的縱座標(x)不相等";
        system("pause");
    }
}

//把第x列,[y1, y2] 之間的座標填充爲 ch
void drawCol(int x, int y1, int y2, char ch)
{
    int y = y1;
    while (y != y2 + 1)
    {
        SetPos(x, y);
        cout << ch;
        y++;
    }
}

//在a, b 橫座標相同的前提下,把座標 [a, b] 之間填充爲 ch
void drawCol(COORD a, COORD b, char ch)
{
    if (a.X == b.X)
        drawCol(a.X, a.Y, b.Y, ch);
    else
    {
        SetPos(0, 25);
        cout << "error code 02:無法填充列,因爲兩個座標的橫座標(y)不相等";
        system("pause");
    }
}

//左上角座標、右下角座標、用row填充行、用col填充列
void drawFrame(COORD a, COORD  b, char row, char col)
{
    drawRow(a.Y, a.X + 1, b.X - 1, row);
    drawRow(b.Y, a.X + 1, b.X - 1, row);
    drawCol(a.X, a.Y + 1, b.Y - 1, col);
    drawCol(b.X, a.Y + 1, b.Y - 1, col);
}
//點覆蓋
void drawFrame(COORD a, char r)
{
    SetPos(a.X, a.Y);
    cout << r;
}

void drawFrame(int x1, int y1, int x2, int y2, char row, char col)
{
    COORD a = { x1, y1 };
    COORD b = { x2, y2 };
    drawFrame(a, b, row, col);
}

void drawFrame(Frame frame, char row, char col)
{
    COORD a = frame.position[0];
    COORD b = frame.position[1];
    drawFrame(a, b, row, col);
}

void drawPlaying()
{
    drawFrame(0, 0, 48, 24, '=', '|');//    draw map frame;
    drawFrame(49, 0, 77, 24, '-', '|');//        draw output frame
    SetPos(52, 6);
    cout << "玩家1長度:";
    SetPos(52, 8);
    cout << "玩家2長度:";
    SetPos(52, 14);
    cout << "操作方式:";
    SetPos(52, 16);
    cout << " 玩家1 上下左右";
    SetPos(52, 17);
    cout << " 玩家2 a,s,d,w";
    SetPos(52, 19);
    cout << "  p 暫停遊戲。";
    SetPos(52, 20);
    cout << "  esc 退出遊戲。";
}

//在[a, b)之間產生一個隨機整數
int random(int a, int b)
{
    int c = (rand() % (a - b)) + a;
    return c;
}

//在兩個座標包括的矩形框內隨機產生一個座標
COORD random(COORD a, COORD b)
{
    int x = random(a.X, b.X);
    int y = random(a.Y, b.Y);
    COORD c = { x, y };
    return c;
}

//判斷是否撞到蛇身或者牆壁 點對點
bool  judgeCoordSnake(COORD spot1, COORD spot2)
{
    if (spot1.X == spot2.X)
        if (spot1.Y == spot2.Y)
            return true;
    if (spot1.X == 0 || spot1.X == 48 || spot1.Y == 0 || spot1.Y == 24)
        return true;
    return false;
}

//判斷是否撞到蛇身或者牆壁 頭對身子
bool  judgeCoordSnake(COORD spot1, COORD *snake1, COORD *snake2)
{
    for (int i = 1; i < 250; i++)
    {
        if (spot1.X == snake1[i].X)
            if (spot1.Y == snake1[i].Y)
                return false;
        if (spot1.X == snake2[i].X)
            if (spot1.Y == snake2[i].Y)
                return false;
        if (spot1.X == 0 || spot1.X == 48 || spot1.Y == 0 || spot1.Y == 24)
            return false;
    }
    return true;
}
bool  judgeCoordSnakeFood(COORD spot1, COORD spot2, COORD spot3,int& a)
{
    if (spot1.X == spot2.X)
        if (spot1.Y == spot2.Y)
        {
            a = 0;
            return true;
        }
    if (spot1.X == spot3.X)
        if (spot1.Y == spot3.Y)
        {
            a = 1;
            return true;
        }

    return false;
}
//因爲在判斷時頭部的問題所以單列出來



void printCoord(COORD a)
{
    cout << "( " << a.X << " , " << a.Y << " )";
}

int drawMenu()
{
    SetPos(30, 1);
    cout << "貪喫的大蟒蛇";
    drawRow(3, 0, 79, '-');
    drawRow(5, 0, 79, '-');
    SetPos(28, 4);
    cout << "w 和 s 選擇, k 確定";
    SetPos(15, 11);
    cout << "開始遊戲";
    SetPos(15, 13);
    cout << "結束遊戲";
    drawRow(20, 0, 79, '-');
    drawRow(22, 0, 79, '-');
    SetPos(47, 11);
    cout << "本遊戲爲雙人遊戲:";
    SetPos(51, 13);
    cout << "wasd和ijkl控制";
    SetPos(24, 21);
    cout << "製作: 威微遊戲製造廠廠長  唐宇威";
    int j = 11;
    SetPos(12, j);
    cout <<"->";
    while (1)
    {
        if (_kbhit())
        {
            char x = _getch();
            switch (x)
            {
            case 'w':
            {
                if (j == 13)
                {
                    SetPos(12, j);
                    cout << " ";
                    j = 11;
                    SetPos(12, j);
                    cout << "->";
                    SetPos(51, 13);
                    cout << "            ";
                    SetPos(47, 11);
                    cout << "準備好了嗎?";
                    SetPos(51, 13);
                    cout << "wasd和ijkl控制";
                }
                break;
            }
            case 's':
            {
                if (j == 11)
                {
                    SetPos(12, j);
                    cout << " ";
                    j = 13;
                    SetPos(12, j);
                    cout << "->";
                    SetPos(51, 13);
                    cout << "              ";
                    SetPos(47, 11);
                    cout << "結束遊戲:";
                    SetPos(51, 13);
                    cout << "要走了嗎?";
                }
                break;
            }
            case 'k':
            {
                if (j == 11)    
                    return 1;
                else exit(0);
            }
            }
        }
    }
}

/*
DWORD WINAPI MusicFun(LPVOID lpParamte)
{
//DWORD OBJ;
sndPlaySound(TEXT("bgm.wav"), SND_FILENAME|SND_ASYNC);
return 0;
}
*/


/*================== the Game Class ==================*/

class Game
{
public:
    COORD snake1[250];
    COORD snake2[250];
    COORD food[2];
    int length1;
    int length2;
    int direction1;//蛇1的頭 1上2下3左4右
    int direction2;//蛇2的頭 1上2下3左4右
    string title;
    //初始化所有
    void initFood();
    COORD randomFood();
    //初始化其中一個
    //void initThisBullet( COORD );
    //void initThisEnemy( Frame );
    void Playing();
    void Pause();
    void judgeSnake();
    void GameOver();
    void snake1ChangeDirection(char x);
    void snake2ChangeDirection(char x);
    void drawSnake1(int direction);
    void drawSnake2(int direction);
    void drawSnake1ToNull();
    void drawSnake2ToNull();
    void drawFood();
    void drawFoodToNull();
    Game()
    {
        direction1 = 1,direction2 = 1;
        snake1[0] = { 8, 15 }, snake1[1] = { 8, 16 }, snake1[2] = { 8, 17 };
        snake2[0] = { 40, 15 }, snake2[1] = { 40, 16 }, snake2[2] = { 40, 17 };
        length1 = 3, length2 = 3;
        for (int i = 3; i < 249; i++)
        {
            snake1[i] = { 0, 0 };
            snake2[i] = { 0, 0 };
        }
    }

};

//畫第一條蛇
void Game::drawSnake1(int direction)
{
    for (int i = 0; i<240; i++)
    {
        SetPos(snake1[i]);
        if (i != 0)
            cout << "O";
        else if (i == 0)
        {
            if (direction==1)
            {
                cout << "^";
            }
            else if(direction == 2)
            {
                cout << "v";
            }
            else if (direction == 3)
            {
                cout << "<";
            }
            else if (direction == 4)
            {
                cout << ">";
            }

        }

    }
}
void Game::drawSnake2(int direction)
{
    for (int i = 0; i<240; i++)
    {
        SetPos(snake2[i]);
        if (i != 0)
            cout << "X";
        else if (i == 0)
        {
            if (direction == 1)
            {
                cout << "^";
            }
            else if (direction == 2)
            {
                cout << "v";
            }
            else if (direction == 3)
            {
                cout << "<";
            }
            else if (direction == 4)
            {
                cout << ">";
            }

        }

    }
}
//把第一條蛇消失,行動時使用,只讓蛇頭蛇尾消失,這樣不會一閃一閃
void Game::drawSnake1ToNull()
{
    SetPos(snake1[0]);
    cout << " ";
    SetPos(snake1[length1]);
    cout << " ";    
}
void Game::drawSnake2ToNull()
{
    /*for (int i = length2; i<240; i++)
    {
        SetPos(snake2[i]);
        cout << " ";
    }*/
    SetPos(snake2[0]);
    cout << " ";
    SetPos(snake2[length2]);
    cout << " ";
}
//初始食物
void Game::initFood()
{
    COORD a = { 2, 2  };
    COORD b = { 24,12 };
    COORD c = { 25, 2 };
    COORD d = { 47,14 };
    food[0] = random(a, b);
    food[1] = random(c, d);
}
//隨機食物,如果有牆需要修改。
COORD Game::randomFood()
{
    COORD food;
    COORD a = { 2, 2 };
    COORD b = { 47, 23 };
    while (1)
    {
        food = random(a, b);
        if (judgeCoordSnake(food, snake1, snake2))
            return food;
    }
}
//畫出食物
void Game::drawFood()
{
    for (int i = 0; i<2; i++)
        drawFrame(food[i], '@');
}
//判斷蛇是否喫到東西

/*不用這個也行,蛇喫過了就沒了*/void Game::drawFoodToNull()
{
    for (int i = 0; i<2; i++)
    {
        drawFrame(food[i], ' ');
    }
}
//暫停遊戲
void Game::Pause()
{
    SetPos(61, 2);
    cout << "               ";
    SetPos(61, 2);
    cout << "暫停中...";
    char c = _getch();
    while (c != 'p')
        c = _getch();
    SetPos(61, 2);
    cout << "         ";
}

void Game::snake1ChangeDirection(char x)
{

        if (x == 'w')//是上箭頭;
        {
            if (direction1!=2)
            direction1 = 1;
        }
        else if (x == 's') //是 下箭頭;
        {
            if (direction1 != 1)
            direction1 = 2;
        }
        else if (x == 'a')  //是 左箭頭;
        {
            if (direction1 != 4)
            direction1 = 3;
        }
        else if (x == 'd') // 是 右箭頭;
        {
            if (direction1 != 3)
            direction1 = 4;
        }

}
void Game::snake2ChangeDirection(char x)
{

    if (x == 'i')//是上箭頭;
    {
        if (direction2 != 2)
            direction2 = 1;
    }
    else if (x == 'k') //是 下箭頭;
    {
        if (direction2 != 1)
            direction2 = 2;
    }
    else if (x == 'j')  //是 左箭頭;
    {
        if (direction2 != 4)
            direction2 = 3;
    }
    else if (x == 'l') // 是 右箭頭;
    {
        if (direction2 != 3)
            direction2 = 4;
    }

}

void Game::judgeSnake()
{
    for (int i = 0; i < 250; i++)
    {
        if (judgeCoordSnake(snake1[0], snake1, snake2) == false )
        {
            for (int i = 1; i < 500; i++)
            {
                Sleep(2);
                SetPos(random(1,79), random(1,24));
                cout << "玩家一輸了";
            }
            Sleep(1000);
            GameOver();
            break;
        }
        if (judgeCoordSnake(snake2[0], snake1, snake2) == false)
        {
            for (int i = 1; i < 500; i++)
            {
                Sleep(2);
                SetPos(random(1, 79), random(1, 24));
                cout << "玩家二輸了";
            }
            Sleep(1000);
            GameOver();
            break;
        }
    }



}


void Game::Playing()
{
    //HANDLE MFUN;
    //MFUN= CreateThread(NULL, 0, MusicFun, NULL, 0, NULL); 

    drawSnake1(direction1);
    drawSnake2(direction2);
    initFood();
    drawFood();
    int numfood;

    while (1)
    {
        Sleep(10);
        SetPos(52, 7);
        cout << length1;
        SetPos(52, 9);
        cout << length2;
        drawSnake1ToNull();
        drawSnake2ToNull();
        if (_kbhit())
        {
            char x = _getch();
            if ('a' == x || 's' == x || 'd' == x || 'w' == x)
            {
                snake1ChangeDirection(x);    
            }
            else if ('p' == x)
                Pause();
            else if ('j' == x || 'k' == x || 'l' == x || 'i' == x)
            {
                snake2ChangeDirection(x);
            }
            else if (27 == x)
            {
                //CloseHandle(MFUN);
                GameOver();
                break;
            }
        }
        if(judgeCoordSnakeFood(snake1[0], food[0], food[1],numfood)==true)
        {

            if (direction1 == 1)
            {
                for (int i = length1; i > 0; i--)
                    snake1[i+1] = snake1[i];
                snake1[0].Y--;
                length1++;
            }
            if (direction1 == 2)
            {
                for (int i = length1; i >= 0; i--)
                    snake1[i+1] = snake1[i];
                snake1[0].Y++;
                length1++;
            }
            if (direction1 == 3)
            {
                for (int i = length1; i >= 0; i--)
                    snake1[i+1] = snake1[i];
                snake1[0].X--;
                length1++;
            }
            if (direction1 == 4)
            {
                for (int i = length1; i >= 0; i--)
                    snake1[i+1] = snake1[i];
                snake1[0].X++;
                length1++;
            }
            food[numfood] = randomFood();
            drawFood();
        }
        else
        {
            if (direction1 == 1)
            {
                for (int i = length1; i > 0; i--)
                    snake1[i] = snake1[i - 1];
                snake1[0].Y--;
            }
            if (direction1 == 2)
            {
                for (int i = length1; i > 0; i--)
                    snake1[i] = snake1[i - 1];
                snake1[0].Y++;
            }
            if (direction1 == 3)
            {
                for (int i = length1; i > 0; i--)
                    snake1[i] = snake1[i - 1];
                snake1[0].X--;
            }
            if (direction1 == 4)
            {
                for (int i = length1; i > 0; i--)
                    snake1[i] = snake1[i - 1];
                snake1[0].X++;
            }
            judgeSnake();
        }
        if (judgeCoordSnakeFood(snake2[0], food[0], food[1], numfood) == true)
        {

            if (direction2 == 1)
            {
                for (int i = length2; i > 0; i--)
                    snake2[i + 1] = snake2[i];
                snake2[0].Y--;
                length2++;
            }
            if (direction2 == 2)
            {
                for (int i = length2; i >= 0; i--)
                    snake2[i + 1] = snake2[i];
                snake2[0].Y++;
                length2++;
            }
            if (direction2 == 3)
            {
                for (int i = length2; i >= 0; i--)
                    snake2[i + 1] = snake2[i];
                snake2[0].X--;
                length2++;
            }
            if (direction2 == 4)
            {
                for (int i = length2; i >= 0; i--)
                    snake2[i + 1] = snake2[i];
                snake2[0].X++;
                length2++;
            }
            food[numfood] = randomFood();
            drawFood();
        }
        else
        {
            if (direction2 == 1)
            {
                for (int i = length2; i > 0; i--)
                    snake2[i] = snake2[i - 1];
                snake2[0].Y--;
            }
            if (direction2 == 2)
            {
                for (int i = length2; i > 0; i--)
                    snake2[i] = snake2[i - 1];
                snake2[0].Y++;
            }
            if (direction2 == 3)
            {
                for (int i = length2; i > 0; i--)
                    snake2[i] = snake2[i - 1];
                snake2[0].X--;
            }
            if (direction2 == 4)
            {
                for (int i = length2; i > 0; i--)
                    snake2[i] = snake2[i - 1];
                snake2[0].X++;
            }
            judgeSnake();
        }
        drawSnake1(direction1);
        drawSnake2(direction2);

    }
}

void Game::GameOver()
{
    system("cls");
    COORD p1 = { 28, 9 };
    COORD p2 = { 53, 15 };
    drawFrame(p1, p2, '=', '|');
    SetPos(36, 12);
    string str = "Game Over!";
    for (int i = 0; i<str.size(); i++)
    {
        Sleep(80);
        cout << str[i];
    }
    Sleep(1000);
    system("cls");
    drawFrame(p1, p2, '=', '|');
    SetPos(31, 11);
    cout << "玩家一長度:" ;
    SetPos(31, 12);
    cout << length1;
    SetPos(31, 13);
    cout << "玩家二長度:";
    SetPos(31, 14);
    cout << length2;
    SetPos(30, 16);
    Sleep(1000);
    cout << "繼續? 是(y)| 否(n)";
as:
    char x = _getch();
    if (x == 'n')
        exit(0);
    else if (x == 'y')
    {
        system("cls");
        Game game;
        int a = drawMenu();    
        system("cls");
        drawPlaying();
        game.Playing();
    }
    else goto as;
}

/*================== the main function ==================*/
int main()
{
    //遊戲準備
    srand((int)time(0));    //隨機種子
    HideCursor();    //隱藏光標

    Game game;
    int a = drawMenu();
    system("cls");
    drawPlaying();
    game.Playing();
}
學習過程中遇到什麼問題或者想獲取學習資源的話,歡迎加入學習交流羣
639368839,我們一起學C/C++!


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