Hallo zusammen.
Das ist hier mein erster Beitrag und schon komme ich mit einer Frage an .
Ich möchte eine Map für ein Spiel in einer Liste(Array) abbilden, und zwar 2D. Wie ist das am besten möglich?
Die Map hat eine definierte Größe. Auf ein Tile möchte ich per z.B. map[x][y] zugreifen, so dass mir am Ende an der Position map[10][13] die Nummer des Tiles angezeigt wird, was dort gezeichnet werden soll. Außerdem sollte auch die Tilenummer an der angegebenen Position geändert werden können.
Ich habe vor langer Zeit mal Maps in Pascal über ein 2D-Array abgebildet, habe aber irgendwie keine Ahnung, wie ich das nun in Python realisieren kann. Irgendwelche Tipps?
Danke schonmal,
Christian
Abbilden einer Spielemap in Listen möglich?
Öhm, man macht zuerst'ne Liste aus "Konstanten", sozusagen oO Wo dann die Tiles beschrieben werden:
Dann macht man anschließend ein Feld:
Und dann darstellen, hier mal in'r Konsole:
Oder wie meinst du das oO
Code: Alles auswählen
tiles = ["gras", "sand"] #Natürlich kann man das auch mit anderen Objekten füllen...
Code: Alles auswählen
felder = [[0, 1, 0],
[1, 0, 1]]
Code: Alles auswählen
for zeile in feld:
for feld in zeile:
print tiles[feld],
print
- Ravetracer
- User
- Beiträge: 7
- Registriert: Montag 10. Dezember 2007, 14:50
Mhh... jo, das haut ja so hin. Ich stand irgendwie auf'm Schlauch.
Also wird quasi in der Liste für jede Zeile (Y-Koordinate) ein komplettes Array der Spalten (X-Koordinate) gemacht mit der Tilenummer. Warum ich da nicht drauf gekommen bin.
Kann aber auch daran liegen, dass ich eigentlich arbeiten sollte und nebenbei wieder an Spieleprogrammierung denke *gg*.
Danke dir
Also wird quasi in der Liste für jede Zeile (Y-Koordinate) ein komplettes Array der Spalten (X-Koordinate) gemacht mit der Tilenummer. Warum ich da nicht drauf gekommen bin.
Kann aber auch daran liegen, dass ich eigentlich arbeiten sollte und nebenbei wieder an Spieleprogrammierung denke *gg*.
Danke dir
Mein Tipp: Bau dir deine eigene Abstraktion für die Karte. Wenn du mit `map[x, y]` auf die Felder zugreifen können willst, dann lass deine Karte ein Exemplar der folgenden Klasse sein:
Intern könntest du eine unveränderliche Karte als Tupel speichern.
Code: Alles auswählen
class Map(object):
def __getitem__(self, (x, y)):
"""add your code here..."""
Code: Alles auswählen
class Map(object):
fields = (water, plain, forest, water, plain, desert, swamp, plain, forest)
def __getitem__(self, (x, y)):
return self.fields[x + y * 3]
Alternativ kann man auch ein Dictionary benutzen und ein Tupel aus den Koordinaten als Schlüssel verwenden. Zugriff dann auch mit ``map[x, y]``.
- nkoehring
- User
- Beiträge: 543
- Registriert: Mittwoch 7. Februar 2007, 17:37
- Wohnort: naehe Halle/Saale
- Kontaktdaten:
mmh... ich glaube BlackJacks Vorschlag ist nicht unbedingt der performanteste, oder?
@sma: Map ist eine fertige Funktion in Python. Evtl sollte man den Namen also meiden.
Die Daten sollen doch folgende Form haben:
fuer eine ID bestehend aus x- und y-Koordinate bekomme ich eine beliebiges Objekt zurueck (zB eine Zahl, eine Klasse, einen String... ein Objekt eben).
Also hier mal was entsprechendes. Ich denke mal, wenn ich verstanden habe, was du haben moechtest, wird dir das sehr behilflich sein - eine Komplettloesung sozusagen:
...mit Sicherheit gibt es auch noch bessere Moeglichkeiten, aber das war die Erstbeste die mir einfiel
@sma: Map ist eine fertige Funktion in Python. Evtl sollte man den Namen also meiden.
Die Daten sollen doch folgende Form haben:
fuer eine ID bestehend aus x- und y-Koordinate bekomme ich eine beliebiges Objekt zurueck (zB eine Zahl, eine Klasse, einen String... ein Objekt eben).
Also hier mal was entsprechendes. Ich denke mal, wenn ich verstanden habe, was du haben moechtest, wird dir das sehr behilflich sein - eine Komplettloesung sozusagen:
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: utf-8 -*-
# how to map a map
import sys
from pprint import pprint
class GameMap(object):
def __init__(self, initial_size=(100, 100)):
mapdata = list()
# Karte mit Nullen initialisieren
x, y = initial_size
for i in xrange(x):
mapdata.append(list("0"*y))
self._mapdata = mapdata
def set_field(self, koords, id):
""" setzt den Wert `id` an die Koordinaten `koords`
Argumente:
koords (tuple or list)
id (int or long or whatever you want ^^ )
"""
try:
x, y = koords
except TypeError:
raise AttributeError, "First argument must be a tuple or list!"
except ValueError:
raise AttributeError, "Koordinate list must be of length 2!"
self._mapdata[x][y] = id
def get_field(self, koords):
""" gibt die id auf den Koordinaten `koords` zurueck
Argumente:
koords (tuple or list)
"""
x, y = koords
return self._mapdata[x][y]
if __name__ == '__main__':
# kreiere eine Karte der Groesse 10x10 (Standardgroesse 100x100 Felder)
myMap = GameMap((10, 10))
# setze beliebige Felder mit set_fields(koord-tuple, value):
myMap.set_field((1, 8), 3)
myMap.set_field((3, 6), 5)
myMap.set_field((5, 4), 7)
myMap.set_field((7, 2), 11)
myMap.set_field((9, 0), 13)
# "drucke" die Karte zur Veranschaulichung:
pprint(myMap._mapdata)
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
Was gibt's an einem Dictionary auszusetzen!? Zumindest der Zugriff ist in O(1) Zeit möglich. Ich sehe da keinen gravierenden Nachteil gegenüber einer Liste. Falls die Karte nur spärlich mit betretbaren Feldern besetzt ist, hätte man sogar einen Speichervorteil wenn man ein `collections.defaultdict` verwendet, dass ein "Wand"-Feld für Koordinaten zurück gibt, die nicht im Dictionary enthalten sind.
- nkoehring
- User
- Beiträge: 543
- Registriert: Mittwoch 7. Februar 2007, 17:37
- Wohnort: naehe Halle/Saale
- Kontaktdaten:
Oh, das stimmt natuerlich... Das waere bei groesseren Karten wirklich sehr speicherschonend... da hab ich doch gleich mal umgebaut:
Natuerlich muss man sich was beim Speichern ausdenken wenn man den "Spareffekt" erhalten moechte.
Code: Alles auswählen
#!/usr/bin/python
# -*- coding: utf-8 -*-
# how to map a map
import collections
class GameMap(collections.defaultdict):
def __init__(self, default_value=0):
self.default = default_value
collections.defaultdict.__init__(self, self.default_value)
def default_value(self):
return self.default
if __name__ == '__main__':
# kreiere eine Karte der Groesse 10x10 (Standardgroesse 100x100 Felder)
myMap = GameMap((10, 10))
# setze beliebige Felder, zB:
myMap[(1, 0)] = 3
myMap[(3, 2)] = 5
myMap[(5, 4)] = 7
myMap[(7, 6)] = 11
myMap[(9, 8)] = 13
# "drucke" die Karte zur Veranschaulichung (das wird hier n bissl umstaendlicher...):
for x in xrange(10):
print ""
for y in xrange(10):
print str(myMap[(x, y)]).zfill(2),
Natuerlich muss man sich was beim Speichern ausdenken wenn man den "Spareffekt" erhalten moechte.
[url=http://www.python-forum.de/post-86552.html]~ Wahnsinn ist auch nur eine andere Form der Intelligenz ~[/url]
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
hackerkey://v4sw6CYUShw5pr7Uck3ma3/4u7LNw2/3TXGm5l6+GSOarch/i2e6+t2b9GOen7g5RAPa2XsMr2
- Ravetracer
- User
- Beiträge: 7
- Registriert: Montag 10. Dezember 2007, 14:50
Oha... habe 'ne Weile nicht reingeschaut, da ich nicht dazu gekommen bin. Sorry dafür. Hier hat sich ja einiges getan, doch in der Zwischenzeit habe ich meine Lösung schon gefunden und programmiere gerade einen Map-Editor.
Dieser funktioniert soweit schon recht gut, nur bekomme ich das Undo noch nicht so recht hin. Naja, mal sehen.
Trotzdem vielen Dank für eure Antworten und Lösungen.
Dieser funktioniert soweit schon recht gut, nur bekomme ich das Undo noch nicht so recht hin. Naja, mal sehen.
Trotzdem vielen Dank für eure Antworten und Lösungen.