MAP mit pygame bauen

Hier werden alle anderen GUI-Toolkits sowie Spezial-Toolkits wie Spiele-Engines behandelt.
Antworten
Py19917062
User
Beiträge: 113
Registriert: Freitag 30. Januar 2009, 00:53
Wohnort: Dortmund
Kontaktdaten:

hey leute,

ich weiß gar nicht wie ich die frage formulieren soll :lol:

also nehmen wir an ich habe eine spielfigur im center meines pygame fensters und ich bewege sie, die figur soll weiterhin im center bleiben nur der hintergrund soll eine bewegung der figur darstellen

jetzt möchte ich bald ein kleines rpg schreiben und dort sollte man über große maps laufen können, ohne jetzt alle 5 sekunden über eine klaine map laufen und die nächste laden lassen

ich wollt nur mal die theorie hören wie sich der hintergrund bewegt...
ich kann mir nicht vorstellen, dass man z.B. ein bild mit 30720x30720 pixel läd und es bei jedem tastendruck verschiebt und neu blitet

also wie funktioniert das wircklich?

ich hoffe man konnte mit folgen.... fragt mich wenn ich es noch näher erklären soll


Py19917062
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ich verstehe zwar nix von pygame, aber das klingt nach keiner guten Idee. Üblich ist, die Darstellung aus vielen kleinen Kacheln (engl. Tile) zusammenzustückeln. Google findet in diesem Artikel den Begriff "Tilemap". Es scheint ein Tutorial zu sein. Vielleicht ist es interessant.

Stefan
Py19917062
User
Beiträge: 113
Registriert: Freitag 30. Januar 2009, 00:53
Wohnort: Dortmund
Kontaktdaten:

so hat ich das auch nicht vor xD mit den 30720x30720

das es aus kacheln besteht ist logisch, also wenn die tilemaps ausßerhalb des fensters sind werden sie sie ausgeblendet um den rechner nicht so zu belasten, aber wie erstellt man eine map wenn man z.B. nur ein fenster mir 800x600 hat?

und dein link, zwar bedanke ich mich dafür aber der kerl, der dieses tut geschrieben hat der stellt das überall rein hier ist er auch drin und besondes gut erklärt er das nicht

ich versuche inzwischen selber war heraus zu finden
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ich verstehe nicht, wo du ein Problem mit verschiedenen Fenstergrößen siehst. Angenommen, ich habe eine Klasse `Tile`, deren Exemplare ich mit `draw(x, y)` an Koordinate (x, y) (wobei (0,0) links oben sein soll) auf dem Bildschirm zeichnen kann. Angenommen ich kenne die Höhe und Breite des Bildschirms und die Dimension der Kacheln. Außerdem weiß ich, welche virtuelle Kartenkoordinate in der Mitte des Bildschirms sein soll (`centerx`, `centery`), dann kann ich's doch so machen:

Code: Alles auswählen

class Map(object):
    def __init__(self, centerx, centery):
        self.centerx, self.centery = centerx, centery
        
    def tileat(self, x, y): ...
    
    def draw(self):
        numtilesx = (screen_width + tile_width - 1) // tile_width
        numtilesy = (screen_height + tile_height - 1) // tile_height
        
        width_rounded_to_tiles = numtilesx * tile_width
        height_rounded_to_tiles = numtilesy * tile_height
        
        firstx = self.centerx - width_rounded_to_tiles // 2
        firsty = self.centery - height_rounded_to_tiles // 2
        
        firsttilex = firstx // tile_width
        firsttiley = firsty // tile_height
        
        offsetx = firsttilex * tile_width - firstx
        offsety = firsttiley * tile_height - firsty
        
        for y in range(firsttiley, numtilesy + 1):
            for x in range(firsttilex, numtilesx + 1):
                self.tileat(x, y).draw(
                    x * tile_width + offsetx, 
                    y * tile_height + offsety)
(ohne gewähr)

Stefan
Zuletzt geändert von sma am Donnerstag 6. August 2009, 10:31, insgesamt 1-mal geändert.
Py19917062
User
Beiträge: 113
Registriert: Freitag 30. Januar 2009, 00:53
Wohnort: Dortmund
Kontaktdaten:

ich mein das so

angenommen ich habe jetzt ein fenster mit 1024x768 und habe es gefüllt mit 32x32 kacheln, meine figur bleibt immer in der mitte jetzt geh ich mit der figur nach links oder rechts... jetzt rutschen die map kacheln nach links bzw. rechts und sind außerhalb des fensters

1. was passiert mit den kacheln wenn ich sie nicht mehr sehe?

werden die kacheln ausgeblendet bis sie wieder gebraucht werden?

ich will eigentlich nur wissen wie man eine srollbare map baut.
es ist schwer was darüber im inet zu finden
und die map soll sich nicht ständig wiederholen wie bei diesen space spielen

also mein projekt soll so ähnlich wie das spiel zelda werden (nur halt einem
eigenen charakter, eigen landschaften, eigene monster und items, und
ne andere story)
nur grafisch soll es wie zelda aussehen
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Die Lösung ist ganz einfach: Die Kacheln, die sich im Sichtbereich befinden, werden gezeichnet, alle andern nicht. Im Speicher bleiben die Kacheln und die dazugehörigen Daten natürlich noch liegen. Du musst nur berechnen, welche Felder den gerade zu sehen sind. Das ist aber nicht so schwierig.
Das Leben ist wie ein Tennisball.
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Py19917062 hat geschrieben:i1. was passiert mit den kacheln wenn ich sie nicht mehr sehe?

werden die kacheln ausgeblendet bis sie wieder gebraucht werden?
Hast du mein Beispiel gesehen und verstanden? Genau dies demonstriere ich doch. Es werden immer gleich viele Kacheln gezeichnet, nämlich die, die zu sehen sind unter Berücksichtigung der Koordinaten centerx/centery.

Stefan
Py19917062
User
Beiträge: 113
Registriert: Freitag 30. Januar 2009, 00:53
Wohnort: Dortmund
Kontaktdaten:

sind firstx und firsty nicht beide gleich 0?

aber der spuckt kein fehler aus wenn firstx durch tile_width dividiert wird

könntet ihr mir vlt ein spiel schicken koplet in python wo eine scrolling map verwendet wird? auf pygame.org finde ich keine scrolling maps

@sma: also den code hab ich nur teilweise verschtanden bei der methode
tileat(x, y) versteh ich nicht was ich da genau machen soll
Py19917062
User
Beiträge: 113
Registriert: Freitag 30. Januar 2009, 00:53
Wohnort: Dortmund
Kontaktdaten:

ich seh ständig sowas hier

wooowoowwwoow
wowwowwowwwo
aaauuuuuuddddd
eeeeessssswwww
oooosssssxxxxxx

w = baum
o = wasser
a = feuer
u = weg
d = sand
e = monster
s = dreck
x = zaun

also ist jetzt ein beispiel, sind abgespeichert als text datei und soll die map darstellen

wie bringe ich jetzt zB w dazu ein image zu sein von einem baum?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Warum sollte es einen Fehler geben, wenn 0 durch irgend eine Zahl (außer 0) dividiert wird?

Der Code von sma ist doch genug an Beispiel, versuch dich doch mal an einer eigenen Implementierung. Wenn der Code nicht funktioniert, dann kannst du ihn immer noch hier posten.
Das Leben ist wie ein Tennisball.
Py19917062
User
Beiträge: 113
Registriert: Freitag 30. Januar 2009, 00:53
Wohnort: Dortmund
Kontaktdaten:

ok mach ich morgen und schick ihn falls es nicht funkt

danke
Py19917062
User
Beiträge: 113
Registriert: Freitag 30. Januar 2009, 00:53
Wohnort: Dortmund
Kontaktdaten:

noch eine frage habe ich aber und zwar

wenn ich eine scrolling map benutze muss ich ja die tiles bewegen und nicht
den spieler oder?
und wenn der spieler nicht in der mitte ist bewege ich den spieler
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Ja, ich würde die Figur des Spielers immer in der Mitte anzeigen und nur die Karte unter ihm scrollen.

Stefan
Py19917062
User
Beiträge: 113
Registriert: Freitag 30. Januar 2009, 00:53
Wohnort: Dortmund
Kontaktdaten:

ich denk mal wenn ich deinen code richtig verstanden habe dann kommt ich
erst voran... also setz ich zahlen für die variablen ein... ich bin mir sicher ich hab nen denkfehler i-wo
also das ist dein code sma nur mit zahlen

Code: Alles auswählen

class Map(object):
    def __init__(self, centerx, centery): #512 und 384
        self.centerx, self.centery = centerx, centery
        
    def tileat(self, x, y): ...
    
    def draw(self):
        numtilesx = (screen_width + tile_width - 1) // tile_width # gibt an wie oft tile in x passt hier: (1024 + 32 -1) / 32 hier ca. 33 mal
        numtilesy = (screen_width + tile_width - 1) // tile_width #gibt an wie ift tile in y passt hier: (768 + 32 - 1) / 32 hier ca. 24 mal
        
        width_rounded_to_tiles = numtilesx * tile_width # 33*32=1056
        height_rounded_to_tiles = numtilesy * tile_height # 24*32=800
        
        firstx = self.centerx - width_rounded_to_tiles // 2 # 512 - 528 = -16
        firsty = self.centery - height_rounded_to_tiles // 2 # 368 - 400 = -32
        
        firsttilex = firstx // tile_width # -16/32= -0,5
        firsttiley = firsty // tile_height # -32/32 = -1
        
        offsetx = firsttilex * tile_width - firstx # -0,5*32+16=0
        offsety = firsttiley * tile_height - firsty # -1*32+32=0


        for y in range(firsttiley, numtilesy + 1): #range von -1 bis 26
            for x in range(firsttilex, numtilesx + 1): #range von -0,5 bis 34?
                self.tileat(x, y).draw(
                    x * tile_width + offsetx,              
                    y * tile_height + offsety)
(ohne gewähr)

Stefan
in der methode tileat stell ich mir nichts vor
sma
User
Beiträge: 3018
Registriert: Montag 19. November 2007, 19:57
Wohnort: Kiel

Py19917062 hat geschrieben:in der methode tileat stell ich mir nichts vor
"In"? Du meinst "unter", oder? Eine Klasse Map, so dachte ich mir, wird ja wohl wissen, welche Kachel wo dargestellt werden muss. So, wie du das mit deiner ASCII-Map gezeigt hast. Die Methode `tileat` kann nun ein Tile-Objekt für die übergebene Koordinate liefern, wenn als an Position (42, 11) ein Wald sein soll, eben ein Tile-Objekt, das für Wald steht.

Deine Kommentare stimmen so weit. Allerdings hatte ich nicht bedacht, dass centerx/y so klein könnte, dass die erste Kachel eine negative Koordinate bekommt. Das würde ich in `tileat` abfangen, was für Positionen außerhalb der Karte eine "außerhalb"-Kachel liefern muss. Das `//` ist (hättest du es ausprobiert) eine Ganzzahldivision und kann nicht -0.5 liefern, sondern -1 als nächstkleinere Ganzzahl.

Stefan
Py19917062
User
Beiträge: 113
Registriert: Freitag 30. Januar 2009, 00:53
Wohnort: Dortmund
Kontaktdaten:

stimmt...danke jetzt komm ich glaub ich soweit alleine zurecht
ihr hört bestimmt bald von mir :twisted: :D
Antworten