Konversion zwischen arithmetischen Typen
-
Für arithmetische Umwandlungen verwende ich i.d.R. immer Casts. Allerdings nicht static_cast<> - das wäre viel zu häßlich -, sondern den Cast im Konstruktor-Stil, also
int round (float f) { return int (f + 0.5f); }
-
1. Ich habe eigentlich kaum solche Casts, da ich meistens entsprechende typedefs brauche oder ähnliches. Also überall der gleiche Typ verändert wird.
2. Falls es einen hat und ich genau weiss, was hier gemacht werden soll, dann kommt einstatic_castzum Einsatz.
3. Falls es Bereichsprüfung und ähnliches braucht, dann hilft dir Boost:
http://www.boost.org/doc/libs/1_39_0/libs/numeric/conversion/doc/html/index.htmlGrüssli
-
Vielen Dank für die Antworten!
Ich habe bei mir eben schon ab und zu Casts, da ich Koordinaten von Spielobjekten teilweise als
floats speichere und teilweise alsint(das muss so sein, weil gewisse Objekte nur ganzzahlige Koordinaten haben können). Allerdings könnte ich versuchen, durch entsprechende Funktionen die Anzahl Casts zu minimieren, was ich wahrscheinlich demnächst tun werde.
-
Nexus schrieb:
... und teilweise als
int(das muss so sein, weil gewisse Objekte nur ganzzahlige Koordinaten haben können).Wieso speicherst du es intern nicht als
floatund sorgst im Getter oder Setter dafür, dass es nur Ganzzahlen sind? Zum Beispiel überceiloderfloor. Wenn du mit SFML arbeitest, was ich irgendwie stark vermute, brauchst du am Ende doch sowieso einenfloatfür die Position oder Grösse.
Allenfalls könntest du auch einen RealInteger oder sowas bauen, damit es noch ein wenig klarer ist für den Leser oder Benutzer der Bibliothek.Grüssli
-
Es geht um Lifte, die sich zwischen zwei Positionen bewegen. Da müssen die Koordinaten exakt sein, da ich auf Gleichheit prüfen möchte (wenn das Ende erreicht ist, soll der Lift wieder umkehren). Anfangs hatte ich
int, jetzt bin ich aufboost::rational<int>umgestiegen, um flexibler zu sein.An der Schnittstelle habe ich dennoch eine Funktion
GetPosition(), die die einenfloat-Vektor zurückgibt (aktuelle Position). Zudem habe ich noch eine Methode, die die Startposition des Liftes zurückgibt (GetOriginalPosition()). Die gibt einenint-Vektor zurück, weil die Startposition immer ganzzahlig ist (genauer gesagt, jeweils ein Vielfaches der Tilegrösse, da Lifte gerade an Tile-Ecken starten).Ja, ich arbeite mit SFML. Doch manchmal ist es da selber nicht ganz konsistent. Will ich zum Beispiel mit
sf::Shape::Rectangle()ein Rechteck erstellen, muss ichfloat-Koordinaten übergeben. Wenn die Koordinaten von der Bildschirmgrösse abhängen, greife ich aufsf::Window::GetWidth()zu, welchesintzurückgibt. Also wäre streng genommen wieder ein Cast erforderlich...
-
Nexus schrieb:
Es geht um Lifte, die sich zwischen zwei Positionen bewegen.
Da würde ich eher einen
intnehmen für das Stockwerk und dann einenfloatfür Stockwerkhöhen und entsprechend berechnen lassen, wodurch man einenfloatbekommt für die Position.
Ka ob das gehen würde, kommt natürlich darauf an, wie deine Lifte aussehen, aber fände ich ein typisches Beispiel für nicht genügend differenzierte Informationen/Daten
Nexus schrieb:
Wenn die Koordinaten von der Bildschirmgrösse abhängen, greife ich auf
sf::Window::GetWidth()zu, welchesintzurückgibt. Also wäre streng genommen wieder ein Cast erforderlich...Kommt darauf an, ob du dann mit einer
floatVariable rechnest, dann passiert dercastexplizit. Allerdings ist mir das noch nicht aufgefallen, wäre aber mal interessant im SFML Forum nachzufragen, ob hier nicht eher einfloatangebracht wäre, vor allem wegen der Konsistenz. Wäre sicher eine interessante Diskussion
Grüssli
-
Dravere schrieb:
Da würde ich eher einen
intnehmen für das Stockwerk und dann einenfloatfür Stockwerkhöhen und entsprechend berechnen lassen, wodurch man einenfloatbekommt für die Position.
Ka ob das gehen würde, kommt natürlich darauf an, wie deine Lifte aussehen, aber fände ich ein typisches Beispiel für nicht genügend differenzierte Informationen/Daten
Nicht solche klassischen Aufzüge, sondern Jump'n'Run-Lifte.

Also bewegliche Plattformen, die einen Anfangs- und Endpunkt haben, wie du sie vielleicht von Super Mario kennst. Und da ist ein Bruch wohl keine schlechte Wahl (er wird ja nur intern verwendet), um die Position exakt zu halten, aber trotzdem nicht nur Ganzzahlen zu erlauben.Dravere schrieb:
Allerdings ist mir das noch nicht aufgefallen, wäre aber mal interessant im SFML Forum nachzufragen, ob hier nicht eher ein
floatangebracht wäre, vor allem wegen der Konsistenz. Wäre sicher eine interessante Diskussion
Hm, es hat eben schon seinen Grund, warum
sf::WindowGanzzahlen zurückgibt, schliesslich kann die Fenstergrösse nur eine ganzzahlige Anzahl von Pixeln sein.Bei den Zeichenobjekten (von
sf::Drawableabgeleitete Klassen, daruntersf::Shape) hingegen wurdenfloats gewählt, um flexibler bezüglich der Position zu sein. Weil viele Spielobjekte sich auch um reelle Zahlen fortbewegen können. Andererseits ist das wieder nur relevant, wenn man seine Spiellogik nicht von der Grafik getrennt hält und direktsf::Sprites als Klasse für seine Spielfiguren nimmt. Hmm...
-
Nexus schrieb:
Nicht solche klassischen Aufzüge, sondern Jump'n'Run-Lifte.

Also bewegliche Plattformen, die einen Anfangs- und Endpunkt haben, wie du sie vielleicht von Super Mario kennst. Und da ist ein Bruch wohl keine schlechte Wahl (er wird ja nur intern verwendet), um die Position exakt zu halten, aber trotzdem nicht nur Ganzzahlen zu erlauben.Dann gäbe es die Möglichkeit 0 (unten) und 1 (oben). Oder man führt Grenzbereiche ein, in welchen man ein- oder aussteigen kann.
Nexus schrieb:
Hm, es hat eben schon seinen Grund, warum
sf::WindowGanzzahlen zurückgibt, schliesslich kann die Fenstergrösse nur eine ganzzahlige Anzahl von Pixeln sein.Und "Zeichenobjekte" (was für ein Name?
:D) haben keine feste Pixelposition schlussendlich?
Wofür braucht man die Fenstergrösse in SFML, ausser für die Berechnung der Grösse oder Position von Objekten? Mir will da nichts sinnvolles einfallen
Grüssli
-
Dravere schrieb:
Dann gäbe es die Möglichkeit 0 (unten) und 1 (oben). Oder man führt Grenzbereiche ein, in welchen man ein- oder aussteigen kann.
Ich weiss jetzt nicht genau, was du meinst, aber irgendwie habe ich das Gefühl, wir verstehen unter Lift nicht das Gleiche. Bei mir sind die Lifte bewegliche Plattformen, die sich in 8 Richtungen fortbewegen können. Diese haben Wegpunkte gespeichert, eine Bahn muss also nicht geradlinig sein, sondern kann sich aus mehreren geradlinigen Stücken zusammensetzen. Doch speichern musst du die aktuelle Position so oder so. Und da reichen 2 Möglichkeiten nicht. Statt eines ungenauen
floats für die Koordinaten habe ich ebenboost::rationalgenommen.Dravere schrieb:
Und "Zeichenobjekte" (was für ein Name?
:D) haben keine feste Pixelposition schlussendlich?Doch. Aber "schlussendlich" ist bereit derart Low-Level, dass man sich selber nicht darum kümmern muss. OpenGL nimmt selber
floats, wieso sollte ich also zuerst runden? Koordinaten haben ausserdem nicht immer Pixel als Masseinheit, denke zum Beispiel an verschiedene Viewports. Deshalb ist es auch sinnvoll, dass SFMLfloat-Koordinaten nimmt. Zumal man wohl in den meisten Fällen Fliesskommazahlen für spiellogische Koordinaten verwendet.Dravere schrieb:
Wofür braucht man die Fenstergrösse in SFML, ausser für die Berechnung der Grösse oder Position von Objekten? Mir will da nichts sinnvolles einfallen

Naja, mir fällt jetzt auch nicht gerade ein Fall ein. Aber ich finde
unsigned inttrotzdem sinnvoll, eben weil nur Ganzzahlen angenommen werden können. Einfloatfür eine Fenstergrösse wäre verwirrend und inkonsistent, man müsste dann entsprechend die Fenstergrösse auch auf zweifloats setzen können. Im Gegensatz zu den Zeichenobjekten (hast du den Begriff wirklich noch nie gehört? Ich finde gerade keinen besseren...) macht das hier absolut keinen Sinn.
-
Nexus schrieb:
... Lifte mit Wegpunkten ...
Ich würde zwar immer noch sagen, dass es anders ginge, denn ich hatte durchaus auch sowas im Kopf. Aber ist ja auch nicht so weiter wichtig, vielleicht sehe ich dich noch irgendwann im MSN, dann können wir das noch genauer diskutieren, sofern ich endlich mal wieder online gehen würde ^^"
Nexus schrieb:
OpenGL nimmt selber
floats, wieso sollte ich also zuerst runden? Koordinaten haben ausserdem nicht immer Pixel als Masseinheit, denke zum Beispiel an verschiedene Viewports. Deshalb ist es auch sinnvoll, dass SFMLfloat-Koordinaten nimmt. Zumal man wohl in den meisten Fällen Fliesskommazahlen für spiellogische Koordinaten verwendet.Ich war ja auch nicht gegen
floatWerte. Ich bin nur der Meinung, dass man die verschiedenen Argumente fürfloatWerte bei Figuren auch fast 1:1 auf das Fenster anwenden kann
Nexus schrieb:
Ein
floatfür eine Fenstergrösse wäre verwirrend und inkonsistent, man müsste dann entsprechend die Fenstergrösse auch auf zweifloats setzen können. Im Gegensatz zu den Zeichenobjekten [...] macht das hier absolut keinen Sinn.Ich fände es aber noch gut, wenn man auch die Fenstergrösse und Position als
floatWerte setzen könnte. Zum Beispiel könntest du das Fenster selbst animieren, dann hast du auchfloatWerte, welche du setzen musst. Wieso vorher runden, wieso kann dies nicht das Framework für dich übernehmen? Das ist doch völlig Low-Level
Nexus schrieb:
... (hast du den Begriff wirklich noch nie gehört? Ich finde gerade keinen besseren...) ...
Ich würde es eher eine Figur nennen. Oder ein graphisches Objekt. Ein Zeichenobjekt klingt einfach nur seltsam. Wenn schon eher noch Zeichnungsobjekt, aber auch das ist ... naja
Grüssli
-
Dravere schrieb:
Ich fände es aber noch gut, wenn man auch die Fenstergrösse und Position als
floatWerte setzen könnte. Zum Beispiel könntest du das Fenster selbst animieren, dann hast du auchfloatWerte, welche du setzen musst. Wieso vorher runden, wieso kann dies nicht das Framework für dich übernehmen? Das ist doch völlig Low-Level
Naja. Wie oft animiert man sein Fenster, und wie oft seine Spielfiguren?

Bei Spielfiguren ist es teilweise wirklich notwendig, die Position mitfloat-Koordinaten zu setzen. Zum Beispiel, wenn man heranzoomt. Beim Fenster wäre es mehr Faulheit,floats zu nehmen, um sich das Runden zu ersparen. Denn für das Fenster selbst sind nur ganze Pixel relevant, und zwar immer. Es gibt wahrscheinlich auch Fälle, wo man auf die Anzahl Pixel angewiesen ist, und da ist man wieder froh über genaue Angaben.Auch das mit dem Low-Level kannst du nicht 1:1 übertragen. Bei SFML müsstest du, um direkt die Pixelkoordinaten von Spielfiguren setzen zu können, Zugriff auf den Viewport und die Matrizen von OpenGL haben. Ich finde es gut, dass dieser Teil gekapselt wird. Beim Fenster hingegen ist es wirklich nur ein Runden, was in einer Zeile gemacht werden kann.
Dravere schrieb:
Ich würde es eher eine Figur nennen. Oder ein graphisches Objekt. Ein Zeichenobjekt klingt einfach nur seltsam. Wenn schon eher noch Zeichnungsobjekt, aber auch das ist ... naja
Hmm, stimmt schon, ich habe mir gar nicht soviel dabei überlegt. Figur triffts wohl am besten...

Vielen Dank übrigens für die Antworten, Dravere! Ja, eventuell können wir uns da noch einmal ausführlicher drüber unterhalten...

-
Nexus schrieb:
Es geht um Lifte, die sich zwischen zwei Positionen bewegen. Da müssen die Koordinaten exakt sein, da ich auf Gleichheit prüfen möchte (wenn das Ende erreicht ist, soll der Lift wieder umkehren). Anfangs hatte ich
int, jetzt bin ich aufboost::rational<int>umgestiegen, um flexibler zu sein.An der Schnittstelle habe ich dennoch eine Funktion
GetPosition(), die die einenfloat-Vektor zurückgibt (aktuelle Position). Zudem habe ich noch eine Methode, die die Startposition des Liftes zurückgibt (GetOriginalPosition()). Die gibt einenint-Vektor zurück, weil die Startposition immer ganzzahlig ist (genauer gesagt, jeweils ein Vielfaches der Tilegrösse, da Lifte gerade an Tile-Ecken starten).Ja, ich arbeite mit SFML. Doch manchmal ist es da selber nicht ganz konsistent. Will ich zum Beispiel mit
sf::Shape::Rectangle()ein Rechteck erstellen, muss ichfloat-Koordinaten übergeben. Wenn die Koordinaten von der Bildschirmgrösse abhängen, greife ich aufsf::Window::GetWidth()zu, welchesintzurückgibt. Also wäre streng genommen wieder ein Cast erforderlich...