Wie angedroht habe ich mein NetHack-inspiriertes Spiele-Template dahingehend überarbeitet, daß es nun vollständig objektorientiert funktioniert. Das ist zwar für den derzeitigen Stand ein wenig überdimensioniert, aber da dieses Mazegame ja als Blaupause für eine Umgebung dienen soll, in der ich Algorithmen zur Künstlichen Intelligenz vorstellen und testen will, ist es sicher für später nützlich. Wie man jetzt schon am Quellcode feststellen kann, sind die von mir ungeliebten, globalen Variablen aus dem Template verschwunden. Alleine dafür hat sich der Aufwand schon gelohnt.
# Simple Maze Game with Pygame Zero (v 1.2) , Python 3
# Stage 2 (Objektorientierung)
# Assets: DawnLike-Tileset (CC BY 4.0) by DawnBringer und DragonDePlatino
# (https://opengameart.org/content/dawnlike-16x16-universal-rogue-like-tileset-v181)
# Jörg Kantel 2022 (MIT-Lizenz)
import pgzrun
# WIDTH: 25 Tiles á 16 Pixel + je 20 Pixel Rand
WIDTH = 440
# HEIGHT: 25 Tiles á 16 Pixel + je 20 Pixel Rand
HEIGHT = 440
TITLE = "Mazegame Stage 2"
WALL = 63
DOOR = 62
CHEST = 22
margin_x = 20
margin_y = 20
sz = 16 # Step-/Tile-Size
maze_map = [[63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63],
[63,-1,-1,63,63,63,63,63,63,63,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,63,63,63,63,63],
[63,-1,-1,63,63,63,63,63,63,63,-1,-1,63,63,63,63,63,63,-1,-1,63,63,63,63,63],
[63,-1,-1,-1,-1,-1,-1,-1,63,63,-1,-1,63,63,63,63,63,63,-1,-1,63,63,63,63,63],
[63,-1,-1,-1,-1,-1,-1,-1,63,63,-1,-1,63,63,63,-1,-1,-1,-1,-1,-1,-1,-1,63,63],
[63,63,63,63,63,63,-1,-1,63,63,-1,-1,63,63,63,-1,-1,-1,-1,-1,-1,-1,-1,63,63],
[63,63,63,63,63,63,-1,-1,63,63,-1,-1,63,63,63,63,63,63,-1,-1,63,63,63,63,63],
[63,63,63,63,63,63,-1,-1,63,63,-1,-1,-1,-1,63,63,63,63,-1,-1,63,63,63,63,63],
[63,-1,-1,63,63,63,-1,-1,-1,-1,-1,-1,-1,-1,63,63,63,63,22,-1,63,63,63,63,63],
[63,-1,-1,63,63,63,-1,-1,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63],
[63,-1,-1,-1,-1,-1,-1,-1,-1,-1,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63],
[63,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,63,63,63,63,63,63,63,63],
[63,63,63,63,63,63,63,63,63,63,63,63,-1,-1,-1,-1,-1,63,63,63,63,63,-1,22,63],
[63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,-1,-1,63,63,63,63,63,-1,-1,63],
[63,-1,-1,63,63,63,63,63,63,63,63,63,63,63,63,-1,-1,-1,-1,-1,-1,-1,-1,-1,63],
[63,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,63],
[63,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,63,63,63,63,63,63,63,63,63,63,63,63,63],
[63,63,63,63,63,63,63,63,63,63,-1,-1,63,63,63,63,63,63,63,63,63,63,63,63,63],
[63,63,63,63,63,63,63,63,63,63,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,63],
[63,22,-1,-1,63,63,63,63,63,63,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,63],
[63,-1,-1,-1,63,63,63,63,63,63,63,63,63,63,63,63,63,63,-1,-1,63,63,63,63,63],
[63,-1,-1,-1,-1,-1,63,63,63,63,63,63,63,63,63,63,63,63,-1,-1,63,63,63,63,63],
[63,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,63,63,63,63,-1,-1,-1,-1,-1,-1,-1,-1,63],
[63,63,63,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,-1,62],
[63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63,63]]
class Wall(Actor):
def __init__(self, image):
Actor.__init__(self, image)
self.image = image
def set_screen_pos(self, x, y):
self.x = x
self.y = y
self.topleft = margin_x + self.x*sz, margin_y + self.y*sz
class Door(Actor):
def __init__(self, image):
Actor.__init__(self, image)
self.image = image
self.status = "closed"
def set_screen_pos(self, x, y):
self.x = x
self.y = y
self.topleft = margin_x + self.x*sz, margin_y + self.y*sz
class Chest (Actor):
def __init__(self, image):
Actor.__init__(self, image)
self.image = image
self.score = 100
def set_screen_pos(self, x, y):
self.x = x
self.y = y
self.topleft = margin_x + self.x*sz, margin_y + self.y*sz
class Rogue(Actor):
def __init__(self, image):
Actor.__init__(self, image)
self.image = image
self.xpos = 1 # x-Position im Grid
self.ypos = 1 # y-Position im Grid
self.set_screen_pos()
self.dir = None
self.score = 0
def set_screen_pos(self):
self.topleft = margin_x + self.xpos*sz, margin_y + self.ypos*sz
def walk(self):
if self.dir == "left":
move_to_x = self.xpos - 1
move_to_y = self.ypos
self.dir = None
# Kollisionserkennung
if (move_to_x, move_to_y) not in walls_pos:
self.xpos -= 1
self.set_screen_pos()
elif self.dir == "right":
move_to_x = self.xpos + 1
move_to_y = self.ypos
self.dir = None
# Kollisionserkennung
if (move_to_x, move_to_y) not in walls_pos:
self.xpos += 1
self.set_screen_pos()
elif self.dir == "up":
move_to_x = self.xpos
move_to_y = self.ypos - 1
self.dir = None
# Kollisionserkennung
if (move_to_x, move_to_y) not in walls_pos:
self.ypos -= 1
self.set_screen_pos()
elif self.dir == "down":
move_to_x = self.xpos
move_to_y = self.ypos + 1
self.dir = None
# Kollisionserkennung
if (move_to_x, move_to_y) not in walls_pos:
self.ypos += 1
self.set_screen_pos()
rogue = Rogue("rogue16")
walls = []
chests = []
doors = []
walls_pos = []
chests_pos = []
def init_game():
for y in range(25):
for x in range(25):
if maze_map[y][x] == WALL:
wall = Wall("wall16")
wall.set_screen_pos(x, y)
walls.append(wall)
walls_pos.append((x, y))
if maze_map[y][x] == DOOR:
door = Door("door16")
door.set_screen_pos(x, y)
doors.append(door)
walls_pos.append((x, y))
if maze_map[y][x] == CHEST:
chest = Chest("chest16")
chest.set_screen_pos(x, y)
chests.append(chest)
chests_pos.append((x, y))
def update():
rogue.walk()
for chest in chests:
if rogue.colliderect(chest):
rogue.score += chest.score
chests.remove(chest)
print(rogue.score)
def draw():
screen.fill((90, 90, 90))
for wall in walls:
wall.draw()
for door in doors:
door.draw()
for chest in chests:
chest.draw()
rogue.draw()
def on_key_down(key):
if key == keys.LEFT:
rogue.dir = "left"
elif key == keys.RIGHT:
rogue.dir = "right"
elif key == keys.UP:
rogue.dir = "up"
elif key == keys.DOWN:
rogue.dir = "down"
if key == keys.ESCAPE: # ESCAPE beendet das Spiel
print("Bye, bye, Baby!")
quit()
init_game()
pgzrun.go()
Ich habe dem Labyrinth zusätzlich eine Tür spendiert, damit es einen Ausgang gibt. Und für jede erbeutete Schatzschatulle bekommt der Spieler 100 Punkte.
Ich möchte dieses Template testweise zu einem kompletten Spiel ausbauen, daher wird es in einer weiteren Version Gegener geben, denen der Spieler ausweichen muß, sonst stirbt er. Und wenn er alle Schatullen erbeutet hat, öffnet sich die Tür und das Spiel ist gewonnen.
Die erste Übung in Künstlicher Intelligenz wird sein, die Gegner nicht nur hirnlos durch das Labyrinth irren zu lassen, sondern sobald der Spieler in »Sichtweite« eines Gegners ist, nimmt dieser die Verfolgung auf. In diesem Zusammenhang möchte ich »endliche Automaten« vorstellen und diskutieren. Still digging!
Die Sprites und Tiles habe ich dem DawnLike-Tileset auf OpenGameArt.org entnommen. Die Lizenz (CC BY 4.0) verlangt zwingend die Namensnennung der Schöpfer DawnBringer und DragonDePlatino. Dem bin ich hiermit pflichtbewußt nachgekommen. Und wie immer findet Ihr den Quellcode und die Assets auch in meinem GitHub-Repositorium.
Über …
Der Schockwellenreiter ist seit dem 24. April 2000 das Weblog digitale Kritzelheft von Jörg Kantel (Neuköllner, EDV-Leiter Rentner, 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
Diese Spalte wurde absichtlich leergelassen!