C++ SFML:如何更改网格上的视图(实现无限网格)

C++ SFML how to change view on a grid (implementing infinite grid)

提问人:sadcat_1 提问时间:11/8/2023 更新时间:11/9/2023 访问量:72

问:

我正在尝试使用 C++ 的 SFML 库中的矩形网格创建生命游戏的模拟。 为此,我需要实现一个“无限”网格。 我当时想的只是画一个非常大的网格,窗口只会显示其中的一小部分,而用户可以使用键盘更改视图(向上、向下、向右和向左移动)。

为此,我有以下代码。我创建了一个网格,其大小是正常大小的十倍(没有实现视图逻辑)。然后我创建了一个特定大小的窗口,以及相同大小的视图对象。

#include <iostream>
#include <SFML/Graphics.hpp>
#include "game_logic.h"

int main() {    
    // Create the grid of cells
    std::vector< std::vector<sf::RectangleShape> > grid;
    for (int i = 0; i < WINDOW_HEIGHT * 10 / GRID_SIZE; i++) {
        std::vector<sf::RectangleShape> row;
        for (int j = 0; j < WINDOW_WIDTH * 10 / GRID_SIZE; j++) {
            sf::RectangleShape cell(sf::Vector2f(GRID_SIZE, GRID_SIZE));
            cell.setFillColor(DEAD_CELL_COLOR);
            cell.setOutlineColor(sf::Color(200, 200, 200)); // Beige
            cell.setOutlineThickness(1.25);
            row.push_back(cell);
        }
        grid.push_back(row);
    }

    sf::RenderWindow window(sf::VideoMode(WINDOW_WIDTH, WINDOW_HEIGHT), "Game of life", sf::Style::Default);
    sf::View view(sf::Vector2f(WINDOW_HEIGHT / 2, WINDOW_WIDTH / 2), sf::Vector2f(WINDOW_HEIGHT, WINDOW_WIDTH));

    getUserInput(window, grid, WINDOW_WIDTH, WINDOW_HEIGHT, GRID_SIZE);

    while (window.isOpen()) {
        sf::Event evnt;
        while (window.pollEvent(evnt)) {
            switch(evnt.type) {
                case sf::Event::KeyPressed:
                    if (evnt.key.code == sf::Keyboard::D){
                        view.move(sf::Vector2f(10, 0));
                        window.setView(view);
                    }
                    break;
            }
        }

        updateGrid(grid); // This simply change the grid values, based on Game of Life logic

        sf::sleep(sf::milliseconds(SLEEP_DURATION));
        window.clear();
        drawGrid(window, grid, GRID_SIZE);
        window.display();
    }

    return 0;
}

这是'drawGrid()':

void drawGrid(sf::RenderWindow& window, std::vector< std::vector<sf::RectangleShape> >& grid, int grid_size){
    for (int i = 0; i < grid.size(); i++) {
        for (int j = 0; j < grid[0].size(); j++) {
            // Set cell position based on its grid coordinates
            grid[i][j].setPosition(j * grid_size, i * grid_size);
            window.draw(grid[i][j]);
        }
    }
}

我的问题是,这段代码在按下“D”时不会改变视角,它只是扭曲了整个网格。当按下“D”时,我从这个: enter image description here 到这个:enter image description here

将不胜感激,提前致谢

C++ SFML

评论

0赞 Jesper Juhl 11/8/2023
sfml-dev.org/tutorials/2.6/graphics-view.php

答:

1赞 Olivier Samson 11/8/2023 #1

根据文档,如果未调用,则将内容绘制到默认视图。这意味着您最初拥有的视图和按 D 时拥有的视图是两个不同的视图,这可以解释您获得的透视图的变化。我会尝试在初始化窗口和视图后立即调用,看看会发生什么。setViewsetView

编辑: 我想我们俩都错过了这一点,这实际上可能是你的问题:你的观点被设置和混淆了。由于视图的纵横比与窗口的纵横比不同,因此这肯定是导致翘曲问题的原因WINDOW_WIDTHWINDOW_HEIGHT

评论

0赞 sadcat_1 11/9/2023
感谢您的回答,我尝试过,它所做的只是从一开始就显示扭曲的显示(甚至在用户输入之前)。我阅读了文档,但遗憾的是,我仍然不明白我哪里出了问题。我的猜测是,这是因为我使用的是网格,而不是静止图片。
0赞 Olivier Samson 11/9/2023
@sadcat_1 现在我们知道是视图本身导致了问题,我回顾了一下你的代码,注意到了一些东西!请参阅我的编辑。
0赞 sadcat_1 11/9/2023
我已经尝试修复它一个星期了,简直不敢相信它是如此简单:')。非常感谢