Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

1

17.07.2012, 17:01

Menü +SFML2 +FloatRect mit RenderWindow

Hallo zusammen,

Ich erstell gerade ein Menü für ein Spiel, bei dem der aktuell mit der Maus anvisierte Menüpunkt heller Leuchtet als die nicht selektierten. Das erreiche ich durch ein FloatRect, dass ich mit den Mauskoordinaten vergleiche...
Der Code sieht so aus:

sf::FloatRect spriteRectangle(const sf::Text &sprite)
{
return sf::FloatRect(sprite.getPosition().x ,
sprite.getPosition().y ,
sprite.getGlobalBounds().width,
sprite.getGlobalBounds().height);
}

int main()
...

sf::RenderWindow App(sf::VideoMode(800,600),"SFML Graphics");
...
while (App.isOpen())
{

sf::Event Event;
while (App.pollEvent(Event))
{
...
if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
if(spriteRectangle(text1).contains(mausposition.x, mausposition.y))
{
App.close();
}
}
...

Nun habe ich das Problem, dass wenn ich mein Fenster maximiere, ändert sich die Position meiner FloatRect nicht. Wie skaliere ich diese mit der Fenstergröße??

Gruß
Arch

Dieser Beitrag wurde bereits 1 mal editiert, zuletzt von »archer345« (17.07.2012, 17:24)


eXpl0it3r

Treue Seele

Beiträge: 386

Wohnort: Schweiz

Beruf: Professional Software Engineer

  • Private Nachricht senden

2

17.07.2012, 17:25

Wenn du nichts machst, dann bleibt die sf::View des Fensters fix beim Vergrössern des Fensters. Dies hat den Effekt einer skalierung. Die sf::View selbst hat keine direkte Funktion um den Skalierungsfaktor abzufragen, aber man kann das Ganze auch 'umkehren'. Da ja nur die sf::View angepasst wird, bleibt das Koordinatensystem und somit die Koordinaten des Sprites gleich. Mit sf::RenderWindow::convertCoords() kannst du nun die Mausposition in das andere Koordinatensystem konvertieren und dann erst der intersects() Funktion übergeben.

Wenn du genauer verstehen willst wie die sf::View funktioniert, kannst du mein Tutorial lesen.
Blog: https://dev.my-gate.net/
—————————————————————————
SFML: https://www.sfml-dev.org/
Thor: http://www.bromeon.ch/libraries/thor/
SFGUI: https://github.com/TankOs/SFGUI/

3

18.07.2012, 10:27

danke für die Antwort eXpl0it3r, ich habe dein Tutorial gelesen und es ist zwar alles gut beschrieben, bei der Umsetzung habe ich aber trotzdem Schwierigkeiten. Ich brauche die Funktion für ein Projekt. Ich wäre für eine konkrete Implementierung sehr dankbar.

Gruß
Arch

eXpl0it3r

Treue Seele

Beiträge: 386

Wohnort: Schweiz

Beruf: Professional Software Engineer

  • Private Nachricht senden

4

18.07.2012, 10:42

Ist nicht so schwer. ;)

C-/C++-Quelltext

1
if(spriteRectangle(text1).contains(window.convertCoords(sf::Mouse::getPosition(window))

Wir holen die Position der Maus und konvertieren die Koordinaten in das Koordinatensystem der View und überprüfen dann die überschneidung.
Blog: https://dev.my-gate.net/
—————————————————————————
SFML: https://www.sfml-dev.org/
Thor: http://www.bromeon.ch/libraries/thor/
SFGUI: https://github.com/TankOs/SFGUI/

5

18.07.2012, 12:29

Danke für die schnelle Hilfe, aber leider funktioniert das bei mir nicht. Wenn ich das Fenster nun vergrößere kann ich gar nix mehr markieren. Also ob mein FloatRect iwo außerhalb liegen würe :dash:.

Hier mal der vollständige Code...

sf::FloatRect spriteRectangle(const sf::Text &sprite)
{
return sf::FloatRect(sprite.getPosition().x ,
sprite.getPosition().y ,
sprite.getGlobalBounds().width,
sprite.getGlobalBounds().height);
}



int main()
{


sf::RenderWindow App(sf::VideoMode(800,600),"SFML Graphics");

App.setFramerateLimit(30);


double y;
y = App.getSize().y;


//Check ob Bilder geladen werden können

sf::Font font1;
if (!font1.loadFromFile("quake.ttf"))
return EXIT_FAILURE;
sf::Text text1("SuperTUX", font1, 60);
text1.setStyle(sf::Text::Bold);
text1.setColor(sf::Color::White);
text1.setPosition(App.getSize().x/2.f - text1.getGlobalBounds().width/2.f, 0.1*y);

sf::Font font2;
if (!font2.loadFromFile("quake.ttf"))
return EXIT_FAILURE;
sf::Text text2("Spiel starten", font2, 50);

text2.setColor(sf::Color::White);
text2.setPosition(App.getSize().x/2.f - text2.getGlobalBounds().width/2.f, 0.3*y);


...




sf::Vector2f mausposition(0.f, 0.f); //Vektor für Mausposition


// Mainloop

while (App.isOpen())
{
// Eventliste
sf::Event Event;
while (App.pollEvent(Event))
{



// Close window : exit
if (Event.type == sf::Event::Closed || sf::Keyboard::isKeyPressed(sf::Keyboard::Escape))
App.close();

if(Event.type == sf::Event::MouseMoved)
{
mausposition.x = Event.mouseMove.x;
mausposition.y = Event.mouseMove.y;


}




//Was passiert wenn man auf Bilder klickt --> Auswahl Charackter

if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
if(spriteRectangle(text1).contains(mausposition.x, mausposition.y))
{
App.close();
}
}
if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
if(spriteRectangle(text2).contains(mausposition.x, mausposition.y))
{
App.close();
}
}
if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
if(spriteRectangle(text3).contains(mausposition.x, mausposition.y))
{
App.close();
}
}
if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
if(spriteRectangle(text4).contains(mausposition.x, mausposition.y))
{
App.close();
}
}
...


//Prüfe Mausposition
//if(spriteRectangle(text2).contains(App.convertCoords(sf::Mouse::getPosition(App)) -> Funktioniert nicht
if(spriteRectangle(text2).contains(App.convertCoords(sf::Mouse::getPosition(App))))
{
text2.setColor(sf::Color(255,255,255));

text3.setColor(sf::Color(255,255,255,128));
text4.setColor(sf::Color(255,255,255,128));
text5.setColor(sf::Color(255,255,255,128));
text6.setColor(sf::Color(255,255,255,128));
text7.setColor(sf::Color(255,255,255,128));
}


if(spriteRectangle(text3).contains(mausposition.x, mausposition.y))
{

text3.setColor(sf::Color(255,255,255));
text2.setColor(sf::Color(255,255,255,128));
text4.setColor(sf::Color(255,255,255,128));
text5.setColor(sf::Color(255,255,255,128));
text6.setColor(sf::Color(255,255,255,128));
text7.setColor(sf::Color(255,255,255,128));
}


if(spriteRectangle(text4).contains(mausposition.x, mausposition.y))
{
text4.setColor(sf::Color(255,255,255));
text2.setColor(sf::Color(255,255,255,128));
text3.setColor(sf::Color(255,255,255,128));
text5.setColor(sf::Color(255,255,255,128));
text6.setColor(sf::Color(255,255,255,128));
text7.setColor(sf::Color(255,255,255,128));
}

if(spriteRectangle(text5).contains(mausposition.x, mausposition.y))
{
text5.setColor(sf::Color(255,255,255));
text2.setColor(sf::Color(255,255,255,128));
text3.setColor(sf::Color(255,255,255,128));
text4.setColor(sf::Color(255,255,255,128));
text6.setColor(sf::Color(255,255,255,128));
text7.setColor(sf::Color(255,255,255,128));
}

if(spriteRectangle(text6).contains(mausposition.x, mausposition.y))
{
text6.setColor(sf::Color(255,255,255));
text2.setColor(sf::Color(255,255,255,128));
text3.setColor(sf::Color(255,255,255,128));
text4.setColor(sf::Color(255,255,255,128));
text5.setColor(sf::Color(255,255,255,128));
text7.setColor(sf::Color(255,255,255,128));
}

if(spriteRectangle(text7).contains(mausposition.x, mausposition.y))
{
text7.setColor(sf::Color(255,255,255));
text2.setColor(sf::Color(255,255,255,128));
text3.setColor(sf::Color(255,255,255,128));
text5.setColor(sf::Color(255,255,255,128));
text4.setColor(sf::Color(255,255,255,128));
text6.setColor(sf::Color(255,255,255,128));
}

if(
!spriteRectangle(text2).contains(mausposition.x, mausposition.y)
&&!spriteRectangle(text3).contains(mausposition.x, mausposition.y)
&&!spriteRectangle(text4).contains(mausposition.x, mausposition.y)
&&!spriteRectangle(text5).contains(mausposition.x, mausposition.y)
&&!spriteRectangle(text6).contains(mausposition.x, mausposition.y)
&&!spriteRectangle(text7).contains(mausposition.x, mausposition.y))
{


text2.setColor(sf::Color(255,255,255,128));
text3.setColor(sf::Color(255,255,255,128));
text4.setColor(sf::Color(255,255,255,128));
text5.setColor(sf::Color(255,255,255,128));
text6.setColor(sf::Color(255,255,255,128));
text7.setColor(sf::Color(255,255,255,128));

}
}




App.clear();
App.draw(text1);
App.draw(text2);
App.draw(text3);
App.draw(text4);
App.draw(text5);
App.draw(text6);
App.draw(text7);
// Render the frame on screen
App.display();
}

return EXIT_SUCCESS;
}

Danke für die Hilfe!

6

18.07.2012, 12:57

Benutze den Code Tag!
Oben in der Leiste auf klicken.

Außerdem solltest du den Code auf das wesentliche kürzen. ;)

eXpl0it3r

Treue Seele

Beiträge: 386

Wohnort: Schweiz

Beruf: Professional Software Engineer

  • Private Nachricht senden

7

18.07.2012, 13:59

Benutze den Code Tag!
Oben in der Leiste auf klicken.

Ja da kann ich nur zu stimmen. :rolleyes:

Ich weiss jetzt nicht was bei dir schief läuft, da es nach meinem Wissen so funktionieren muss, leider kann ich es nicht testen.
Am Besten gibst du einmal die konvertierten Mauskoordinaten und die Koordinaten & Grösse des Floatrects in der Console aus um zu sehen, was der Unterschied ist.

Überigens kann man deine if Statements wesentlich besser

C-/C++-Quelltext

1
2
3
4
5
6
7
8
9
10
11
12
if(sf::Mouse::isButtonPressed(sf::Mouse::Left))
{
  if(text1.contains(...))
  {
    // ...
  }
  else if(text2.contains(...))
  {
    // ...
  }
  // ...
}


Auch empfehlt es sich sf::Mouse::getPosition() zu verwenden und nicht den Event MouseMoved. ;)
Blog: https://dev.my-gate.net/
—————————————————————————
SFML: https://www.sfml-dev.org/
Thor: http://www.bromeon.ch/libraries/thor/
SFGUI: https://github.com/TankOs/SFGUI/

Werbeanzeige