Seite 1 von 1

Klicker-Game

Verfasst: Mittwoch 5. August 2020, 16:23
von gesundheitsmann
Hallo liebe Community,

ich habe folgendes Problem.

Ich würde gerne ein Klicker-Spiel programmieren, doch nun ist es in Phyton ja so, dass sich Gui´s und While-Schleifen nicht vertragen. Deswegen habe ich mich ein bisschen in OOP eingelesen. Ich habe versucht die Anweißungen für die Knöpfe in Classen zu erstellen. Soweit so gut, aber eine While-True schleife bekomme ich immer noch nicht reingewurstelt. Kann mir jemand eine empfelung geben wo ich nachlesen kann?
und hier ist noch mein jetziger Code

Code: Alles auswählen

from tkinter import *
from time import sleep
Geld = 0
Limo = 0
window = Tk()
class Geld_machen:
    def Geld():
        global Geld
        Geld = Geld + 1
        print('Dein Guthaben', Geld)
        return Geld
    button1 = Button(window, text='Geld', command=Geld)
    button1.pack()

class Limo_Stand:
    def limo_stand():
        global Geld
        global Limo
        if Geld >= 10:
            Geld = Geld - 10
            Limo = Limo + 1
            print('Du hast jetzt', Limo, 'Limostand')
        else:
            print('Du hast nicht genug Geld')
    button2 = Button(window, text='Limostand', command=limo_stand)
    button2.pack()

class IDLE:
    def Idle():
        global Geld
        global Limo
        if Limo >= 1:
            while True:
                Geld = Geld + (1 * Limo)
                print(Geld)
                sleep(1)
    button3 = Button(window, text='Idle', command=Idle)
    button3.pack()
    


Liebe Grüße
gesundheitsmann

Re: Klicker-Game

Verfasst: Mittwoch 5. August 2020, 16:36
von Sirius3
Das, was Du da geschrieben hast, sind keine Klassen, sondern nur Funktionen, die Du unverständlicherweise in einen class-Block gepackt hast.
Richtige Klassen haben eine __init__-Methode und müssen instanziiert werden.
Vergiss gleich wieder, dass es `global` gibt. Wenn Du Zustand über das Ende einer Funktion speichern willst, mußt Du eine Klasse definieren und dort Attribute setzen.
Statt einer while-Schleife benutzt man in tkinter die after-Methode, die nach einer bestimmten Zeit eine Funktion aufruft.
Statt print-Ausgaben wären wahrscheinlich Label besser geeigent, damit alles im Fenster bleibt.

Code: Alles auswählen

import tkinter as tk

class Game:
    def __init__(self):
        self.window = tk.Tk()
        self.geld = 0
        self.limo = 0
        tk.Button(self.window, text='Geld', command=self.geld_laden).pack()
        tk.Button(self.window, text='Limostand', command=self.limo_stand).pack()
        self.geld_anzeige = tk.Label(self.window, text=f"Dein Guthaben: {self.geld}")
        self.geld_anzeige.pack()
        self.limo_anzeige = tk.Label(self.window, text=f'Du hast jetzt {self.limo} Limostand')
        self.limo_anzeige.pack()
        
    def run(self):
        self.window.after(1000, self.idle)
        self.window.mainloop()
        
    def geld_laden(self):
        self.geld += 1
        self.geld_anzeige['text'] = f"Dein Guthaben: {self.geld}"

    def limo_stand(self):
        if self.geld >= 10:
            self.geld -= 10
            self.limo += 1
            self.geld_anzeige['text'] = f"Dein Guthaben: {self.geld}"
            self.limo_anzeige['text'] = f'Du hast jetzt {self.limo} Limostand'
        else:
            # TODO: Status-Label einfügen
            print('Du hast nicht genug Geld')

    def idle(self):
        self.geld += self.limo
        self.geld_anzeige['text'] = f"Dein Guthaben: {self.geld}"
        self.window.after(1000, self.idle)

def main():
    game = Game()
    game.run()
    
if __name__ == '__main__':
    main()

Re: Klicker-Game

Verfasst: Mittwoch 5. August 2020, 16:42
von __blackjack__
@gesundheitsmann: Das sind keine Klassen. ”Klassen” ohne `__init__()` und mit nur einer ”Methode” sind keine Klassen. Die ”Methoden” tun ja nicht mal so als wenn sie welche wären weil keine davon `self` als Argument entgegen nimmt.

Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst. ``global`` hat in einem sauberen Programm nichts zu suchen. Wenn man (echte) Klassen im Programm hat, dann gibt es nicht mal mehr eine Ausrede für ``global``.

Sternchen-Importe sind Böse™. Da holt man sich gerade bei `tkinter` fast 200 Namen ins Modul von denen nur ein kleiner Bruchteil verwendet wird. Auch Namen die gar nicht in `tkinter` definiert werden, sondern ihrerseits von woanders importiert werden. Das macht Programme unnötig unübersichtlicher und fehleranfälliger und es besteht die Gefahr von Namenskollisionen.

Namen werden in Python klein_mit_unterstrichen geschrieben. Ausnahmen sind Konstanten (KOMPLETT_GROSS) und Klassen (MixedCase).

Man nummeriert keine Namen. Man will sich entweder bessere, passendere Namen ausdenken, oder gar keine Einzelnamen und Werte sondern eine Datenstruktur. Oft eine Liste. Hier will man einfach nur `button` verwenden. Selbst wenn die nummerierten `button`-Namen nicht in verschiedenen Namensräumen stecken würden, braucht man den Wert ja nicht noch mal nach dem erstellen und anordnen des `Button`-Objekts. Im Grunde braucht man nicht mal den Namen wenn man die beiden Schritte nicht auf zwei Anweisungen aufteilen würde.

Du suchst die `after()`-Methode auf `Widget`-Objekten um eine Methode jede Sekunde aufrufen zu lassen die das macht was jetzt im Schleifenkörper steht.