sfml一次管理多个窗口

问题描述 投票:0回答:1

好吧,这周我花了很多时间来学习如何一次打开和运行多个sfml寡妇。我有一个指向窗口的唯一指针的向量,以及一个显示它们并处理其事件的for循环。我遇到的问题是我想不出解决办法,因为for循环也运行引力函数。随着越来越多的窗口打开,按键以较低的速率下降。无论我正在处理多少个窗口,我都可以做些什么来确保它们始终以一定的一致性下降。供参考的是我的代码:MakeKey.h

class MakeKey
{
public:
    class NewKey {
    public:
        sf::Image Img;
        sf::Texture Tex;
        sf::Sprite Sprite;
        int velocetyX;
        int velocetyY;
        int accelerationX;
        int accelerationY;
        static bool hitLeft(sf::RenderWindow * window, sf::Image image)
        {
            int XPos{ window->getPosition().x };
            if (XPos <= -40)
                return true;
            return false;
        }
        static bool hitRight(sf::RenderWindow * window, sf::Image image)
        {
            int XPos{ window->getPosition().x };
            if (XPos >= sf::VideoMode::getDesktopMode().width - image.getSize().x + 30)
                return true;
            return false;
        }
        static bool hitTop(sf::RenderWindow * window, sf::Image image) 
        {
            int YPos = window->getPosition().y;
            if (YPos <= -22)
                return true;
            return false;
        }
        static bool hitBottom(sf::RenderWindow * window, sf::Image image)
        {
            int YPos = window->getPosition().y;
            if (YPos >= sf::VideoMode::getDesktopMode().height - image.getSize().y + 20)
                return true;
            return false;
        }
        static void impact(int & velocity) 
        {
            if (velocity > 0) {
                velocity -= 6;
                velocity *= -1;
            }
            if (velocity < 0) {
                velocity += 6;
                velocity *= -1;
            }
        }
        sf::Clock OffGroundClock;
    };

    sf::Vector2i Gravity(MakeKey::NewKey& Key, sf::RenderWindow* window);
    bool setShape(sf::RenderWindow * window, const sf::Image& image);
    sf::Vector2i RandSpawn(sf::Image image);
    bool setTransparency(HWND hwnd, unsigned char alpha);
    void MakeTopWindow(sf::RenderWindow* window);
    void StepWindows();
    void RunEvents(sf::RenderWindow* window);
    void DrawKey(string input);
private:
    vector <MakeKey::NewKey> KeyArray;
    vector <unique_ptr <sf::RenderWindow>> WindowArray;
    bool grabbedWindow{ false };
    sf::Vector2i grabbedOffSet;
};

MakeKey.cpp

static void StepVelocity(MakeKey::NewKey* Key) {
    Key->velocetyX += Key->accelerationX;
    Key->velocetyY += Key->accelerationY;
}
sf::Vector2i MakeKey::Gravity(MakeKey::NewKey & Key, sf::RenderWindow * window)
{
    int XPos = window->getPosition().x;
    int YPos = window->getPosition().y;
    YPos += 10;
    if (Key.hitTop(window, Key.Img))
        YPos = -22;
    if (Key.hitBottom(window, Key.Img))
        YPos = sf::VideoMode::getDesktopMode().height - Key.Img.getSize().y + 20;
    if (Key.hitRight(window, Key.Img))
        XPos = sf::VideoMode::getDesktopMode().width - Key.Img.getSize().x + 30;
    if (Key.hitLeft(window, Key.Img))
        XPos = (-44);
    /*StepVelocity(Key);
    XPos += Key->velocetyX;
    YPos += Key->velocetyY;*/
    return sf::Vector2i(XPos, YPos);
}
bool MakeKey::setShape(sf::RenderWindow * window, const sf::Image& image)
{
    HWND hwnd = window->getSystemHandle();
    const sf::Uint8* pixelData = image.getPixelsPtr();
    HRGN hRegion = CreateRectRgn(0, 0, image.getSize().x, image.getSize().y);

    // Determine the visible region
    for (unsigned int y = 0; y < image.getSize().y; y++)
    {
        for (unsigned int x = 0; x < image.getSize().x; x++)
        {
            if (pixelData[y * image.getSize().x * 4 + x * 4 + 3] == 0)
            {
                HRGN hRegionPixel = CreateRectRgn(x, y, x + 1, y + 1);
                CombineRgn(hRegion, hRegion, hRegionPixel, RGN_XOR);
                DeleteObject(hRegionPixel);
            }
        }
    }

    SetWindowRgn(hwnd, hRegion, true);
    DeleteObject(hRegion);
    return true;
}
sf::Vector2i MakeKey::RandSpawn(sf::Image image)
{
    std::random_device rand;
    int RandX = (rand() % sf::VideoMode::getDesktopMode().width) - image.getSize().x;
    int RandY = (rand() % sf::VideoMode::getDesktopMode().height) - image.getSize().y;
    if (RandX < 1 + image.getSize().x)
        RandX = image.getSize().x;
    if (RandY < 1 + image.getSize().y)
        RandY = image.getSize().y;
    return sf::Vector2i(RandX, RandY);
}
bool MakeKey::setTransparency(HWND hwnd, unsigned char alpha)
{
    SetWindowLong(hwnd, GWL_EXSTYLE, GetWindowLong(hwnd, GWL_EXSTYLE) | WS_EX_LAYERED);
    SetLayeredWindowAttributes(hwnd, 0, alpha, LWA_ALPHA);
    return true;
}
void MakeKey::MakeTopWindow(sf::RenderWindow* window)
{
    HWND hwndPoint = window->getSystemHandle();
    SetWindowPos(hwndPoint, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE);

}
void MakeKey::RunEvents(sf::RenderWindow* window) {
    sf::Event event;
    while (window->pollEvent(event))
    {
        //Key Presses
        if (event.type == sf::Event::KeyPressed) {
            if (event.key.code == sf::Keyboard::A) {
                DrawKey("A");
            }
            else if (event.key.code == sf::Keyboard::D)
            {
                DrawKey("D");
            }
            else if (event.key.code == sf::Keyboard::E)
            {
                DrawKey("E");
            }
            else if (event.key.code == sf::Keyboard::Q)
            {
                DrawKey("Q");
            }
            else if (event.key.code == sf::Keyboard::S)
            {
                DrawKey("S");
            }
            else if (event.key.code == sf::Keyboard::W)
            {
                DrawKey("W");
            }
            else if (event.key.code == sf::Keyboard::X)
            {
                DrawKey("X");
            }
            else if (event.key.code == sf::Keyboard::Z)
            {
                DrawKey("Z");
            }
            else if (event.key.code == sf::Keyboard::Escape)
            {
                DrawKey("Esc");
            }
        }
        else if (event.type == sf::Event::MouseButtonPressed)
        {
            if (event.mouseButton.button == sf::Mouse::Left)
            {
                grabbedOffSet = window->getPosition() - sf::Mouse::getPosition();
                grabbedWindow = true;
            }
        }
        else if (event.type == sf::Event::MouseButtonReleased)
        {
            if (event.mouseButton.button == sf::Mouse::Left)
                grabbedWindow = false;
        }
        else if (event.type == sf::Event::MouseMoved)
        {
            if (grabbedWindow)
                window->setPosition(sf::Mouse::getPosition() + grabbedOffSet);
        }
    }
}
void MakeKey::StepWindows()
{
    for (int i{ 0 }; i < WindowArray.size(); i++)
    {
        cout << "Inside Step Windows For Loop" << endl;
        WindowArray[i]->setActive(true);
        MakeTopWindow(WindowArray[i].get());
        setShape(WindowArray[i].get(), KeyArray[i].Img);
        RunEvents(WindowArray[i].get());
        WindowArray[i]->clear(sf::Color::Transparent);
        KeyArray[i].Sprite.setTexture(KeyArray[i].Tex);
        WindowArray[i]->draw(KeyArray[i].Sprite);
        WindowArray[i]->display();
        WindowArray[i]->setPosition(Gravity(KeyArray[i], WindowArray[i].get()));
    }
}
void MakeKey::DrawKey(string input)
{
    unique_ptr <sf::RenderWindow> window = make_unique<sf::RenderWindow>();
    NewKey Key;
    if (input == "A")
        Key.Img.loadFromFile("Assets/Images/A.png");
    else if (input == "D")
        Key.Img.loadFromFile("Assets/Images/D.png");
    else if (input == "E")
        Key.Img.loadFromFile("Assets/Images/E.png");
    else if (input == "Q")
        Key.Img.loadFromFile("Assets/Images/Q.png");
    else if (input == "S")
        Key.Img.loadFromFile("Assets/Images/S.png");
    else if (input == "W")
        Key.Img.loadFromFile("Assets/Images/W.png");
    else if (input == "X")
        Key.Img.loadFromFile("Assets/Images/X.png");
    else if (input == "Z")
        Key.Img.loadFromFile("Assets/Images/Z.png");
    else if (input == "Esc")
        Key.Img.loadFromFile("Assets/Images/esc.png");
    window->create(sf::VideoMode(Key.Img.getSize().x, Key.Img.getSize().y, 32), "Key", sf::Style::None);
    Key.Tex.loadFromImage(Key.Img);
    Key.Sprite.setTexture(Key.Tex);
    window->setPosition(RandSpawn(Key.Img));
    //Make Transparent
    const unsigned char opacity = 1000;
    setTransparency(window->getSystemHandle(), opacity);
    KeyArray.emplace_back(move(Key));
    WindowArray.emplace_back(move(window));

}

主要

int main()
{
    sf::RenderWindow window(sf::VideoMode(100, 100, 32), "Main Window", sf::Style::Default);
    MakeKey MakeKey;
    while (window.isOpen())
    {
        MakeKey::NewKey Key;
        MakeKey.RunEvents(&window);
        MakeKey.StepWindows();
    }
    return EXIT_SUCCESS;
}
c++ c++17 sfml
1个回答
0
投票

我还没有解决,但我知道如何解决。我需要实现多线程。

© www.soinside.com 2019 - 2024. All rights reserved.