【问题标题】:Can't draw sf::RectangleShape s stored in vector (Tetris clone)无法绘制存储在向量中的 sf::RectangleShape (俄罗斯方块克隆)
【发布时间】:2020-03-11 23:19:08
【问题描述】:

我正在尝试将sf::RectangleShape 存储到std::vector 中,然后将它们中的每一个都绘制到sf::RenderWindow 中。

单个矩形形状代表 1x1 tetromino,我想在每次到达窗口底部时将其存储到向量中。然后我想将当前tetromino的位置重置为默认位置。

我想我什至无法正确存储它。每次 tetromino 到达底部时,它都会给我这个错误消息:

    terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc

请在下面找到我当前的代码。我刚刚开始研究它并已经陷入困境。

定义.h

#pragma once

// Point structure
struct Point
{
    int dim_x;
    int dim_y;
};

// Field Dimensions
const int fieldRows = 10;
const int fieldColumns = 9;
const int pointSize = 50.f;

// For checkingEdges funntion within the Tetrnomino.h
enum Edge
{
    leftEdge,
    rightEdge,
    noneEdge
};

Game.h

#pragma once

#include <SFML/Window.hpp>
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>

#include "Definitions.h"
#include "Tetromino.h"

class Game
{
public:
    Game();
    ~Game();
    // Game starter
    void run();

    // Accessors
    bool running();
private:

    // Updating and rendering the game window
    void update();
    void render();

    // Initialization
    void initVariables();
    void initWindow();
    void initBacgroundMusic();

    // Polling
    void pollEvents();

    // Window logic stuff
    sf::RenderWindow* _window;
    sf::Event _event;
    void drawStack();

    // Bacground Music
    sf::Music _ost;

    // Tetromino + Its logic
    Tetromino _T;
    sf::Time delayTime = sf::milliseconds(300);
    sf::Clock clock;

};

Tetromino.h

#pragma once

#include <SFML/Graphics.hpp>
#include <vector>

#include "Definitions.h"

class Tetromino
{
public:
    Tetromino();
    ~Tetromino();

    // Initialization
    void initTetromino();

    // Tetromonino logic
    void moveTetromino();
    Edge checkEdges();

    // Getters & Setters
    sf::RectangleShape getTetromino();
    sf::RectangleShape getStackPart(int part);
    int getStackSize();
    void setTetromino(sf::RectangleShape &t);

private:
    // The current tetromino
    sf::RectangleShape _tetromino;
    std::vector<sf::RectangleShape> _stack;
};

Game.cpp

#include "Game.h"

//-----Consturcotrs and Destructors-----//
Game::Game()
{
    //Basic Initialization
    _T.initTetromino();
    initVariables();
}

Game::~Game()
{
    delete _window;
}

//-----Private Functions-----//
void Game::run()
{
     update();
     render();
}

bool Game::running()
{
    return _window->isOpen();
}

void Game::update()
{
    sf::Time elapsed = clock.getElapsedTime();

    pollEvents();
    if (elapsed >= delayTime)
    {
        _T.moveTetromino();
        clock.restart();
    }
}

void Game::render()
{
    _window->clear(sf::Color::White);
    _window->draw(_T.getTetromino());
    drawStack();
    _window->display();
}

void Game::initVariables()
{
    _window = nullptr;
    initWindow();
    initBacgroundMusic();
}

void Game::initWindow()
{
    _window = new sf::RenderWindow(sf::VideoMode(fieldColumns * pointSize, fieldRows * pointSize), "Tetris v0.2", sf::Style::Default);
    _window->setVerticalSyncEnabled(true);
    _window->setFramerateLimit(60);
}

void Game::initBacgroundMusic()
{
    _ost.openFromFile("../QT_SFML_Tetris/Music.ogg");
    _ost.play();
    _ost.setLoop(true);
    _ost.setVolume(50.f);
}

void Game::pollEvents()
{
    while (_window->pollEvent(_event))
    {
        if (_event.type == sf::Event::Closed) {_window->close();}
        if (_event.type == sf::Event::KeyPressed)
        {
            if (_event.key.code == sf::Keyboard::Escape){_window->close();}
            if (_event.key.code == sf::Keyboard::Left && _T.checkEdges() != leftEdge)
            {
                sf::RectangleShape t = _T.getTetromino();
                t.setPosition(t.getPosition().x - pointSize, t.getPosition().y);
                _T.setTetromino(t);
                render();
            }
            if (_event.key.code == sf::Keyboard::Right && _T.checkEdges() != rightEdge)
            {
                sf::RectangleShape t = _T.getTetromino();
                t.setPosition(t.getPosition().x + pointSize, t.getPosition().y);
                _T.setTetromino(t);
                render();
            }
            if (_event.key.code == sf::Keyboard::Down)
            {
                sf::RectangleShape t = _T.getTetromino();
                t.setPosition(t.getPosition().x, t.getPosition().y+ pointSize);
                _T.setTetromino(t);
                render();
            }
        }
    }
}

**void Game::drawStack()**
{
        for (unsigned int i = _T.getStackSize(); i > 0; --i)
        {
            _window->draw(_T.getStackPart(i));
        }
}

ma​​in.cpp

#include <Game.h>

int main()
{
    Game game;
    while (game.running())
    {
        game.run();
    }
    return 0;
}

Tetromino.cpp

#include "Tetromino.h"

//-----Consturcotrs and Destructors-----//
Tetromino::Tetromino()
{

}

Tetromino::~Tetromino()
{

}

//-----Public Functions-----//
void Tetromino::initTetromino()
{
    _tetromino.setPosition(sf::Vector2f((fieldColumns * pointSize - pointSize) / 2, 0.f));
    _tetromino.setSize(sf::Vector2f(pointSize, pointSize));
    _tetromino.setFillColor(sf::Color::Red);
}

void Tetromino::moveTetromino()
{
    _tetromino.move(0.f, pointSize);

    if (_tetromino.getPosition().y > fieldRows * pointSize - pointSize)
    {
        _stack.push_back(_tetromino);
        _tetromino.setPosition(sf::Vector2f((fieldColumns * pointSize - pointSize) / 2, 0.f));
    }
}

Edge Tetromino::checkEdges()
{
    if (_tetromino.getPosition().x == 0)
    {
        return leftEdge;
    }
    else if (_tetromino.getPosition().x == (fieldColumns * pointSize) - pointSize)
    {
        return rightEdge;
    }
    else return noneEdge;
}

sf::RectangleShape Tetromino::getTetromino()
{
    return _tetromino;
}

sf::RectangleShape Tetromino::getStackPart(int part)
{
    return _stack[part];
}

int Tetromino::getStackSize()
{
    return _stack.size();
}

void Tetromino::setTetromino(sf::RectangleShape &t)
{
    _tetromino = t;
}

我认为主要问题可能在这一行:

        _stack.push_back(_tetromino);

【问题讨论】:

  • bad_alloc 通常是由于内存不足造成的。低悬的果实:打印出vector 的大小,看看vector 是否变得异常大。

标签: c++ draw sfml bad-alloc


【解决方案1】:

在 drawStack() 方法中,您尝试向后迭代。

  1. 有一个反向迭代器为您执行此操作。
  2. 您的索引计算中有一个错误,该错误仅适用于空向量(为了防止这些错误,您应该使用迭代器!)

您可能想了解 C++ 中的迭代器 here is a small example。 根据您的代码,它看起来像(请注意,您还需要 Tetromino.hpp 中的 getStack() 方法,返回向量的 reference):

void Game::drawStack()
{
    for (auto it = _T.getStack().rbegin(); it != _T.getStack().rend(); it++)
    {
        _window->draw(*it);
    }
}

如果你想保留索引,我这是一个修复:

    void Game::drawStack()
    {
        for (int i = _T.getStackSize()-1; i >= 0; --i)
        {
            _window->draw(_T.getStackPart(i));
        }
    }

【讨论】:

    猜你喜欢
    • 2010-10-08
    • 2017-12-18
    • 2013-02-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-06
    • 2010-10-28
    • 1970-01-01
    相关资源
    最近更新 更多