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!
ich entwickel seit einiger Zeit einen kleinen isometrischen 2D Shooter (wird noch umfangreicher vorgestellt) mit SFML. Bin jetzt an dem Punkt angelangt an dem ich den Schuss des Spielers zeichnen will. Ich habe die letzte Zeit viel rumprobiert und mir auch die mathematische Grundidee erarbeitet. Bei der Umsetzung stoße ich jedoch auf einige Probleme. Vielleicht habe ich in meiner Idee auch einen Denkfehler. Am besten bebilder ich meine derzeitige Vorgehensweise zunächst:
Drückt der Spieler auf die linke Maustaste erscheint ein Schuss sprite auf Höhe der Pistole:
Nun erstelle ich einen Richtungsvektor des Schusssprites mit x=1 und y=0, sowie einen Richtungsvektor direction vom geometrischen Ursprung des Schusses zur Mausposition
Der Winkel Alpha zwischen diesen beiden Vektoren ist der Rotationswinkel des Sprites
Soweit die Theorie.
Allerdings rotiert sich der Schuss nicht immer in die richtige Richtung und fliegt auch nicht immer in Richtung Fadenkreuz und wenn doch dann eher an diesem vorbei.
Hier einige Codeausschnitte:
C-/C++-Quelltext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//in class Level private:
Player* actualPlayer;
//....//Beim Mausklick:
levelContent.push_back(new Shot(25,
actualPlayer->actualSprite->GetPosition().x,
actualPlayer->actualSprite->GetPosition().y,
sf::Mouse::GetPosition()));
//LevelContent ist eine std::list<Object*> die sich immer richtig sortiert, damit die Objekte in richtiger Reihenfolge gerendert werden, also zB hinter oder vor einen Baum//Alle gezeichneten Elemente, also Player, Bäume oder auch Schüsse sind irgendwie von Object abgeleitet. Gebrauche hier viel Polymorphismus//25 ist hier nur die Stärke des Schusses also total irrelevant
C-/C++-Quelltext
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
//in class Shot//Konstruktor//...
sprite.SetOrigin(-59,0);
//der Schuss wird 59 pixel rechts neben dem Spieler(ursprung) gerendert
fDirection.x = mousePos.x - playerCenterX;
fDirection.y = mousePos.y - playerCenterY;
fDirection = normalize(fDirection);
//playerCenter ist der Originfloat ang = angle(fDirection,sf::Vector2<float>(1.0,0.0));
if(fDirection.y <0.f)
ang *=-1; //Keine Ahnung ob das Sinn so macht
sprite.Rotate(ang);
C-/C++-Quelltext
1
2
3
//bewegungsfunktion des Schusses
sprite.Move(fSpeed*fDirection*fTime);
//fTime ist hierbei: sf::RenderWindow.getFrameTime() / 1000.f
Ist jetzt etwas schwer zu erklären. Bin mir grad auch bei den Mathematischen Grundlagen nicht 100% sicher. Acos ist periodisch, dass heisst ab einem bestimmten Punkt wiederholt sich die Funktion. Das sind immer 180° Schritte. Dein Winkel wird vermutlich für einen Halbkreis stimmen und für die andere Hälfte nicht. Das Problem sollten die y-Werte darstellen. Du hast ja 2 Punkte first und second. Du musst quasi unterscheiden ob first.Y < second.Y und je nachdem dann den Winkel anpassen. In dem Fall, das der Winkel falsch ist, müsste ein Vorzeichenwechsel reichen. Also einfach * -1. Ich hoffe ich habe jetzt nicht völligen quatsch erzählt. Habe jetzt nicht noch mal genauer nach gesehen.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“
hab mal ein wenig ausprobiert...
rundungsfehler gibts wohl keine und der Debugger hilft mir da leider auch nicht wirklich.
Wenn ich mit meiner Figur ein wenig in der Welt rumlaufe gibt es immer eine Stelle bei der es funktioniert.. bei anderen jedoch nicht.
Da ich eine sf::View benutze wird es hier irgendwelche Probleme geben...vermute ich...
Wenn ich die Figur weiter nach rechts bewege wird der Winkel steiler, nach links flacher. Mhhhh
was trotz allem auf keinen Fall stimmt ist die Ausrichtung des Schusses... also das Rotieren misslingt irgendwie trotz anscheinend korrektem Winkel.
Habe ich vielleicht irgendwie die setOrigin() Funktion falsch verstanden?
Ohne setzen des Origins spawned der Schuss näher am Spieler ...
Da habe ich eine Vermutung. Wenn du deine Sicht durch eine View änderst, musst du auch bei den Koordinaten umrechnen. Ich bin mir nicht sicher, wie es bei SFML abläuft, aber ich gehe davon aus, dass die Maus immer in Bildschirmkoordinaten angegeben wird. Das heisst, Ursprung ist immer oben links. Die Position deines Spielers ist jetzt aber nicht mehr relativ zum Bildschirmursprung gesehen, sondern um die View verschoben. Das heisst, du musst zwischen beiden Systemen umrechnen.
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“
Ich habs geschafft... Daran lags auch tatsächlich allerdings habe ich die Maus Koordinaten jetzt in View Koordinaten umgerechnet.
Schorchs Antwort kam allerdings nachdem ich das gemacht habe aber trotzdem super herzlichen Dank auch euch!
Jetzt klappts astrein... die nächsten Tage stell ich mein Spiel mal unter Projekte vor