Хорошо, поэтому на этой неделе я потратил много времени на изучение того, как открывать и запускать несколько вдов sfml одновременно. У меня есть вектор уникальных указателей на windows и a для l oop, который отображает их и обрабатывает их события. У меня возникла проблема, которую я не могу придумать, как исправить это то, что для l oop также работает гравитационная функция. По мере того, как все больше и больше windows открываются, ключи падают медленнее. Что я могу сделать, чтобы убедиться, что они всегда сбрасываются с некоторой постоянной скоростью, независимо от того, сколько windows я обрабатываю. Для справки вот мой код: 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));
}
Main
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;
}