Pygame: Aktualisierung centerx durch Fließkommazahlen

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
TomBombadil
User
Beiträge: 12
Registriert: Sonntag 26. November 2017, 17:29

Montag 28. Mai 2018, 18:52

Guten Abend,

derzeit versuche ich mich am ersten Projekt des Buches "Python Crashkurs". In diesem geht es darum, den Spieleklassiker Alien Invasion zu programmieren.
Zunächst wird der Bildschirm erzeugt und die Spielfigur auf diesem ausgegeben. Nun folgt die Bewegung der Spielfigur nach links und rechts.
Dies wurde bisher immer folgendermaßen realisiert (nur ein Schnipsel):

Code: Alles auswählen

...
	self.image = pygame.image.load('images/ship.bmp')
	self.rect = self.image.get_rect()
	self.rect.centerx += 1
...
Das Buch schreitet weiter fort, und ersetzt die 1 durch eine Variable. So weit, so gut.

Code: Alles auswählen

...
	self.image = pygame.image.load('images/ship.bmp')
	self.rect = self.image.get_rect()
	self.center = float(self.rect.centerx)
	self.center += 1.5
	self.rect.centerx += self.center
...
Was mich nun stark irritiert ist, dass die Variable bzw. die Erhöhung von self.rect.centerx auch mit einer Dezimalzahl geschehen kann - obwohl der Autor selbst anmerkt, dass Werte, die in ...centerx gespeichert werden können, nur Integer-Werte sind. Auch hierzu merkt der Autor etwas an: "[...] Dabei wird in self.rect.centerx nur der Integralanteil von self.center gespeichert, aber für die Anzeige des Schiffes reicht das aus."
Leider erzielte ich mit meiner Suche nach "Integralanteil" nicht die gewünschten Ergebnisse.
Deshalb frage nun euch, wie es möglich ist, dass das Schiff bzw. dessen Rahmen um eine Fließkommazahl bewegt werden kann, auch wenn in self.rect.centerx lediglich eine Integer-Zahl gespeichert wird ...

MfG

Tom
Benutzeravatar
ThomasL
User
Beiträge: 419
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Montag 28. Mai 2018, 19:07

Hi Tom,
mit Integralanteil ist der Teil vor dem Komma gemeint, also 2 bei 2.543
ich meine das Pygame pixelorientiert arbeitet, d.h. der Wert in self.rect.centerx ist die x Komponente eines Koordinatenpaares x,y, welches die Mitte des Rechteckes ist.
halbe Pixel kann man nicht auf dem Bildschirm darstellen, also macht eine Fließkommazahl keinen Sinn.
Warum möchtest du denn den Rahmen oder das Objekt mit Bruchteilen eines Pixel bewegen?
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
Sirius3
User
Beiträge: 8805
Registriert: Sonntag 21. Oktober 2012, 17:20

Montag 28. Mai 2018, 19:10

Sehr viel sinn machen die Zeilen ja nicht, aber darum geht es Dir ja hier nicht. Pygame wird wahrscheinlich intern jede Zahl, die an centerx gebunden wird in ein `int` konvertieren, also das, was man explizit so schreiben würde:

Code: Alles auswählen

self.rect.centerx = int(self.rect.centerx + self.center)
TomBombadil
User
Beiträge: 12
Registriert: Sonntag 26. November 2017, 17:29

Montag 28. Mai 2018, 19:18

ThomasL hat geschrieben:
Montag 28. Mai 2018, 19:07
Hi Tom,
mit Integralanteil ist der Teil vor dem Komma gemeint, also 2 bei 2.543
ich meine das Pygame pixelorientiert arbeitet, d.h. der Wert in self.rect.centerx ist die x Komponente eines Koordinatenpaares x,y, welches die Mitte des Rechteckes ist.
halbe Pixel kann man nicht auf dem Bildschirm darstellen, also macht eine Fließkommazahl keinen Sinn.
Warum möchtest du denn den Rahmen oder das Objekt mit Bruchteilen eines Pixel bewegen?
Hallo Thomas,

ja, davon war ich zunächst auch ausgegangen. Jedoch wird das Schiff auch - spürbar langsam - bewegt, wenn ich als Variable bspw. 0.1 benutze. Ich dachte eigentlich, dass sich das Schiff überhaupt nicht bewegen würde, weil - meiner Meinung nach - die Nachkommastellen einfach abgeschnitten werden würden.
Laut Buch ist es ganz praktisch, Kommazahlen zu verwenden, da das Schiff so genauer bewegt werden könnte ...

Wenn es hilft, würde ich einfach eben alle Module angeben und nicht nur diesen Codeschnipsel verwenden.
Benutzeravatar
ThomasL
User
Beiträge: 419
Registriert: Montag 14. Mai 2018, 14:44
Wohnort: Kreis Unna NRW

Montag 28. Mai 2018, 19:24

du hast doch bestimmt für die Bewegung eine Schleife am laufen, innerhalb derer du die xpos veränderst
diese schleife wird eine gewisse Anzahl pro Sekunde durchlaufen
wenn du die Position um 0.01 veränderst, dann benötigt das Objekt halt 100 Durchläufe um sich ein Pixel fortzubewegen,
d.h. es wird dann 100mal an der gleichen Stelle gezeichnet
wenn du mit größeren Werten arbeitest, bewegt sich das Objekt halt schneller
Ich bin Pazifist und greife niemanden an, auch nicht mit Worten.
Für alle meine Code Beispiele gilt: "There is always a better way."
TomBombadil
User
Beiträge: 12
Registriert: Sonntag 26. November 2017, 17:29

Montag 28. Mai 2018, 19:30

ThomasL hat geschrieben:
Montag 28. Mai 2018, 19:24
du hast doch bestimmt für die Bewegung eine Schleife am laufen, innerhalb derer du die xpos veränderst
diese schleife wird eine gewisse Anzahl pro Sekunde durchlaufen
wenn du die Position um 0.01 veränderst, dann benötigt das Objekt halt 100 Durchläufe um sich ein Pixel fortzubewegen,
d.h. es wird dann 100mal an der gleichen Stelle gezeichnet
wenn du mit größeren Werten arbeitest, bewegt sich das Objekt halt schneller
Hey Thomas,

Herr schmeiße bitte Hirn auf mein Haupt! :oops:

Ich hatte mich so darauf konzentriert, dass es doch nicht sein kann, dass ich eine float-Zahl in einem Integer speichere und was anderes als eine Integer-Zahl rauskommt, dass ich einfach nicht auf diese total einfache Antwort gekommen bin.

Vielen Dank und einen schönen Abend wünscht

TomBombadil
Sirius3
User
Beiträge: 8805
Registriert: Sonntag 21. Oktober 2012, 17:20

Montag 28. Mai 2018, 19:40

... weil `self.centerx` die Kommazahl enthält und nur für `self.rect.centerx` gerundet wird.
Antworten