• 我罗斯方块最终篇


    本次作业要求    我罗斯作业要求
    本次作业属于     2020面向对象程序设计
    本次作业具体要求
    • 代码的 git 仓库链接
    • 运行截图/运行视频
    • 代码要点
    • 收获与心得
    • 依然存在的问题
    本次作业目标
    • 基本实现我罗斯的正常运行
    • 发表博客
    本次作业正文   https://www.cnblogs.com/smallgrape/p/13122112.html
    小组成员

       031902534  陈妍羽

       031902541  许雅萍

    代码仓库     完整代码

    一.代码仓库

    我罗斯代码仓库

    二.运行截图/运行的视频

    点击观看视频

    游戏封面:

    游戏开始:

     

    游戏结束,可选择再来一局

    三.代码要点

    //游戏类
    class Game
    {
    public:
        void Move();//每个玩家操作的大函数
        void SetWindow();//初始界面 
        void GameOver(Player& player, Player& opponent);//游戏结束再来一局的函数
        void GamePause();//游戏暂停
        int step2(Player& player1, Player& player2);//方块生命过程的第二个步骤
    };
    int Game::step2(Player& player1, Player& player2)//读取按键,进行相应方块变化的函数
    {
        int flag = 0;
        if (_kbhit())
        {
            switch (_getch())
            {
            case 'w':case 'W':
                player1.BlockUp(player1.OriginX);
                break;
            case 'a':case 'A':
                player1.BlockLeft(player1.OriginX);
                break;
            case 'd':case 'D':
                player1.BlockRight(player1.OriginX);
                break;
            case 's':case 'S':
                switch (player1.BlockDown(player1.OriginY))
                {
                case 0:
                    player1.check = false;
                    break;
                case 1:
                    player1.check = true;
                    break;
                case 2:
                    GameOver(player1, player2);
                    flag = 1;
                    //goto initial;
                }
                break;
            case 72:
                player2.BlockUp(player2.OriginX);
                break;
            case 75:
                player2.BlockLeft(player2.OriginX);
                break;
            case 77:
                player2.BlockRight(player2.OriginX);
                break;
            case 80:
                switch (player2.BlockDown(player2.OriginY))
                {
                case 0:
                    player2.check = false;
                    break;
                case 1:
                    player2.check = true;
                    break;
                case 2:
                    GameOver(player2, player1);
                    flag = 1;
                    //goto initial;
                default:
                    break;
                }
                break;
            case 32:
                GamePause();
                break;
            case 27:
                exit(0);
            default:
                break;
            }
        }
        return flag;
    }
    gameover函数:
    void Game::GameOver(Player& player, Player& opponent)//gameover函数,一轮游戏的结束,可以敲击空格键再来一局
    {
        SetConsoleTextAttribute(hOut, BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_RED | FOREGROUND_INTENSITY);
        SetPos(player.x0 + 10, 8);
        cout << "LOSE";
        SetPos(48 - player.x0 + 10, 8);
        cout << "WIN";
        SetConsoleTextAttribute(hOut, BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE);
        SetPos(38, 22);
        cout << "空格键重新开始";
        SetPos(40, 23);
        cout << "Esc键退出";
        char key;
        while (true)
        {
            key = _getch();
            if (key == 32)
            {
                SetConsoleTextAttribute(hOut, BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | FOREGROUND_INTENSITY | FOREGROUND_RED | FOREGROUND_BLUE);
                player.PrintScreen();
                opponent.PrintScreen();
                return;
            }
            if (key == 27)
            {
                exit(0);
            }
        }
    }
    //玩家类
    //随机生成,打印,清除方块的操作函数
    {
    void randBlock();
    void printBlock(int block[4][4], int a, int b);//打印 
    void clearBlock(int block[4][4], int a, int b);
    }
    //对运动中的方块的四种操作
    {
    int BlockDown(int y);
    void BlockLeft(int x);
    void BlockRight(int x);
    void BlockUp(int x);
    
    }
    //检测碰撞,消行,加行的函数
    {
    void Eliminate_Row_Add_Row(int& val, int map2[21][12]);
    bool Detect_Collision(int block[4][4], int x, int y);
    }
    //被大函数调用的两个步骤函数
    {
    bool step1(int& val, Player& opponent);
    int step3();
    }
    //绘制玩家的游戏页面,初始化地图
    {
    void setMap();
    void PrintScreen();//打印窗口
    }
    检测碰撞
    bool Player::Detect_Collision(int block[4][4], int x, int y)
    {
        for (int i = 0; i < 4; i++)
        {
            for (int j = 0; j < 4; j++)
            {
                if (x + i >= 0 && y + j >= 0 && map[x + i][y + j] && block[i][j] == 1)
                {
    
                    return false;
                }
            }
        }
    
        return true;
    }
    增减行函数:
    void Player::Eliminate_Row_Add_Row(int& val, int map2[21][12])//为玩家自己消一行,为对方增加一行
    {
        int checking = 0;//判断是否需要消行
        SetConsoleTextAttribute(hOut, BACKGROUND_RED | BACKGROUND_BLUE | BACKGROUND_GREEN | FOREGROUND_BLUE | FOREGROUND_GREEN | FOREGROUND_RED | FOREGROUND_INTENSITY);
        int i, j, m, n, x, f, k;
        for (i = 19; i >= 0; i--)
        {
            x = 0;
            for (j = 1; j < 11; j++)
            {
                x += map[i][j];
            }
    
            if (x == 10)
            {
                checking = 1;
                for (m = i; m > 0; m--)
                {
                    for (n = 1; n < 11; n++)
                    {
                        map[m][n] = map[m - 1][n];
                        SetPos(2 * (n + x0 / 2), y0 + m);
                        if (map[m][n] == 1)
                        {
                            cout << "";
                        }
                        else
                        {
                            cout << "  ";
                        }
                    }
                }
                i++;
            }
        }
        if (checking == 1)
        {
            for (i = 0; i < 20; i++)//寻找方块镇的首行
            {
                f = 0;
                for (j = 1; j < 11; j++)
                {
                    if (map2[i][j] != 0)
                    {
                        f = 1;
                    }
                    if (f == 1)
                        break;
                }
                if (f == 0)break;
            }
            int y = i;
            for (m = i; m < 19; m++)//地图向上平移
            {
                for (j = 1; j < 11; j++)
                {
                    map2[m][j] = map2[m + 1][j];
                }
            }
            map2[19][1] = 1;//为了避免随机生成的凌乱的一行,全是方块,或全是空的
            map2[19][10] = 0;
            for (i = 2; i < 10; i++)
            {
                k = rand() % 2;
                map2[19][i] = k;
            }
            for (i = y; i < 20; i++)
            {
                for (j = 1; j < 11; j++)
                {
                    SetPos(2 * (j + (48 - x0) / 2), y0 + i);
                    if (map2[i][j] == 1)
                    {
                        cout << "";
                    }
                    else
                    {
                        cout << "  ";
                    }
                }
            }
        }
    
    }
    //实现双人游戏

    网上查询到的资料,要实现两个玩家各玩各的,互不影响,要用双线程。双线程学了一些知识,也用了进去,但是有出现问题;了解到双线程,看起来是双人同时玩,但是实际上,同一个时刻其实还是只会执行其中一个玩家的代码,只不过是时间够短,“看不出来”;实际上,是错开时间执行两个玩家各自的代码,于是思考到了另外的方式,实现双人模式,就真的是两个玩家交替执行,实现还可以。

        player1.setMap();
        player2.setMap();
        srand((unsigned)time(NULL));
        player1.randBlock();
        player2.randBlock();
        while (true)
        {
            if (player1.step1(val, player2))
            {
                GameOver(player1, player2);
                goto initial;
    
            }
    
            player1.printBlock(player1.newblock, player1.OriginX, player1.OriginY);
    
            if (player2.step1(val, player1))
            {
                GameOver(player2, player1);
                goto initial;
            }
    
            player2.printBlock(player2.newblock, player2.OriginX, player2.OriginY);
    
            if (step2(player1, player2))
                goto initial;
    
            Sleep(20);
            if (!(--times))
            {
                if (player1.step3())
                {
                    GameOver(player1, player2);
                    goto initial;
                }
    
                if (player2.step3())
                {
                    GameOver(player2, player1);
                    goto initial;
                }
    
                times = val;
            }
    
        }
        cin.get();
    双线程设计背景音乐与我罗斯游戏并行
    void music()
    {
        while (1)
        {
            PlaySound(LPWSTR(IDR_WAVE2), GetModuleHandle(NULL), SND_RESOURCE | SND_LOOP);
            PlaySound(LPWSTR(IDR_WAVE3), GetModuleHandle(NULL), SND_RESOURCE | SND_LOOP);
            PlaySound(LPWSTR(IDR_WAVE4), GetModuleHandle(NULL), SND_RESOURCE | SND_LOOP);
            PlaySound(LPWSTR(IDR_WAVE5), GetModuleHandle(NULL), SND_RESOURCE | SND_LOOP);
        }
    
    }
    int main()
    {
        //    SetConsoleTextAttribute(hOut, FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE);
        Game game;
        game.SetWindow();
        initgraph(840, 560);
    
        IMAGE a;
        loadimage(&a, L"jpg", MAKEINTRESOURCE(IDB_BITMAP1));
        putimage(0, 0, &a);
        _getch();
        closegraph();
        //
        thread t1(music);
        thread t2((&Game::Move), game);
        t1.join();
        t2.join();
        return 0;
    }

    四.收获与心得

    1、收获最大的肯定是找代码bug的能力,不得不说,最困难的事,本来以为是实现双人模式,但是实际上最困难的莫过于,修改优化代码后,出现的令人措手不及的一系列bug。最叫人难受的是,每次犯了一些搞笑的错误,比如该是玩家1的时候,写成了玩家2,导致游戏实现的乱七八糟,结果不停调试不停找,分析应该是哪里出现了错误,有时候找了几个钟头,最后猛然发现是某些惊为天人的愚蠢的错误。感觉有些时候,不知名地方的一个小错误,像是蝴蝶效应一样,会因为代码的庞大,函数之间,类之间错综复杂的关系,反映在看起来毫不相关的地方。果然,还是要努力打好基础,提升能力,才不会因为代码的越来越长,修改bug越来越吃力,费劲。

    2、还有一点,要实现我罗斯,要学会了解好多东西,比如做界面的一系列函数,制作封面,设计背景音乐,时间的函数。要在短的时间,迅速掌握一些方法的使用,并不容易,尤其是网络上的信息真的太乱了,有时候开了几十个窗口,搜寻到的有效信息还是不足以实现相应的功能,要了解到有用的信息真是不容易。

    3、最后一点,能实现这个游戏,在一开始知晓这个学习任务的时候,是没有料到会做成的,尤其是要实现双人模式,但是当那个夜晚,实现了双人玩耍,两只手玩着双人的俄罗斯的时候,原来我们真的可以做成,真是不可思议。后来我们还设计了一个封面,封面的图片是画出来的,还加了背景音乐,虽然,还有好多可以改进的地方,但是亲手做出来的东西,还是很喜欢的。

    五.依然存在的问题

    1、原设想是,我罗斯游戏的背景要设计成颜色丰富,更好看的样子,暂时还不会实现背景嵌套;

    2、我罗斯的方块的下降速度,还没有设计成可以根据玩家自己的意愿更改速度,因为我们的游戏只分玩家胜负,没有限制玩一盘的时间,所以并不需要,分数,后续要改进成,即使两个玩家不分伯仲都可以保持方块不到顶,也要根据一轮游戏,有限的时间,分数的高低,来确定输赢的局面。

    3、因为,使用的是检测按键的函数,再区分那个键是哪一种键,来实现方块的运动;所以当一个玩家长按某个键,另一个玩家的按键会失灵;

    4、还没来得及,设计输入玩家的名字,或是直接固定玩家的名字(主要是还没想到理想的游戏玩家昵称);

    5、因为双人模式就是从单人模式发展过来的,我罗斯是一个双人游戏,就没有设计单双人模式可供选择,任意切换,后期会尝试改进。

  • 相关阅读:
    为什么要用全文搜索引擎:全文搜索引擎 VS 数据库管理系统
    大数据学习路线之hive存储格式
    web测试教程之JavaScript中的变量
    Java学习中面向过程与面向对象的优缺点
    Java教程之Java反射
    Python技术基础知识点:OS模块的应用
    软件测试教程——概念解析及常用方法概说
    UI设计师必备技能 网页中的色彩搭配(色彩篇)
    UI技术分享 如何提高自己的设计视野
    JavaScript学习指南分享
  • 原文地址:https://www.cnblogs.com/smallgrape/p/13122112.html
Copyright © 2020-2023  润新知