Heute möchte ich mein hier begonnenes Tutorial über einen Side-Scroller mit Bewegungsparallaxe abschließen. Die Spielfigur (das kleine rosa Alien) soll hüpfen können und es soll Hindernisse geben, über die sie springen muß. Erfreulicherweise muß dafür nur wenig im bisherigen Code ergänzt werden, denn da die Bewegungsparallaxe schon weitgehend vollständig programmiert ist, bleibt der Reiter backgrounds.py
von Änderungen verschont.
Den Reiter sprites.py
habe ich erst einmal um die Klasse Obstacle()
erweitert, die ebenfalls von der Klasse Sprite()
erbt1:
class Obstacle(Sprite): def __init__(self, x, y, im): Sprite.__init__(self, x, y) self.im = loadImage(im + ".png") self.step = -4 def update(self): self.x += self.step if self.x <= -150: self.x = width + 750 def show(self): image(self.im, self.x, self.y)
Die verschiedenen Hindernisse unterscheiden sich im Prinzip nur durch ihre unterschiedlichen Bilder, daher wird der Bildname (ohne Suffix) dem Konstruktor mitgegeben, der sich daraus den Namen der Bilddatei zusammenbastelt. Das Beispielprogramme besitzt drei verschiedene Hindernisse, die – sobald sie den linken Bildrand verlassen haben – weit rechts außerhalb des Bildes wieder ins Spiel kommen. Den Parameter width + 750
habe ich experimentell ermittelt und muß bei mehr oder anderen Hindernissen angepaßt werden.
Auch die Bilder der Hindernisse habe ich der freien Sprite-Sammlung von Kenney.nl entnommen.
Im Hauptprogramm habe ich die Hindernisse dann in der setup()
-Funktion – nach den Hügeln, aber vor dem Alien – eingebaut
obstacles.append(Obstacle(width + 150, 330, "spikes")) obstacles.append(Obstacle(width + 650, 330, "spikesBottomAlt")) obstacles.append(Obstacle(width + 750, 330, "spikesBottom")) obstacles.append(Obstacle(width + 1190, 330, "fence")) obstacles.append(Obstacle(width + 1250, 330, "fenceBroken")) obstacles.append(Obstacle(width + 1310, 330, "fence"))
und in draw()
(ebenfalls nach den Hintergründen aber vor dem Alien) zum Leben erweckt:
for obstacle in obstacles: obstacle.update() obstacle.show()
Die Hindernisse sind noch einmal einen Tick (-4
) schneller, als die kleinen Hügel im Hintergrund, so daß hiermit eine vierte Parallaxen-Ebene erschaffen wurde.
Damit das kleine rosa Alien nicht in die Hindernisse hineinrennt, muß die Möglichkeit geschaffen werden, daß es darüber springen kann. Dazu mußten in der Klasse Alien()
einige Veränderungen vorgenommen werden. Erst einmal wurde die Methode update()
überschrieben
def update(self): if self.status == "jumping": self.vely += 0.1
und in der Methode show()
das Alien zu einem kleinen endlichen Automaten mit zwei Zuständen definiert:
def show(self): if self.status == "walking": self.count += 1 if self.count > 15: self.count = 0 if self.count < 8: image(self.im1, self.x, self.y) else: image(self.im2, self.x, self.y) elif self.status == "jumping": self.y += self.vely image(self.im3, self.x, self.y) if self.y >= 320: self.y = 320 self.status = "walking"
Wenn das Alien im Zustand jumping
ist, bleibt es so lange in diesem Zustand, bis es wieder den Boden berührt. Dann geht es in den Zustand walking
über. Getriggert wird dieser endliche Automat im Hauptprogramm, das um die Funktion keyPressed()
ergänzt wurde:
def keyPressed(): alien = sprites[0] if key == CODED: if keyCode == UP and alien.status == "walking": alien.vely = -5 alien.status = "jumping"
Wenn die Pfeiltaste nach oben gedrückt wird und das Alien im Zustand walking
ist, dann (und nur dann) 2 wird vely
auf -5
gesetzt und das Alien geht in den Zustand jumping
über.
Mit der Zeile alien = sprites[0]
habe ich die Funktion etwas lesefreundlicher gemacht, denn die Liste sprites
ist auch hier eigentlich overkill. Aber wenn Ihr das Spiel mal ergänzen wollt, indem Dutzende von Aliens Eure Spielwelt bevölkern, werdet Ihr froh sein, wenn Ihr diese Listenstruktur vorausschauend angelegt habt.
Bevor ich das gesamte Programm noch einmal aufliste, zuerst die verwendeten Bilder, ohne die Ihr das Spiel ja nicht nachprogrammieren könnt:
Der Reiter backgrounds.py
ist seit der ersten Version unverändert geblieben:
# coding=utf-8 class Hill(object): def __init__(self, x, r, s, c): self.xpos = x self.radius = r self.step = s self.col = c def update(self): self.xpos += self.step if self.xpos <= -self.radius: self.xpos = width + self.radius def show(self): fill(self.col) circle(self.xpos, 400, 2*self.radius) class Cloud(object): def __init__(self, x, s): self.xpos = x self.step = s def update(self): self.xpos += self.step if self.xpos <= -200: self.xpos = width + 200 def show(self): fill("#ffffff") circle(self.xpos, 150, 100) circle(self.xpos, 200, 100) circle(self.xpos - 50, 200, 100) circle(self.xpos + 50, 200, 100)
Die meisten Veränderungen gab es im Reiter sprites.py
:
# coding=utf-8 class Sprite(object): def __init__(self, x, y): self.x = x self.y = y self.vely = 0 self.step = 0 def update(self): pass def show(self): pass class Alien(Sprite): def __init__(self, x, y): Sprite.__init__(self, x, y) self.status = "walking" self.im1 = loadImage("alienwalk1.png") self.im2 = loadImage("alienwalk2.png") self.im3 = loadImage("alienjump.png") self.count = 0 def update(self): if self.status == "jumping": self.vely += 0.1 def show(self): if self.status == "walking": self.count += 1 if self.count > 15: self.count = 0 if self.count < 8: image(self.im1, self.x, self.y) else: image(self.im2, self.x, self.y) elif self.status == "jumping": self.y += self.vely image(self.im3, self.x, self.y) if self.y >= 320: self.y = 320 self.status = "walking" class Obstacle(Sprite): def __init__(self, x, y, im): Sprite.__init__(self, x, y) self.im = loadImage(im + ".png") self.step = -4 def update(self): self.x += self.step if self.x <= -150: self.x = width + 750 def show(self): image(self.im, self.x, self.y)
Und auch das Hauptprogramm hat einige Veränderungen erfahren:
# Side Scroller 2 from backgrounds import Hill, Cloud from sprites import Alien, Obstacle FPS = 60 clouds = [] bighills = [] smallhills = [] sprites = [] obstacles = [] def setup(): size(800, 450) this.surface.setTitle("Side Scroller 2: Jump, Ally, jump!") clouds.append(Cloud(400, -1)) for i in range(3): bighills.append(Hill(i*400, 200, -2, "#63e06b")) for i in range(6): smallhills.append(Hill(i*200, 100, -3, "#217424")) obstacles.append(Obstacle(width + 150, 330, "spikes")) obstacles.append(Obstacle(width + 650, 330, "spikesBottomAlt")) obstacles.append(Obstacle(width + 750, 330, "spikesBottom")) obstacles.append(Obstacle(width + 1190, 330, "fence")) obstacles.append(Obstacle(width + 1250, 330, "fenceBroken")) obstacles.append(Obstacle(width + 1310, 330, "fence")) sprites.append(Alien(66, 320)) frameRate(FPS) noStroke() def draw(): background(64, 176, 226) # Wolke(n) im Hintergrund for cloud in clouds: cloud.update() cloud.show() # Große Hügel im Hintergrund for hill in bighills: hill.update() hill.show() # Kleine Hügel im Vordergrund for hill in smallhills: hill.update() hill.show() # Erdboden fill("#ffd05e") rect(0, 400, width, 50) # Obstacles for obstacle in obstacles: obstacle.update() obstacle.show() # Sprites (erst einmal nur das rosa Alien) for sprite in sprites: sprite.update() sprite.show() def keyPressed(): alien = sprites[0] if key == CODED: if keyCode == UP and alien.status == "walking": alien.vely = -5 alien.status = "jumping"
Das war es dann erst einmal mit dem kleinen Sidescroller-Programm. Natürlich ist es kein fertiges Spiel, es sollte nur zeigen, wie man einen Sidescroller mit Parallaxenverschiebung programmiert. Der nächste Schritt wäre, Kollisionserkennung und komplexere Hindernisse einzubauen.
Einen interessanten Ansatz zur Kollisionserkennung – speziell für Sidescroller und Platformer – hat jemand, der sich DaFluffyPotato nennt, in obigem Video veröffentlicht. Seine Programmierumgebung ist Pygame, aber das Prinzip läßt sich sicher leicht nach Processing.py portieren. Wer weiß, vielleicht wird dies mein nächstes Tutorial? Still digging!
Das ist momentan ein wenig Overkill, aber wenn Ihr später zum Beispiel Kollisionserkennung einbauen wollt, dann ist es sinnvoll, diverse Sprite-Listen zu verwalten, um sie auf Kollision überprüfen zu können. ↩
Durch das logische und
wird verhindert, daß das Alien durch das Drücken der Pfeiltast weiter nach oben katapultiert werden kann, wenn es sich schon in der Luft befindet. Denn das Alien soll nur springen können, wenn es festen Boden unter den Füßen hat. ↩
Ü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