Pygame-Tutorial

Aus Spieleprogrammierer-Wiki
(Unterschied zwischen Versionen)
Wechseln zu: Navigation, Suche
[unmarkierte Version][unmarkierte Version]
(Überblick)
(Die Animation-Klasse)
Zeile 721: Zeile 721:
 
# Die Klasse kümmert sich um eine einfache Animation:
 
# Die Klasse kümmert sich um eine einfache Animation:
 
class Animation(object):
 
class Animation(object):
     def __init__(self, image, startX, startY, num, width, height, duration):
+
     def __init__(self, image, start_x, start_y, num, width, height, duration):
 
         # Die Surface speichern,
 
         # Die Surface speichern,
 
         # alle Einzelbilder müssen in einer Reihe liegen.
 
         # alle Einzelbilder müssen in einer Reihe liegen.
         self.__image = image
+
         self.image = image
 
          
 
          
 
         # Dazu müssen wir wissen, an welcher Position die Frames beginnen,
 
         # Dazu müssen wir wissen, an welcher Position die Frames beginnen,
 
         # wie viele Frames die Animation hat,
 
         # wie viele Frames die Animation hat,
 
         # sowie die Breite und Höhe der Animation kennen.
 
         # sowie die Breite und Höhe der Animation kennen.
         self.__startX = startX
+
         self.start_x = start_x
         self.__startY = startY
+
         self.start_y = start_y
         self.__num = num
+
         self.num = num
         self.__width = width
+
         self.width = width
         self.__height = height
+
         self.height = height
 
          
 
          
         # Und natürlich auch, nach welchem Zeitraum wir das nächste Frame anzeigen sollen.
+
         # Und natürlich auch, nach welchem Zeitraum wir das nächsten Frame anzeigen sollen.
         self.__duration = duration
+
         self.duration = duration
 
          
 
          
         # Die aktuelle Zeit und das aktuelle Frame speichern wie ebenfalls.
+
         # Die aktuelle Zeit und das aktuellen Frame speichern wir ebenfalls.
         self.__time = 0
+
         self.time = 0
         self.__current = 0
+
         self.current = 0
 
</sourcecode>
 
</sourcecode>
  
Im Konstruktor passiert nicht viel. Um die Animation darstellen zu können, benötigen wir ein paar Daten: Natürlich das Bild, wir erwarten hier aber keinen Dateinamen sondern, direkt eine Surface mit den Bilddaten. Das hat den Vorteil, dass wir in einem Bild mehrere Animationen unterbringen können und nicht unnötigerweise das Bild für jede Animation komplett geladen wird. Aus diesem Grund müssen wir auch wissen, an welcher Position im Bild die Animation beginnt: <tt>startX</tt> und <tt>startY</tt>. Dazu brauchen wir die Abmessungen der Animation (<tt>width</tt>, <tt>height</tt>) und die Anzahl der Einzelbilder (<tt>num</tt>). Jetzt fehlt noch die Zeitspanne, für die ein Frame angezeigt, wird bevor zum nächsten gewechselt wird: <tt>duration</tt>.
+
Im Konstruktor passiert nicht viel. Um die Animation darstellen zu können, benötigen wir ein paar Daten: Natürlich das Bild, wir erwarten hier aber keinen Dateinamen sondern, direkt eine Surface mit den Bilddaten. Das hat den Vorteil, dass wir in einem Bild mehrere Animationen unterbringen können und nicht unnötigerweise das Bild für jede Animation komplett geladen wird. Aus diesem Grund müssen wir auch wissen, an welcher Position im Bild die Animation beginnt: <tt>start_x</tt> und <tt>start_y</tt>. Dazu brauchen wir die Abmessungen der Animation (<tt>width</tt>, <tt>height</tt>) und die Anzahl der Einzelbilder (<tt>num</tt>). Jetzt fehlt noch die Zeitspanne, für die ein Frame angezeigt, wird bevor zum nächsten gewechselt wird: <tt>duration</tt>.
  
 
Das Rendern der Animation erledigen wir in einer Zeile:
 
Das Rendern der Animation erledigen wir in einer Zeile:
Zeile 753: Zeile 753:
 
         # Die x-Position können wir aus der Breite und der Start-Position berechnen,
 
         # Die x-Position können wir aus der Breite und der Start-Position berechnen,
 
         # die restlichen Werte kennen wir bereits.
 
         # die restlichen Werte kennen wir bereits.
         screen.blit(self.__image, pos, pygame.Rect(self.__startX + (self.__width * self.__current), self.__startY, self.__width, self.__height))
+
         screen.blit(self.image, pos, pygame.Rect(self.start_x + (self.width * self.current), self.start_y, self.width, self.height))
 
</sourcecode>
 
</sourcecode>
  
Wir benötigen hier wieder eine Surface, auf die wir zeichnen sollen, und dazu eine Positionsangabe. Diese beiden Parameter geben wir so direkt an die <tt>blit</tt>-Methode weiter. Fehlt nur noch die Information, welcher Bereich des Bilds genau dargestellt werden soll. Dazu basteln wir ein Rechteck (<tt>pygame.Rect</tt>) mit den folgenden Daten: Der Beginn unserer Animation ist in <tt>__startX</tt> und <tt>__startY</tt> gespeichert. Da wir festgelegt haben, dass sich unsere Frames alle in einer Reihe befinden müssen, addieren wir die Breite des Einzelbildes multipliziert mit der Nummer des aktuellen Einzelbild zur x-Position dazu. Das bringt uns exakt zu dem Einzelbild, das wir anzeigen wollen. Die Größe der Animation kennen wir bereits.
+
Wir benötigen hier wieder eine Surface, auf die wir zeichnen sollen, und dazu eine Positionsangabe. Diese beiden Parameter geben wir so direkt an die <tt>blit</tt>-Methode weiter. Fehlt nur noch die Information, welcher Bereich des Bilds genau dargestellt werden soll. Dazu basteln wir ein Rechteck (<tt>pygame.Rect</tt>) mit den folgenden Daten: Der Beginn unserer Animation ist in <tt>start_x</tt> und <tt>start_y</tt> gespeichert. Da wir festgelegt haben, dass sich unsere Frames alle in einer Reihe befinden müssen, addieren wir die Breite des Einzelbildes multipliziert mit der Nummer des aktuellen Einzelbild zur x-Position dazu. Das bringt uns exakt zu dem Einzelbild, das wir anzeigen wollen. Die Größe der Animation kennen wir bereits.
  
 
Jetzt müssen wir die Animation nur noch aktualisieren, denn momentan würde immer nur das gleiche Bild (das erste) angezeigt.
 
Jetzt müssen wir die Animation nur noch aktualisieren, denn momentan würde immer nur das gleiche Bild (das erste) angezeigt.
Zeile 762: Zeile 762:
 
<sourcecode lang=python line start=29>
 
<sourcecode lang=python line start=29>
 
     # Die update-Methode rufen wir einmal pro Frame auf:
 
     # Die update-Methode rufen wir einmal pro Frame auf:
     def update(self, time = 1):
+
     def update(self, time=1):
         # Die vergangene Zeit addieren.
+
         # Die vergangene Zeit addieren
         self.__time += time
+
         self.time += time
 
          
 
          
         # Falls wir die Anzeigedauer überschreiten, ...
+
         # Falls wir den Anzeige-Zeitraum überschreiten, ...
         if self.__time > self.__duration:
+
         if self.time > self.duration:
             # ... setzen wir die Zeit zurück und gehen zum nächsten Frame.
+
             # ... setzten wir die Zeit zurück und gehen zum nächsten Frame.
             self.__time = 0
+
             self.time = 0
             self.__current += 1
+
             self.current += 1
 
             # Sicherstellen, dass das aktuelle Frame auch verfügbar ist.
 
             # Sicherstellen, dass das aktuelle Frame auch verfügbar ist.
             if self.__current >= self.__num:
+
             if self.current >= self.num:
                 self.__current = 0
+
                 self.current = 0
 
</sourcecode>
 
</sourcecode>
  
Ein Einzelbild der Animation soll immer nur eine bestimmte Zeit lang angezeigt werden. Der <tt>update</tt>-Methode übergeben wir einfach die Zeit, die seit dem letzten Aufruf der Methode vergangen ist. Hier in dem Tutorial machen wir das auf Frame-Basis, deshalb erhöhen wir standardmäßig die Zeit um 1 und rufen die <tt>update</tt>-Methode später in jedem Frame genau einmal auf. Ab Zeile 22 überprüfen wir, ob genügend viel Zeit vergangen ist und wir ein neues Frame anzeigen müssen. Wenn die Zeit größer als die Anzeigedauer für ein Einzelbild ist, setzen wir zuerst die Zeit zurück auf 0 und erhöhen die Nummer des aktuellen Einzelbildes. Im Tutorial lassen wir unsere Animation einfach am Anfang weiterspielen wenn sie fertig ist (Looping), deshalb sorgen wir noch dafür, dass <tt>__current</tt> im erlaubten Wertebereich bleibt.
+
Ein Einzelbild der Animation soll immer nur eine bestimmte Zeit lang angezeigt werden. Der <tt>update</tt>-Methode übergeben wir einfach die Zeit, die seit dem letzten Aufruf der Methode vergangen ist. Hier in dem Tutorial machen wir das auf Frame-Basis, deshalb erhöhen wir standardmäßig die Zeit um 1 und rufen die <tt>update</tt>-Methode später in jedem Frame genau einmal auf. Ab Zeile 22 überprüfen wir, ob genügend viel Zeit vergangen ist und wir ein neues Frame anzeigen müssen. Wenn die Zeit größer als die Anzeigedauer für ein Einzelbild ist, setzen wir zuerst die Zeit zurück auf 0 und erhöhen die Nummer des aktuellen Einzelbildes. Im Tutorial lassen wir unsere Animation einfach am Anfang weiterspielen wenn sie fertig ist (Looping), deshalb sorgen wir noch dafür, dass <tt>current</tt> im erlaubten Wertebereich bleibt.
  
 
Und damit ist unsere Animations-Klasse schon fertig. Den Rest erledigt die <tt>Player</tt>-Klasse.
 
Und damit ist unsere Animations-Klasse schon fertig. Den Rest erledigt die <tt>Player</tt>-Klasse.

Version vom 13. März 2015, 14:25 Uhr

Klicke hier, um diese Version anzusehen.

Meine Werkzeuge
Namensräume
Varianten
Aktionen
Navigation
Werkzeuge