Pygame-Tutorial
Aus Spieleprogrammierer-Wiki
(Unterschied zwischen Versionen)
[unmarkierte Version] | [gesichtete Version] |
(→Die Player-Klasse) |
(→Zusammenbasteln) |
||
Zeile 870: | Zeile 870: | ||
<sourcecode lang=python line start=15> | <sourcecode lang=python line start=15> | ||
− | self. | + | self.tileset.add_tile("grass-mud", 0, 64) |
− | self. | + | self.tileset.add_tile("empty", 0, 96) |
</sourcecode> | </sourcecode> | ||
Zeile 877: | Zeile 877: | ||
<sourcecode lang=python line start=30> | <sourcecode lang=python line start=30> | ||
− | for i in range(0, self. | + | for i in range(0, self.height): |
− | self. | + | self.tiles.append(list()) |
− | for j in range(0, self. | + | for j in range(0, self.width): |
if i == 14: | if i == 14: | ||
− | self. | + | self.tiles[i].append("grass") |
elif i == 15: | elif i == 15: | ||
− | self. | + | self.tiles[i].append("grass-mud") |
elif i > 15: | elif i > 15: | ||
− | self. | + | self.tiles[i].append("mud") |
else: | else: | ||
− | self. | + | self.tiles[i].append("empty") |
</sourcecode> | </sourcecode> | ||
Zeile 893: | Zeile 893: | ||
<sourcecode lang=python line start=43> | <sourcecode lang=python line start=43> | ||
− | self. | + | self.player = Player.Player() |
</sourcecode> | </sourcecode> | ||
Zeile 899: | Zeile 899: | ||
<sourcecode lang=python line start=70> | <sourcecode lang=python line start=70> | ||
− | self. | + | self.player.render(screen) |
</sourcecode> | </sourcecode> | ||
− | Und in der <tt> | + | Und in der <tt>handle_input</tt>-Methode reichen wir die Tastendrücke durch: |
<sourcecode lang=python line start=75> | <sourcecode lang=python line start=75> | ||
− | self. | + | self.player.handle_input(key) |
</sourcecode> | </sourcecode> | ||
Zeile 922: | Zeile 922: | ||
# 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, | + | 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. | + | 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. | + | self.start_x = start_x |
− | self. | + | self.start_y = start_y |
− | self. | + | self.num = num |
− | self. | + | self.width = width |
− | self. | + | self.height = height |
# Und natürlich auch, nach welchem Zeitraum wir das nächsten Frame anzeigen sollen. | # Und natürlich auch, nach welchem Zeitraum wir das nächsten Frame anzeigen sollen. | ||
− | self. | + | self.duration = duration |
# Die aktuelle Zeit und das aktuellen Frame speichern wir ebenfalls. | # Die aktuelle Zeit und das aktuellen Frame speichern wir ebenfalls. | ||
− | self. | + | self.time = 0 |
− | self. | + | self.current = 0 |
# 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. | + | self.time += time |
# Falls wir den Anzeige-Zeitraum überschreiten, ... | # Falls wir den Anzeige-Zeitraum überschreiten, ... | ||
− | if self. | + | if self.time > self.duration: |
# ... setzten wir die Zeit zurück und gehen zum nächsten Frame. | # ... setzten wir die Zeit zurück und gehen zum nächsten Frame. | ||
− | self. | + | self.time = 0 |
− | self. | + | self.current += 1 |
# Sicherstellen, dass das aktuelle Frame auch verfügbar ist. | # Sicherstellen, dass das aktuelle Frame auch verfügbar ist. | ||
− | if self. | + | if self.current >= self.num: |
− | self. | + | self.current = 0 |
Zeile 964: | Zeile 964: | ||
# 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. | + | screen.blit(self.image, pos, pygame.Rect(self.start_x + (self.width * self.current), self.start_y, self.width, self.height)) |
</sourcecode> | </sourcecode> | ||
Zeile 979: | Zeile 979: | ||
def __init__(self): | def __init__(self): | ||
# Bild laden und erste Animation erstellen: | # Bild laden und erste Animation erstellen: | ||
− | self. | + | self.anim_image_right = Utils.load_image("tileset.png", (255, 0, 255)) |
− | self. | + | self.anim_right = Animation.Animation(self.anim_image_right, 32, 32, 2, 32, 64, 15) |
# Die Grafik spiegeln und in einer neuen Surface speichern, | # Die Grafik spiegeln und in einer neuen Surface speichern, | ||
# dann können wir die linke Animation erstellen. | # dann können wir die linke Animation erstellen. | ||
− | self. | + | self.anim_image_left = pygame.transform.flip(self.anim_image_right, True, False) |
− | self. | + | self.anim_left = Animation.Animation(self.anim_image_left, 32, 32, 2, 32, 64, 15) |
# Start-Position des Players festlegen und | # Start-Position des Players festlegen und | ||
# merken in welche Richtung wir schauen und ob wir überhaupt laufen. | # merken in welche Richtung wir schauen und ob wir überhaupt laufen. | ||
− | self. | + | self.pos_x = 10*32 |
− | self. | + | self.pos_y = 13*32 |
− | self. | + | self.dir = 0 |
− | self. | + | self.walking = False |
def render(self, screen): | def render(self, screen): | ||
# Die Blickrichtung ist links: | # Die Blickrichtung ist links: | ||
− | if self. | + | if self.dir == -1: |
# Wenn der Spieler die linke oder rechte Pfeiltaste gedrückt hat sind wir am laufen, | # Wenn der Spieler die linke oder rechte Pfeiltaste gedrückt hat sind wir am laufen, | ||
− | if self. | + | if self.walking: |
# nur dann die Animation updaten. | # nur dann die Animation updaten. | ||
− | self. | + | self.anim_left.update() |
# Blickrichtung links rendern. | # Blickrichtung links rendern. | ||
− | self. | + | self.anim_left.render(screen, (self.pos_x, self.pos_y)) |
else: | else: | ||
# Und das gleiche nochmal für rechts: | # Und das gleiche nochmal für rechts: | ||
− | if self. | + | if self.walking: |
− | self. | + | self.anim_right.update() |
− | self. | + | self.anim_right.render(screen, (self.pos_x, self.pos_y)) |
# De Laufen-Zustand zurücksetzen, im nächsten Frame bleiben wir stehen. | # De Laufen-Zustand zurücksetzen, im nächsten Frame bleiben wir stehen. | ||
− | self. | + | self.walking = False |
− | def | + | def handle_input(self, key): |
# Linke Pfeiltaste wird gedrückt: | # Linke Pfeiltaste wird gedrückt: | ||
if key == pygame.K_LEFT: | if key == pygame.K_LEFT: | ||
Zeile 1.020: | Zeile 1.020: | ||
# die Blickrichtung festlegen | # die Blickrichtung festlegen | ||
# und den Laufen-Zustand einschalten. | # und den Laufen-Zustand einschalten. | ||
− | self. | + | self.pos_x -= 1 |
− | self. | + | self.dir = -1 |
− | self. | + | self.walking = True |
# Und nochmal für die rechte Pfeiltaste. | # Und nochmal für die rechte Pfeiltaste. | ||
if key == pygame.K_RIGHT: | if key == pygame.K_RIGHT: | ||
− | self. | + | self.pos_x += 1 |
− | self. | + | self.dir = 1 |
− | self. | + | self.walking = True |
</sourcecode> | </sourcecode> | ||
Zeile 1.044: | Zeile 1.044: | ||
# Wir erstellen ein neues Tileset. | # Wir erstellen ein neues Tileset. | ||
# Hier im Tutorial fügen wir manuell vier Tile-Typen hinzu. | # Hier im Tutorial fügen wir manuell vier Tile-Typen hinzu. | ||
− | self. | + | self.tileset = Tileset.Tileset("tileset.png", (255, 0, 255), 32, 32) |
− | self. | + | self.tileset.add_tile("grass", 0, 0) |
− | self. | + | self.tileset.add_tile("mud", 32, 0) |
− | self. | + | self.tileset.add_tile("grass-mud", 0, 64) |
− | self. | + | self.tileset.add_tile("empty", 0, 96) |
# Festlegen der Startposition der Kamera. Hier (0, 0). | # Festlegen der Startposition der Kamera. Hier (0, 0). | ||
− | self. | + | self.camera_x = 0 |
− | self. | + | self.camera_y = 0 |
# Die Größe der Maps in Tiles. | # Die Größe der Maps in Tiles. | ||
− | self. | + | self.width = 30 |
− | self. | + | self.height = 25 |
# Erstellen einer leeren Liste für die Tile Daten. | # Erstellen einer leeren Liste für die Tile Daten. | ||
− | self. | + | self.tiles = list() |
− | + | ||
# Sehr einfache Karte basteln: | # Sehr einfache Karte basteln: | ||
− | for i in range(0, self. | + | for i in range(0, self.height): |
− | self. | + | self.tiles.append(list()) |
− | for j in range(0, self. | + | for j in range(0, self.width): |
if i == 14: | if i == 14: | ||
− | self. | + | self.tiles[i].append("grass") |
elif i == 15: | elif i == 15: | ||
− | self. | + | self.tiles[i].append("grass-mud") |
elif i > 15: | elif i > 15: | ||
− | self. | + | self.tiles[i].append("mud") |
else: | else: | ||
− | self. | + | self.tiles[i].append("empty") |
# Player-Objekt erstellen. | # Player-Objekt erstellen. | ||
− | self. | + | self.player = Player.Player() |
Zeile 1.081: | Zeile 1.081: | ||
def render(self, screen): | def render(self, screen): | ||
# Zeilenweise durch die Tiles durchgehen. | # Zeilenweise durch die Tiles durchgehen. | ||
− | for y in range(0, int(screen.get_height() / self. | + | for y in range(0, int(screen.get_height() / self.tileset.tile_height) + 1): |
# Die Kamera Position mit einbeziehen. | # Die Kamera Position mit einbeziehen. | ||
− | ty = y + self. | + | ty = y + self.camera_y |
− | if ty >= self. | + | if ty >= self.height or ty < 0: |
continue | continue | ||
# Die aktuelle Zeile zum einfacheren Zugriff speichern. | # Die aktuelle Zeile zum einfacheren Zugriff speichern. | ||
− | line = self. | + | line = self.tiles[ty] |
# Und jetzt spaltenweise die Tiles rendern. | # Und jetzt spaltenweise die Tiles rendern. | ||
− | for x in range(0, int(screen.get_width() / self. | + | for x in range(0, int(screen.get_width() / self.tileset.tile_width) + 1): |
# Auch hier müssen wir die Kamera beachten. | # Auch hier müssen wir die Kamera beachten. | ||
− | tx = x + self. | + | tx = x + self.camera_x |
− | if tx >= self. | + | if tx >= self.width or tx < 0: |
continue | continue | ||
# Wir versuchen, die Daten des Tiles zu bekommen. | # Wir versuchen, die Daten des Tiles zu bekommen. | ||
tilename = line[tx] | tilename = line[tx] | ||
− | tile = self. | + | tile = self.tileset.get_tile(tilename) |
# Falls das nicht fehlschlägt können wir das Tile auf die screen-Surface blitten. | # Falls das nicht fehlschlägt können wir das Tile auf die screen-Surface blitten. | ||
if tile is not None: | if tile is not None: | ||
− | screen.blit(self. | + | screen.blit(self.tileset.image, (x * self.tileset.tile_width, y * self.tileset.tile_height), tile.rect) |
# Und zuletzt den Player rendern. | # Und zuletzt den Player rendern. | ||
− | self. | + | self.player.render(screen) |
− | + | ||
− | + | ||
# Tastendrücke an den Player weiterreichen: | # Tastendrücke an den Player weiterreichen: | ||
− | def | + | def handle_input(self, key): |
− | self. | + | self.player.handle_input(key) |
</sourcecode> | </sourcecode> | ||
Zeile 1.117: | Zeile 1.117: | ||
import pygame | import pygame | ||
− | # Unser Tilemap Modul | + | # Unser Tilemap Modul |
import Tilemap | import Tilemap | ||
Zeile 1.164: | Zeile 1.164: | ||
# Alle Tastendrücke auch der Tilemap mitteilen. | # Alle Tastendrücke auch der Tilemap mitteilen. | ||
− | map. | + | map.handle_input(event.key) |
# Die Tilemap auf die screen-Surface rendern. | # Die Tilemap auf die screen-Surface rendern. |
Aktuelle Version vom 13. März 2015, 14:32 Uhr
Klicke hier, um diese Version anzusehen.