Python 2D Spielfigur (allgemein)

Fragen zu Tkinter.
Antworten
Gargoyle D.
User
Beiträge: 10
Registriert: Montag 3. Dezember 2018, 20:24

Hallo,
ich habe ein Pokemon - Spiel nach alter Bauweise programmiert und bin leider schon nach kurzer Zeit an einem Problem gescheitert...
Meine Spielfigur wurde mit Tkinter erzeugt (PhotoImage und Label) und hatte daher einen weißen Rand. Um diesen zu entfernen, habe ich
folgendes versucht:

Code: Alles auswählen

def maketransparent(dateipfad):
    global kooxp, kooyp
    image = Image.open(dateipfad)
    image = image.convert('RGBA')
    startermap = Image.open((allgemeiner_dateipfad + 'NeueMap.gif'))
    startermap = startermap.convert('RGBA')
    datasimage = image.getdata()
    datasstartermap = startermap.crop((kooxp - 8, kooyp - 8, kooxp + 8, kooyp + 8)).getdata()
    newData = []
    for x in range(0, len(datasimage)):
        if datasimage[x][0] == 255 and datasimage[x][1] == 255 and datasimage[x][2] == 255:
            newData.append(datasstartermap[x])
        else:
            newData.append(datasimage[x])
    print('Finished')
    image.putdata(newData)
    image = image.resize((96, 96))
    image.save((allgemeiner_dateipfad + 'RAM.gif'), 'GIF')
Dieses Programm sollte in jedem 16x16 Pixel Bild (so viele Pixel haben die Figuren im Gameboy gehabt :D) die weißen Pixel dem
Hintergrund (der großen Map) angleichen. Allerdings tut es das so langsam, dass selbst mein neuer Rechner ins Schwitzen kommt :(
Frage deshalb: Wie mache ich es allgemein, eine Spielfigur mit transparenten weißen Pixeln hinzubekommen und bitte Erklärungen ohne
pygame, numpy oder andere Module. Nur PIL und Tkinter. (PS: Ich arbeite mit GIF Bilder. kooxp und kooyp sind die Koordinaten deiner
Spielfigur)

Danke im Voraus
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Lösung hast Du Dir doch schon selbst gegeben: man nimmt statt weißer Pixel oder Hintergrundpixeln einfach transparente Pixel, die versteht GIF.
Gargoyle D.
User
Beiträge: 10
Registriert: Montag 3. Dezember 2018, 20:24

@Sirius3: Da ich noch ein relativer Anfänger bin, weiß ich nicht, wie man transparente Pixel erzeugt. Hat das vllt. etwas mit dem Alpha Channel zu tun? Und die wichtigste Frage: Kann ich ein solches Bild in einem Label mit dem gewünschten Effekt darstellen oder muss ich das Hild anders verwenden?
Vllt. Würde mir ein Beispiel fürs bessere Verständnis helfen
Danke im Voraus
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Du benutzt GIF, da kannst Du ja z.B. nachlesen, was das GIF-Format an Transparenz unterstützt und kannst das mit dem Bildbearbeitungsprogramm Deiner Wahl auch erzeugen. Und das kannst Du dann mit einem Tkinter-Label auch einfach ausprobieren.
Gargoyle D.
User
Beiträge: 10
Registriert: Montag 3. Dezember 2018, 20:24

Ich habe deine Tips befolgt und folgenden Code versucht, um alle weißen Pixel transparent zu machen:

Code: Alles auswählen

image = image.open(dateipfad)
image =image.convert("RGBA")
datas = image.getdata()
newData = []
for x in datas:
    if x[0] == 255 and x[1] == 255 and x[2] == 255:
        newData.append((255, 255, 255, 0)) 
    else:
        newData.append(x)
image.putdata(newData)
image.save(dateipfad, "GIF", transparency = )
Was macht dieses transparency und ist das Programm soweit richtig? Dieses Programm ist nicht zur Dauereinsetzung in meinem Pokemonspiel gedacht, sondern zum einmaligen Ausführen.
Danke für eure Hilfe
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na der Code führt ja nicht aus, also ist er auch nicht richtig. Kann es sein, dass du da nicht alles zeigst?

Wie dem auch sei. GIF ist ein Paletten-basiertes Format. Das Argument an transparency ist der Index der Farbe in der Palette, der transparent sein soll. Damit kannst du dir das ganze umkodiere sparen.

Eine Frage/Tipp am Rande: für solchenp Unternehmungen ist tkinter nicht erste Wahl. Warum benutzt du nicht pygame?
Gargoyle D.
User
Beiträge: 10
Registriert: Montag 3. Dezember 2018, 20:24

@__deets__: Ich will keine weiteren Hilfsmoduld verwenden und ich kenne mich nicht mit pygame aus :D Ich merke es mir aber für mein nächstes Projekt.
Das mit transparency funktioniert hervorragend, aller dings gibt es noch ein Problem: Das Label, indem ich das Bild anzeige, hat selbst ja auch einen Hintergrund...
Ich habe es probiert mit:

Code: Alles auswählen

label = tkinter.Label(main, ...., bg = None)
Aber das hat nicht geklappt. Wie bekomme ich den Hintergrund des Labels transparent?
Danke im Voraus
__deets__
User
Beiträge: 14494
Registriert: Mittwoch 14. Oktober 2015, 14:29

Es wäre ggf besser statt ein Label für sowas zu missbrauchen das Canvas Objekt zu nehmen, und alle Bilder da rein zu packen. In EINEN Canvas!

Und was das nicht auskennen angeht - das gilt ja auch für tkinter. Das Problem das ich sehe mit deinem jetzigen Ansatz: du kämpfst gegen “das System”. Tkinter ist nicht für sowas gedacht. Wenn du aber pygame nutzt, finden sich zb auch schon Beispiele für tile engines etc.
Benutzeravatar
wuf
User
Beiträge: 1529
Registriert: Sonntag 8. Juni 2003, 09:50

Hi Gargoyle D

Hier ein Skript zum experimentieren:

Code: Alles auswählen

import tkinter as tk

APP_TITLE = "Pokemon"
APP_XPOS = 100
APP_YPOS = 100
APP_WIDTH = 200
APP_HEIGHT = 200

SPRITE_01 = '''
R0lGODlhEAAQAKU4AAAAAJ0ABhUnMwQsNh4lMAosN6QFDQgvORkrNRorNpgK
EbIDDA4wOqcIEKcJECYsNqMLErYHD6kLE6oLE7IJESAxPK8MFLUMFbYMFSI0
QLwNFv4GFP8JGP8NGv8OHP8QHf8QHv8RHv8RH/8SH/8SIP4TIP8TIP8TIf4U
If8UIf8UIv8VI/8WJP8WJWZmZU9ualVua2Nsa21tbGZvb/+DjP+Ejf+GkP+N
l////////////////////////////////yH5BAEKAD8ALAAAAAAQABAAAAae
wJ9wCCgChkgiQOZyyYpJIWAWEyQSiErmiATcAgbHIuJoNDDcH8C2SaU4sALI
fWJxAbWOyfMiPA4iJiYqR2sbgiMDD3+BJiV2ADQdJR4jHwcHH5UlJitFHigc
LwMfIiOipCkQRSx8foCufyRoaieKjImLDBR3LJeZJSW/IhdpAC0hIpwmKSMk
FmlSLConKSoKE7RRRRgTEhpQUUrhSEEAOw==
'''

MOVE_STEP_TIME = 100 #ms


class Application(object):
    def __init__(self, main_win):
        self.main_win = main_win
        
        self.build()
        self.move_sprite()
        
    def build(self):
        self.main_frame = tk.Frame(self.main_win)
        self.main_frame.pack(fill='both', expand=True)
        
        self.canvas = tk.Canvas(self.main_frame, bg='steelblue',
            highlightthickness=0)
        self.canvas.pack()
        
        #self.pokemon_sprite = tk.PhotoImage(file="your_pokemon_sprite_01.gif")
        self.pokemon_sprite = tk.PhotoImage(data=SPRITE_01)

        self.back_ground_object = self.canvas.create_rectangle(
            50, 50, 150, 150, fill='yellow')
        
        self.canvas.create_image(20, 20, image=self.pokemon_sprite,
            tags='sprite_1')
            
    def move_sprite(self):
        self.canvas.move('sprite_1', 1, 1)
        
        self.main_win.after(MOVE_STEP_TIME, self.move_sprite)
        
def main():
    main_win = tk.Tk()
    main_win.title(APP_TITLE)
    #main_win.geometry("+{}+{}".format(APP_XPOS, APP_YPOS))
    main_win.geometry("{}x{}".format(APP_WIDTH, APP_HEIGHT))
    
    app = Application(main_win)
    
    main_win.mainloop()
 
 
if __name__ == '__main__':
    main()      
Gruss wuf :-)
Take it easy Mates!
Gargoyle D.
User
Beiträge: 10
Registriert: Montag 3. Dezember 2018, 20:24

Danke an wuf und alle, die mir bei meinem Problem geholfen haben, ich habe mit dem Skript experimentiert und es sogar verstanden :lol: .
Mein Pokemonprogramm läuft jetzt reibungslos...
VLG Gargoyle D.
Antworten