Nachdem es mir gestern gelungen war, mit Hilfe von Python und PyGlet ein Fenster auf den Monitor zu zaubern, ist es nun an der Zeit, dieses Fenster mit Leben zu füllen. Wie ich schon ankündigte, möchte ich eine Art Space Invaders programmieren. Als ersten Schritt soll eine kleine, animierte Rakte das Fenster bevölkern:
Das Spritesheet für diese Rakete (so wie auch alle übrigen in diesem Tutorium später noch verwendeten Sprites) habe ich diesem freien Set (CC-BY-3.0) von Jacob Zinman-Jeanes entnommen. Das Set besteht aus vier Sprites, jeweils in einer Größe von 64x29 Pixeln. Um dieses Spritesheet zu laden und daraus eine animierte Sprite-Sequenz zu erstellen, habe ich erst einmal die Datei gameobjects.py
erstellt und darin eine Klasse GameObject
angelegt. Hier der Inhalt dieser Datei:
import pyglet
class GameObject():
def __init__(self, posx, posy, image = None):
self.posx = posx
self.posy = posy
if image is not None:
image = pyglet.image.load("images/" + image)
image_seq = pyglet.image.ImageGrid(image, 4, 1, item_width = 64, item_height = 29)
image_texture = pyglet.image.TextureGrid(image_seq)
image_anim = pyglet.image.Animation.from_image_sequence(image_texture[:], 0.1, loop = True)
self.sprite = pyglet.sprite.Sprite(image_anim, self.posx, self.posy)
Noch ist sie relativ klein und übersichtlich, aber wie man in PyGlet Animationen erstellt, ist aus den Zeilen unter if image is not None:
zu erkennen: Zuerst wird das Bild geladen und daraus mit ImageGrid()
die Sequenz extrahiert. Der erste Parameter ist das Dateihandle, der zweite die Anzahl der Zeilen im Bild und der dritte die Anzahl der Spalten.
Die Sequenz des Schiffs besteht aus einer Spalte mit vier Einzelbildern (Zeilen), daher sind 4, 1
der zweite und dritte Parameter. Schließlich wird der Methode noch die Weite und die Höhe der einzelnen Ausschnitte mitgegeben, in diesem Fall 64x29 Pixel.
Systembedingt kann die Sequenz nicht direkt verwendet, sondern muß erst einer Textur zugewiesen werden, die dann in eine animierte Sequenz verwandelt wird. Dabei wird die gesamte Liste der Textur von Anfang bis Ende [:]
durchlaufen. Die Dauer der einzelnen Sequenzen habe ich auf 0.1 gesetzt (das war mein erster naiver Versuch und er brachte auf Anhieb ein ansprechendes Ergebnis) und mit loop = True
festgelegt, daß die Sequenz in einer Endlosschleife abgespielt werden soll.
Zu guter Letzt habe ich aus der animierten Sequenz ein Sprite gemacht, das im PyGlet-Fenster dargestellt werden kann. Dazu habe ich im Hauptprogramm das Template aus dem ersten Teil dieser Reihe wie folgt erweitert:
import pyglet
from pyglet.window import FPSDisplay
from gameobjects import GameObject
import os
TITLE = "Space Invaders Stage 1"
class GameWindow(pyglet.window.Window):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.set_location(100, 100)
self.frame_rate = 1/60.0
self.fps_display = FPSDisplay(self)
self.fps_display.label.font_size = 24
# Hier wird der Pfad zum Verzeichnis des ».py«-Files gesetzt
# Erspart einem das Herumgehample in TextMate mit dem os.getcwd()
# und os.path.join()
file_path = os.path.dirname(os.path.abspath(__file__))
os.chdir(file_path)
self.player = GameObject(50, 300, "Spritesheet_64x29.png")
def on_draw(self):
self.clear()
self.player.sprite.draw()
self.fps_display.draw()
def update(self, dt):
pass
win = GameWindow(900, 600, TITLE, resizable = False)
pyglet.clock.schedule_interval(win.update, win.frame_rate)
pyglet.app.run()
Neben dem Herumspielen mit den Pfaden (dazu weiter unten mehr) und dem import des GameObjects sind eigentlich nur zwei Zeilen hinzugekommen. Mit
self.player = GameObject(50, 300, "Spritesheet_64x29.png")
habe ich den Player initialisiert und mit
self.player.sprite.draw()
habe ich die Rakete in das Spielefenster eingezeichnet. Der obige Screenshot gibt es ja nicht her, aber glaubt mir (oder programmiert es nach): Die Raktee zieht einen fröhlich flackernden Feuerschweif hinter sich her. (Natürlich weiß ich, daß es in der Leere des Weltalls keinen Feuerschweif gibt, aber es ist nur ein Spiel und mit flackernden Feuerschweif wirkt es viel lebendiger.)
Nun zu den beiden Zeilen
file_path = os.path.dirname(os.path.abspath(__file__))
os.chdir(file_path)
für die ich extra noch os
importieren mußte. In den meisten Umgebungen sind diese beiden Zeilen nicht notwendig, da das current working directory
(cwd
) meist mit dem Verzeichnis der Python-Datei gleichgesetzt wird. Einige Editoren – wie zum Beispiel auch TextMate – setzten aber das cwd
auf das Wurzelverzeichnis des Projektes und das bei mir nicht immer das Verzeichnis, in dem auch die Python-Skripte liegen (sie liegen oft tiefer). Dahr habe ich mir angewöhnt, mit diesen beiden Zeilen das cwd
auf das Verzeichnis der Python-Datei zu legen.
So, in einem nächsten Schritt möchte ich die Rakete auf Nutzereingaben reagieren lassen. Sie soll dann ihre Position verändern und Laserkanonen abschießen können. Still digging!
Über …
Der Schockwellenreiter ist seit dem 24. April 2000 das Weblog digitale Kritzelheft von Jörg Kantel (Neuköllner, EDV-Leiter, Autor, Netzaktivist und Hundesportler — Reihenfolge rein zufällig). Hier steht, was mir gefällt. Wem es nicht gefällt, der braucht ja nicht mitzulesen. Wer aber mitliest, ist herzlich willkommen und eingeladen, mitzudiskutieren!
Alle eigenen Inhalte des Schockwellenreiters stehen unter einer Creative-Commons-Lizenz, jedoch können fremde Inhalte (speziell Videos, Photos und sonstige Bilder) unter einer anderen Lizenz stehen.
Der Besuch dieser Webseite wird aktuell von der Piwik Webanalyse erfaßt. Hier können Sie der Erfassung widersprechen.
Diese Seite verwendet keine Cookies. Warum auch? Was allerdings die iframes
von Amazon, YouTube und Co. machen, entzieht sich meiner Kenntnis.
Werbung