首页 > 解决方案 > 在 C++ 中,我的控制台游戏角色在游戏字段数组内移动时不会停止

问题描述

嗨,第一次在 SO 上发帖,所以如果我设法捏造它,请对我温柔一点。我对编码也很陌生,因此任何朝着正确方向推动我自己找到解决方案的努力都将不胜感激。

应该发生什么:有一个由字符串数组组成的游戏场。玩家 (P) 应该能够在每个循环中移动一个字段。

会发生什么:对于 UP、DOWN 和 LEFT,它有效。但是当按下 RIGHT 时,玩家会尽可能地移动而不是只移动一个空格。

它可能是什么:我认为它与改变数组中 P 的位置有关,但我找不到它出错的原因。

#include "iostream"
#include "conio.h"
#include "typeinfo"
#include <cstdlib>
#include <string>
#include <array>
#include <Windows.h>

void main()
{

    // Utilities 
    bool wants_to_exit = false;
    char move;

    // Block types
    std::string a = "   ";
    std::string W = "###";
    std::string P = " O ";

    // Map
    std::string fields[10][10] = {
                                 { W , W , W , W , W , W , W , W , W , W },
                                 { W , a , a , a , a , W , a , a , a , W },
                                 { W , a , P , a , a , W , a , a , a , W },
                                 { W , a , a , a , a , W , a , a , a , W },
                                 { W , a , a , a , a , W , a , a , a , W },
                                 { W , a , a , a , a , a , a , a , a , W },     
                                 { W , a , a , a , a , W , a , a , a , W },
                                 { W , a , a , a , a , W , a , a , a , W },
                                 { W , a , a , a , a , W , a , a , a , W },
                                 { W , W , W , W , W , W , W , W , W , W } 
                                 };

    // Main Loop
    while (!wants_to_exit)
    {
        // Display Map on Console
        for (int x = 0; x < 10; x++)
        {
            for (int y = 0; y < 10; y++) 
            {
                std::cout << fields[x][y];
            }
            printf("\n");
        }

        std::cout << std::endl;
        std::cout << _kbhit() << std::endl;
        std::cout << "\n\nUse the arrow Keys to move" << std::endl;


        move = _getch();

        // Movement
        if (move == 72) // UP
        {
            for (int x = 1; x < 10; x++)
            {
                for (int y = 1; y < 10; y++) 
                {
                    if (fields[y][x] == P) 
                    {
                        if (fields[y-1][x] == a)
                        { 
                            fields[y][x] = a;
                            fields[y-1][x] = P;
                            move = 0;
                            break;

                        }
                    }
                }
            }
        }

        else if (move == 80) // DOWN
        {
            for (int x = 1; x < 10; x++) 
            {
                for (int y = 1; y < 10; y++) 
                {
                    if (fields[y][x] == P) 
                    {
                        if (fields[y+1][x] == a)
                        { 
                            fields[y][x] = a;
                            fields[y+1][x] = P;
                            move = 0;
                            break;
                        }
                    }
                }
            }
        }

        else if (move == 75) // LEFT
        {
            for (int x = 1; x < 10; x++)
            {
                for (int y = 1; y < 10; y++)
                {
                    if (fields[y][x] == P)
                    {
                        if (fields[y][x-1] == a)
                        { 
                            fields[y][x] = a;
                            fields[y][x-1] = P;
                            move = 0;
                            break;

                        }
                    }
                }
            }
        }

        else if (move == 77) // RIGHT
        {
            for (int x = 1; x < 10; x++)
            {
                for (int y = 1; y < 10; y++)
                {
                    if (fields[y][x] == P) 
                    {
                        if (fields[y][x+1] == a)
                        { 
                            fields[y][x] = a;
                            fields[y][x+1] = P;
                            move = 0;
                            break;

                        }
                    }
                }
            }
        }

        else if (move == 113) // QUIT (press q)
        {
            wants_to_exit = true; 
        }

        Sleep(1);
        system("cls");

    }

}

标签: c++arrays

解决方案


您的每个break语句都只跳出内部 for 循环。外部 for 循环继续,在向右移动的情况下,不断绊倒刚刚被上一次迭代推到右侧的玩家。

我建议将玩家运动分解为一个本地函数,一旦你找到并更新了玩家(未经测试的代码),你就可以从中返回:

#include "iostream"
#include "conio.h"
#include "typeinfo"
#include <cstdlib>
#include <string>
#include <array>
#include <Windows.h>

void main()
{

    // Utilities 
    bool wants_to_exit = false;

    // Block types
    std::string a = "   ";
    std::string W = "###";
    std::string P = " O ";

    // Map
    std::string fields[10][10] = {
                                 { W , W , W , W , W , W , W , W , W , W },
                                 { W , a , a , a , a , W , a , a , a , W },
                                 { W , a , P , a , a , W , a , a , a , W },
                                 { W , a , a , a , a , W , a , a , a , W },
                                 { W , a , a , a , a , W , a , a , a , W },
                                 { W , a , a , a , a , a , a , a , a , W },     
                                 { W , a , a , a , a , W , a , a , a , W },
                                 { W , a , a , a , a , W , a , a , a , W },
                                 { W , a , a , a , a , W , a , a , a , W },
                                 { W , W , W , W , W , W , W , W , W , W } 
                                 };

    // New local function doing the moving logic
    auto const movePlayer = [&](int deltaX, int deltaY) {
        for (int x = 1; x < 10; x++) 
        {
            for (int y = 1; y < 10; y++) 
            {
                if (fields[y][x] == P) 
                {
                    if (fields[y + deltaY][x + deltaX] == a)
                    { 
                        fields[y][x] = a;
                        fields[y + deltaY][x + deltaX] = P;
                    }
                    return;
                }
            }
        }
    };

    // Main Loop
    while (!wants_to_exit)
    {
        // Display Map on Console
        for (int x = 0; x < 10; x++)
        {
            for (int y = 0; y < 10; y++) 
            {
                std::cout << fields[x][y];
            }
            printf("\n");
        }

        std::cout << std::endl;
        std::cout << _kbhit() << std::endl;
        std::cout << "\n\nUse the arrow Keys to move" << std::endl;


        // Definition moved to the point of actual use
        char const move = _getch();

        // Movement
        if (move == 72) // UP
        {
            movePlayer(-1, 0);
        }
        else if (move == 80) // DOWN
        {
            movePlayer(1, 0);
        }
        else if (move == 75) // LEFT
        {
            movePlayer(0, -1);
        }
        else if (move == 77) // RIGHT
        {
            movePlayer(0, 1);
        }
        else if (move == 113) // QUIT (press q)
        {
            wants_to_exit = true; 
        }

        Sleep(1);
        system("cls");
    }
}

推荐阅读