Hallo zusammen, gibt es eine Möglichkeit, die Fenster per Befehl in den
Vollbildmodus umzuschalten?
Thx im Vorraus. kossi83
Vollbildmodus bei Tkinter
-
- Python-Forum Veteran
- Beiträge: 1209
- Registriert: Montag 29. September 2003, 17:18
- Wohnort: Purkersdorf (bei Wien [Austria])
Hi!
Gruß, mawe
Code: Alles auswählen
from Tkinter import *
root = Tk()
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.geometry("%dx%d+0+0" % (w, h))
root.mainloop()
Super vielen Dank. Hatte schon in tausend Bücher nachgeguckt. Aber nirgendsgefunden.
Gruss kossi83
Gruss kossi83

-
- User
- Beiträge: 16
- Registriert: Donnerstag 14. April 2005, 12:53
...und wie maximiere ich ein Fenster nur. Also so, dass es nicht die Taskleite verdeckt?
funktioniert nicht.
Wie muss ich deinconify benutzen?
Code: Alles auswählen
hauptfenster = Tk()
hauptfenster.deiconify()
Wie muss ich deinconify benutzen?
-
- Python-Forum Veteran
- Beiträge: 1209
- Registriert: Montag 29. September 2003, 17:18
- Wohnort: Purkersdorf (bei Wien [Austria])
Hi!

Im Ernst, keine Ahnung. Du könntest vielleicht von der screenheight die Höhe der Taskleiste abziehen, aber die ist ja nicht überall gleich hoch ...
Zu deiconify: Das ist ja eigentlich nur zum Enticonifizieren (tolles Wort
). Wenn Du vorher mit withdraw() das Fenster zu einem Icon geschrumpft hast, kannst Du's mit deiconify() wieder zurückholen.
Gruß, mawe
Drück einfach auf das Maximier-IconlangeLeitung hat geschrieben: ...und wie maximiere ich ein Fenster nur. Also so, dass es nicht die Taskleite verdeckt?

Im Ernst, keine Ahnung. Du könntest vielleicht von der screenheight die Höhe der Taskleiste abziehen, aber die ist ja nicht überall gleich hoch ...
Zu deiconify: Das ist ja eigentlich nur zum Enticonifizieren (tolles Wort

Gruß, mawe
Hallo kossi83
ich habe deinen Beitrag gelesen und mir ist eingefallen, dass ich mal ein Spiel programmiert habe, welches
im Vollbild ist:
Der Vollbildcode einzelnt ist wie folgt:
Da dein Beitrag schon älter ist glaube ich nicht, dass ich Dir damit helfen kann, aber so ist die Frage beantwortet. 
ich habe deinen Beitrag gelesen und mir ist eingefallen, dass ich mal ein Spiel programmiert habe, welches
im Vollbild ist:
Code: Alles auswählen
from itertools import cycle
from random import randrange
from tkinter import Canvas, Tk, messagebox, font
root = Tk()
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(1)
root.geometry("%dx%d+0+0" % (w, h))
canvas_width = w
canvas_height = h
c = Canvas(root, width=canvas_width, height=canvas_height, background="deep sky blue")
c.create_rectangle(-5, canvas_height - 300, canvas_width + 50, canvas_height + 50, fill="sea green", width=0)
c.create_oval(-80, -80, 120, 120, fill="orange", width=0)
c.pack()
ei_width = 45
ei_height = 55
global ei_punktzahl
ei_punktzahl = 10
global ei_tempo
ei_tempo = 500
global ei_intervall
ei_intervall = 4000
global schwierigkeit
schwierigkeit = 0.95
global verbleibende_leben
korb_color = "blue"
korb_width = 100
korb_height = 100
korb_start_x = canvas_width / 2 - korb_width / 2
korb_start_y = canvas_height - korb_height - 20
korb_start_x2 = korb_start_x + korb_width
korb_start_y2 = korb_start_y + korb_height
korb = c.create_arc(korb_start_x, korb_start_y, korb_start_x2, korb_start_y2, start=200, extent=140, style="arc", outline=korb_color, width=3)
game_font = font.nametofont("TkFixedFont")
game_font.config(size=18)
global punktzahl
punktzahl = 0
punktzahl_text = c.create_text(10, 10, anchor="nw", font=game_font, fill="darkblue", text="Punktzahl: " + str(punktzahl))
verbleibende_leben = 3
leben_text = c.create_text(canvas_width - 10, 10, anchor="ne", font=game_font, fill="darkblue", text="Leben " + str(verbleibende_leben))
eier = []
def create_ei():
x = randrange(10, 1550)
y = 40
neues_ei = c.create_oval(x, y, x + ei_width, y + ei_height, fill="yellow", width=0)
eier.append(neues_ei)
root.after(ei_intervall, create_ei)
def move_eier():
for ei in eier:
(ei_x, ei_y, ei_x2, ei_y2,) = c.coords(ei)
c.move(ei, 0, 10)
if ei_y2 > canvas_height:
ei_gefallen(ei)
root.after(ei_tempo, move_eier)
def ei_gefallen(ei):
eier.remove(ei)
c.delete(ei)
verliere_ein_leben()
if verbleibende_leben == 0:
messagebox.showinfo("Game Over", "Punkte: " + str(punktzahl))
root.destroy()
exit
def verliere_ein_leben():
global verbleibende_leben
verbleibende_leben = verbleibende_leben - 1
c.itemconfigure(leben_text, text="Leben: " + str(verbleibende_leben))
def check_fang():
(korb_x, korb_y, korb_x2, korb_y2) = c.coords(korb)
for ei in eier:
(ei_x, ei_y, ei_x2, ei_y2,) = c.coords(ei)
if korb_x < ei_x and ei_x2 < korb_x2 and korb_y2 - ei_y2 < 40:
eier.remove(ei)
c.delete(ei)
erhoehe_punktzahl(ei_punktzahl)
root.after(100, check_fang)
def erhoehe_punktzahl(points):
global punktzahl, ei_tempo, ei_intervall
punktzahl = punktzahl + 1
ei_tempo = int(ei_tempo * schwierigkeit)
ei_intervall = int(ei_intervall * schwierigkeit)
c.itemconfigure(punktzahl_text, text="punktzahl: " + str(punktzahl))
def move_left(event):
(x1, y1, x2, y2) = c.coords(korb)
if x1 > 0:
c.move(korb, -20, 0)
def move_right(event):
(x1, y1, x2, y2) = c.coords(korb)
if x2 < canvas_width:
c.move(korb, 20, 0)
c.bind("<Left>", move_left)
c.bind("<Right>", move_right)
c.focus_set()
root.after(1000, create_ei)
root.after(1000, move_eier)
root.after(1000, check_fang)
root.mainloop()
Der Vollbildcode einzelnt ist wie folgt:
Code: Alles auswählen
from tkinter import *
root = Tk()
w, h = root.winfo_screenwidth(), root.winfo_screenheight()
root.overrideredirect(1)
root.geometry("%dx%d+0+0" % (w, h))
root.mainloop()

- __blackjack__
- User
- Beiträge: 13925
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
@timm4444: Da hättest Du vielleicht besser nur den Code für Vollbild gezeigt, denn der Rest ist ziemlich schlecht.
`override_redirect()` ist keine gute Idee, denn damit funktioniert das Programm nicht mehr unter Linux und MacOS, weil dort dann die Tastenereignisse nicht mehr funktionieren und man das Programm nicht mehr steuern kann.
`cycle` aus `itertools` wird importiert, aber nirgends verwendet.
Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
``global`` auf Modulebene hat keinerlei Wirkung. ``global`` sollte auch überhaupt nicht verwendet werden. Alles was Funktionen und Methoden ausser Konstanten benötigen sollten sie als Argument(e) übergeben bekommen.
Namen sollten nicht kryptisch abgekürzt werden, schon gar nicht nur mit einem einzigen Buchstaben. Wenn man `canvas` meint, sollte man nicht nur `c` schreiben. Noch sinnloser wird es wenn man erst `w` und `h` definiert und die dann noch mal an `canvas_width` und `canvas_height` bindet.
Zeichenkettenformatierung mit ``%`` würde ich nicht mehr machen ohne guten Grund. Es gibt f-Zeichenkettenliterale oder die `format()`-Methode auf Zeichenketten. Das sollte man auch statt ``+`` und `str()` verwenden, denn das ist eher BASIC denn Python.
`ei_punktzahl` wird nicht wirklich verwendet. Das wird zwar bei `erhoehe_punktzahl()` als Argument übergeben, die Funktion verwendet das Argument aber überhaupt nicht.
In `ei_gefallen()` wird `destroy()` aufgerufen statt die Tk-Hauptschleife einfach mit `quit()` zu verlassen. Das ist weniger brachial und man kann das auch auf anderen Widget-Objekten aufrufen, da braucht man nicht zwingend das `Tk`-Objekt für.
Das `exit` in der Funktion macht nichts und der Name dürfte eigentlich auch gar nicht existieren wenn man ihn nicht aus `sys` importiert. Die Funktion sollte man aber sowieso nur im Hauptprogramm verwenden und dort auch nur wenn man zumindest potentiell einen anderen Rückgabecode als 0 an den Aufrufer des Programms übermitteln will.
Die 1550 in `create_ei()` ist ziemlich magisch und ein Problem wenn man das Programm auf kleinen Displays laufen lässt. Der Wert sollte von der Breite des `Canvas`-Objekts abhängen.
Zwischenstand:
Die `main()` ist ein bisschen zu lang und es werden zu viele Argumente in der Gegend herum gereicht. Für jede nicht-triviale GUI braucht man deshalb objektorientierte Programmierung.
`check_fang()` macht mit `after()` eigentlich wenig Sinn. Die Funktion sollte einfach nach jedem Eier bewegen aufgerufen werden oder nach jedem Korb bewegen.
`override_redirect()` ist keine gute Idee, denn damit funktioniert das Programm nicht mehr unter Linux und MacOS, weil dort dann die Tastenereignisse nicht mehr funktionieren und man das Programm nicht mehr steuern kann.
`cycle` aus `itertools` wird importiert, aber nirgends verwendet.
Auf Modulebene sollte nur Code stehen der Konstanten, Funktionen, und Klassen definiert. Das Hauptprogramm steht üblicherweise in einer Funktion die `main()` heisst.
``global`` auf Modulebene hat keinerlei Wirkung. ``global`` sollte auch überhaupt nicht verwendet werden. Alles was Funktionen und Methoden ausser Konstanten benötigen sollten sie als Argument(e) übergeben bekommen.
Namen sollten nicht kryptisch abgekürzt werden, schon gar nicht nur mit einem einzigen Buchstaben. Wenn man `canvas` meint, sollte man nicht nur `c` schreiben. Noch sinnloser wird es wenn man erst `w` und `h` definiert und die dann noch mal an `canvas_width` und `canvas_height` bindet.
Zeichenkettenformatierung mit ``%`` würde ich nicht mehr machen ohne guten Grund. Es gibt f-Zeichenkettenliterale oder die `format()`-Methode auf Zeichenketten. Das sollte man auch statt ``+`` und `str()` verwenden, denn das ist eher BASIC denn Python.
`ei_punktzahl` wird nicht wirklich verwendet. Das wird zwar bei `erhoehe_punktzahl()` als Argument übergeben, die Funktion verwendet das Argument aber überhaupt nicht.
In `ei_gefallen()` wird `destroy()` aufgerufen statt die Tk-Hauptschleife einfach mit `quit()` zu verlassen. Das ist weniger brachial und man kann das auch auf anderen Widget-Objekten aufrufen, da braucht man nicht zwingend das `Tk`-Objekt für.
Das `exit` in der Funktion macht nichts und der Name dürfte eigentlich auch gar nicht existieren wenn man ihn nicht aus `sys` importiert. Die Funktion sollte man aber sowieso nur im Hauptprogramm verwenden und dort auch nur wenn man zumindest potentiell einen anderen Rückgabecode als 0 an den Aufrufer des Programms übermitteln will.
Die 1550 in `create_ei()` ist ziemlich magisch und ein Problem wenn man das Programm auf kleinen Displays laufen lässt. Der Wert sollte von der Breite des `Canvas`-Objekts abhängen.
Zwischenstand:
Code: Alles auswählen
#!/usr/bin/env python3
from functools import partial
from random import randrange
from tkinter import ARC, Canvas, IntVar, Tk, font, messagebox
SCHWIERIGKEIT = 0.95
EI_WIDTH = 45
EI_HEIGHT = 55
EI_TEMPO = 500
EI_INTERVALL = 4000
KORB_COLOR = "blue"
KORB_WIDTH = 100
KORB_HEIGHT = 100
def create_ei(canvas, canvas_width, eier, ei_intervall):
x = randrange(10, canvas_width - EI_WIDTH - 10)
y = 40
eier.append(
canvas.create_oval(
x, y, x + EI_WIDTH, y + EI_HEIGHT, fill="yellow", width=0
)
)
canvas.after(
ei_intervall.get(), create_ei, canvas, canvas_width, eier, ei_intervall
)
def verliere_ein_leben(canvas, leben_text, verbleibende_leben):
verbleibende_leben.set(verbleibende_leben.get() - 1)
canvas.itemconfigure(leben_text, text=f"Leben: {verbleibende_leben.get()}")
def ei_gefallen(canvas, leben_text, eier, punktzahl, verbleibende_leben, ei):
eier.remove(ei)
canvas.delete(ei)
verliere_ein_leben(canvas, leben_text, verbleibende_leben)
if verbleibende_leben.get() == 0:
messagebox.showinfo("Game Over", f"Punkte: {punktzahl.get()}")
canvas.quit()
def move_eier(
canvas,
canvas_height,
leben_text,
punktzahl,
verbleibende_leben,
eier,
ei_tempo,
):
for ei in eier:
_, _, _, ei_y2 = canvas.coords(ei)
canvas.move(ei, 0, 10)
if ei_y2 > canvas_height:
ei_gefallen(
canvas, leben_text, eier, punktzahl, verbleibende_leben, ei
)
canvas.after(
ei_tempo.get(),
move_eier,
canvas,
canvas_height,
leben_text,
punktzahl,
verbleibende_leben,
eier,
ei_tempo,
)
def erhoehe_punktzahl(
canvas, punktzahl_text, punktzahl, ei_tempo, ei_intervall
):
punktzahl.set(punktzahl.get() + 1)
ei_tempo.set(int(ei_tempo.get() * SCHWIERIGKEIT))
ei_intervall.set(int(ei_intervall.get() * SCHWIERIGKEIT))
canvas.itemconfigure(punktzahl_text, text=f"punktzahl: {punktzahl.get()}")
def check_fang(
canvas, punktzahl_text, punktzahl, korb, eier, ei_tempo, ei_intervall
):
korb_x, _, korb_x2, korb_y2 = canvas.coords(korb)
for ei in eier:
ei_x, _, ei_x2, ei_y2 = canvas.coords(ei)
if korb_x < ei_x and ei_x2 < korb_x2 and korb_y2 - ei_y2 < 40:
eier.remove(ei)
canvas.delete(ei)
erhoehe_punktzahl(
canvas, punktzahl_text, punktzahl, ei_tempo, ei_intervall
)
canvas.after(
100,
check_fang,
canvas,
punktzahl_text,
punktzahl,
korb,
eier,
ei_tempo,
ei_intervall,
)
def move_left(canvas, korb, _event):
x_1, _, _, _ = canvas.coords(korb)
if x_1 > 0:
canvas.move(korb, -20, 0)
def move_right(canvas, canvas_width, korb, _event):
_, _, x_2, _ = canvas.coords(korb)
if x_2 < canvas_width:
canvas.move(korb, 20, 0)
def main():
root = Tk()
canvas_width, canvas_height = (
root.winfo_screenwidth(),
root.winfo_screenheight(),
)
root.attributes("-fullscreen", True)
root.geometry(f"{canvas_width}x{canvas_height}+0+0")
ei_tempo = IntVar(value=EI_TEMPO)
ei_intervall = IntVar(value=EI_INTERVALL)
punktzahl = IntVar(value=0)
verbleibende_leben = IntVar(value=3)
eier = list()
canvas = Canvas(
root,
width=canvas_width,
height=canvas_height,
background="deep sky blue",
)
canvas.create_rectangle(
-5,
canvas_height - 300,
canvas_width + 50,
canvas_height + 50,
fill="sea green",
width=0,
)
canvas.create_oval(-80, -80, 120, 120, fill="orange", width=0)
canvas.pack()
korb_start_x = canvas_width / 2 - KORB_WIDTH / 2
korb_start_y = canvas_height - KORB_HEIGHT - 20
korb_start_x2 = korb_start_x + KORB_WIDTH
korb_start_y2 = korb_start_y + KORB_HEIGHT
korb = canvas.create_arc(
korb_start_x,
korb_start_y,
korb_start_x2,
korb_start_y2,
start=200,
extent=140,
style=ARC,
outline=KORB_COLOR,
width=3,
)
game_font = font.nametofont("TkFixedFont")
game_font.config(size=18)
punktzahl_text = canvas.create_text(
10,
10,
anchor="nw",
font=game_font,
fill="darkblue",
text=f"Punktzahl: {punktzahl.get()}",
)
leben_text = canvas.create_text(
canvas_width - 10,
10,
anchor="ne",
font=game_font,
fill="darkblue",
text=f"Leben {verbleibende_leben.get()}",
)
root.after(1000, create_ei, canvas, canvas_width, eier, ei_intervall)
root.after(
1000,
move_eier,
canvas,
canvas_height,
leben_text,
punktzahl,
verbleibende_leben,
eier,
ei_tempo,
)
root.after(
1000,
check_fang,
canvas,
punktzahl_text,
punktzahl,
korb,
eier,
ei_tempo,
ei_intervall,
)
canvas.bind("<Left>", partial(move_left, canvas, korb))
canvas.bind("<Right>", partial(move_right, canvas, canvas_width, korb))
canvas.focus_set()
root.mainloop()
if __name__ == "__main__":
main()
`check_fang()` macht mit `after()` eigentlich wenig Sinn. Die Funktion sollte einfach nach jedem Eier bewegen aufgerufen werden oder nach jedem Korb bewegen.
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
- __blackjack__
- User
- Beiträge: 13925
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Die Namen mal alle auf Englisch und teilweise inhaltlich leicht angepasst. EI_TEMPO war beispielsweise falsch, denn Tempo bedeutet ja höherer Wert = schneller, was bei dieser Konstanten genau umgekehrt ist.
Und eine erste Klasse herausgezogen, die von `Canvas` abgeleitet ist, und die Anzeigefläche samt Punkte- und Lebenanzeige repräsentiert. Die Anzahl der Argumente hat an einigen Stellen dadurch schon abgenommen. `check_catch()` (ehemals `check_fang()`) reicht aber immer noch zu viel von Aufruf zu Aufruf.
Als nächstes würde vielleicht eine `Sprite`-Klasse Sinn machen, die das `Display`-Objekt und die ID von einem Ei und dem Korb kapselt. Und eine Hilfsklasse die so ähnlich wie `pygame.Rect` funktioniert und die Operationen auf den Koordinaten leichter lesbar und verständlich macht.
Und eine erste Klasse herausgezogen, die von `Canvas` abgeleitet ist, und die Anzeigefläche samt Punkte- und Lebenanzeige repräsentiert. Die Anzahl der Argumente hat an einigen Stellen dadurch schon abgenommen. `check_catch()` (ehemals `check_fang()`) reicht aber immer noch zu viel von Aufruf zu Aufruf.
Code: Alles auswählen
#!/usr/bin/env python3
from functools import partial
from random import randrange
from tkinter import ARC, Canvas, IntVar, Tk, font, messagebox, NE, NW
DIFFICULTY_FACTOR = 0.95
EGG_WIDTH = 45
EGG_HEIGHT = 55
EGG_MOVE_DELAY = 500
EGG_DROP_INTERVAL = 4000
BASKET_COLOR = "blue"
BASKET_WIDTH = BASKET_HEIGHT = 100
class Display(Canvas):
def __init__(self, master, width, height):
self.width = width
self.height = height
Canvas.__init__(
self,
master=master,
width=self.width,
height=self.height,
background="deep sky blue",
)
#
# Ground and sun.
#
# TODO Make sizes depend on display size.
#
self.create_rectangle(
-5,
self.height - 300,
self.width + 5,
self.height + 5,
fill="sea green",
width=0,
)
self.create_oval(-80, -80, 120, 120, fill="orange", width=0)
game_font = font.nametofont("TkFixedFont")
game_font.config(size=18)
self._score_text_id = self.create_text(
10, 10, anchor=NW, font=game_font, fill="darkblue",
)
self._life_count_text_id = self.create_text(
self.width - 10, 10, anchor=NE, font=game_font, fill="darkblue",
)
self.set_score("-")
self.set_life_count("-")
def set_score(self, value):
self.itemconfigure(self._score_text_id, text=f"Punktzahl: {value}")
def set_life_count(self, value):
self.itemconfigure(self._life_count_text_id, text=f"Leben {value}")
def create_egg(display, eggs, egg_drop_interval_var):
x = randrange(10, display.width - EGG_WIDTH - 10)
y = 40
eggs.append(
display.create_oval(
x, y, x + EGG_WIDTH, y + EGG_HEIGHT, fill="yellow", width=0
)
)
display.after(
egg_drop_interval_var.get(),
create_egg,
display,
eggs,
egg_drop_interval_var,
)
def lose_a_life(display, life_count_var):
life_count_var.set(life_count_var.get() - 1)
display.set_life_count(life_count_var.get())
def on_uncatched_egg(display, eggs, score_var, life_count_var, egg):
eggs.remove(egg)
display.delete(egg)
lose_a_life(display, life_count_var)
if life_count_var.get() == 0:
#
# FIXME While the message box is shown there is still a task running
# creating new eggs.
#
messagebox.showinfo("Game Over", f"Punkte: {score_var.get()}")
display.quit()
def move_eggs(
display, score_var, life_count_var, eggs, egg_move_delay_var,
):
for egg in eggs:
_, _, _, egg_y2 = display.coords(egg)
display.move(egg, 0, 10)
if egg_y2 > display.height:
on_uncatched_egg(display, eggs, score_var, life_count_var, egg)
display.after(
egg_move_delay_var.get(),
move_eggs,
display,
score_var,
life_count_var,
eggs,
egg_move_delay_var,
)
def increase_score(
display, score_var, egg_move_delay_var, egg_drop_interval_var
):
score_var.set(score_var.get() + 1)
#
# TODO Don't change the values of `egg_move_delay_var` and
# `egg_drop_interval_var` but calculate them from `score_var`.
#
egg_move_delay_var.set(int(egg_move_delay_var.get() * DIFFICULTY_FACTOR))
egg_drop_interval_var.set(
int(egg_drop_interval_var.get() * DIFFICULTY_FACTOR)
)
display.set_score(score_var.get())
def check_catch(
display,
score_var,
basket,
eggs,
egg_move_delay_var,
egg_drop_interval_var,
):
basket_x, _, basket_x2, basket_y2 = display.coords(basket)
for egg in eggs:
egg_x, _, egg_x2, egg_y2 = display.coords(egg)
if basket_x < egg_x and egg_x2 < basket_x2 and basket_y2 - egg_y2 < 40:
eggs.remove(egg)
display.delete(egg)
increase_score(
display, score_var, egg_move_delay_var, egg_drop_interval_var
)
display.after(
100,
check_catch,
display,
score_var,
basket,
eggs,
egg_move_delay_var,
egg_drop_interval_var,
)
def move_basket_left(display, basket, _event):
x_1, _, _, _ = display.coords(basket)
if x_1 > 0:
display.move(basket, -20, 0)
def move_basket_right(display, basket, _event):
_, _, x_2, _ = display.coords(basket)
if x_2 < display.width:
display.move(basket, 20, 0)
def main():
root = Tk()
display_width, display_height = (
root.winfo_screenwidth(),
root.winfo_screenheight(),
)
root.attributes("-fullscreen", True)
root.geometry(f"{display_width}x{display_height}+0+0")
egg_move_delay_var = IntVar(value=EGG_MOVE_DELAY)
egg_drop_interval_var = IntVar(value=EGG_DROP_INTERVAL)
score_var = IntVar(value=0)
life_count_var = IntVar(value=3)
eggs = list()
display = Display(root, display_width, display_height)
display.pack()
display.set_score(score_var.get())
display.set_life_count(life_count_var.get())
basket_start_x = display.width / 2 - BASKET_WIDTH / 2
basket_start_y = display.height - BASKET_HEIGHT - 20
basket = display.create_arc(
basket_start_x,
basket_start_y,
basket_start_x + BASKET_WIDTH,
basket_start_y + BASKET_HEIGHT,
start=200,
extent=140,
style=ARC,
outline=BASKET_COLOR,
width=3,
)
root.after(1000, create_egg, display, eggs, egg_drop_interval_var)
root.after(
1000,
move_eggs,
display,
score_var,
life_count_var,
eggs,
egg_move_delay_var,
)
#
# TODO This should not be an indepedent asynchronous task but called each
# time the eggs and/or the basket moved.
#
root.after(
1000,
check_catch,
display,
score_var,
basket,
eggs,
egg_move_delay_var,
egg_drop_interval_var,
)
display.bind("<Left>", partial(move_basket_left, display, basket))
display.bind("<Right>", partial(move_basket_right, display, basket))
display.focus_set()
root.mainloop()
if __name__ == "__main__":
main()
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
@__blackjack__: Ja, du hast recht, es ist nicht das beste Programm. Das war einer meiner ersten Projekte und ich habe den Code nicht mehr übearbeitet. Ich hatte bis letzten Monat Propleme mit Pygame und konnte es deswegen so nicht machen.
Ich werde in Zukunft meine Codes nochmal auf sowas überprüfen bevor ich Codes ins Forum stelle.
Ich werde in Zukunft meine Codes nochmal auf sowas überprüfen bevor ich Codes ins Forum stelle.

- __blackjack__
- User
- Beiträge: 13925
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Eine `Box`-Klasse ähnlich `pygame.Rect` und eine `Sprite`-Klasse eingeführt:
Als nächstes könnte man eine Klasse einführen, die die `eggs`-Liste durch ein Objekt ersetzt, welches sich um die Eier kümmert.
Code: Alles auswählen
#!/usr/bin/env python3
from functools import partial, total_ordering
from random import randrange
from tkinter import ARC, NE, NW, Canvas, IntVar, Tk, font, messagebox
DIFFICULTY_FACTOR = 0.95
EGG_WIDTH = 45
EGG_HEIGHT = 55
EGG_MOVE_DELAY = 500
EGG_DROP_INTERVAL = 4000
BASKET_COLOR = "blue"
BASKET_WIDTH = BASKET_HEIGHT = 100
class Box:
def __init__(self, left, top, right, bottom):
self._left = left
self._top = top
self._right = right
self._bottom = bottom
def __repr__(self):
return (
f"{self.__class__.__name__}"
f"{self.left, self.top, self.right, self.bottom}"
)
def __iter__(self):
yield self.left
yield self.top
yield self.right
yield self.bottom
@property
def left(self):
return self._left
@left.setter
def left(self, value):
self.move(value - self.left, 0)
@property
def top(self):
return self._top
@top.setter
def top(self, value):
self.move(0, value - self.top)
@property
def right(self):
return self._right
@right.setter
def right(self, value):
self.move(value - self.right, 0)
@property
def bottom(self):
return self._bottom
@bottom.setter
def bottom(self, value):
self.move(0, value - self.bottom)
@property
def width(self):
return self.right - self.left
@property
def height(self):
return self.bottom - self.top
@property
def center_x(self):
return self.width // 2 + self.left
@center_x.setter
def center_x(self, value):
self.move(value - self.center_x, 0)
def move(self, x_delta, y_delta):
self._left += x_delta
self._top += y_delta
self._right += x_delta
self._bottom += y_delta
@classmethod
def from_position_and_size(cls, x, y, width, height):
return cls(x, y, x + width, y + height)
@classmethod
def from_size(cls, width, height):
return cls.from_position_and_size(0, 0, width, height)
class Display(Canvas):
def __init__(self, master, width, height):
self.width = width
self.height = height
self._box = Box.from_size(self.width, self.height)
Canvas.__init__(
self,
master=master,
width=self.width,
height=self.height,
background="deep sky blue",
)
#
# Ground and sun.
#
# TODO Let sizes depend on display size.
#
self.create_rectangle(
-5,
self.height - 300,
self.width + 5,
self.height + 5,
fill="sea green",
width=0,
)
#
# TODO `Box.from_center_and_radius()`!?
#
self.create_oval(-80, -80, 120, 120, fill="orange", width=0)
game_font = font.nametofont("TkFixedFont")
game_font.config(size=18)
self._score_text_id = self.create_text(
10, 10, anchor=NW, font=game_font, fill="darkblue",
)
self._life_count_text_id = self.create_text(
self.width - 10, 10, anchor=NE, font=game_font, fill="darkblue",
)
self.set_score("-")
self.set_life_count("-")
def get_box(self):
return self._box
def set_score(self, value):
self.itemconfigure(self._score_text_id, text=f"Punktzahl: {value}")
def set_life_count(self, value):
self.itemconfigure(self._life_count_text_id, text=f"Leben {value}")
@total_ordering
class Sprite:
def __init__(self, display, item_id):
self.display = display
self.id = item_id
def __str__(self):
return str(self.id)
def __eq__(self, other):
return self.id == other.id
def __ne__(self, other):
return not self == other
def __lt__(self, other):
return self.id < other.id
def __hash__(self):
return hash(self.id)
def get_box(self):
return Box(*self.display.coords(self))
def move(self, x_delta, y_delta):
self.display.move(self, x_delta, y_delta)
def delete(self):
self.display.delete(self)
self.id = None
@classmethod
def new_arc(cls, display, box, **kwargs):
return cls(display, display.create_arc(*box, **kwargs))
@classmethod
def new_oval(cls, display, box, **kwargs):
return cls(display, display.create_oval(*box, **kwargs))
def create_egg(display, eggs, egg_drop_interval_var):
eggs.append(
Sprite.new_oval(
display,
Box.from_position_and_size(
randrange(10, display.width - EGG_WIDTH - 10),
40,
EGG_WIDTH,
EGG_HEIGHT,
),
fill="yellow",
width=0,
)
)
display.after(
egg_drop_interval_var.get(),
create_egg,
display,
eggs,
egg_drop_interval_var,
)
def lose_a_life(display, life_count_var):
life_count_var.set(life_count_var.get() - 1)
display.set_life_count(life_count_var.get())
def on_uncatched_egg(display, eggs, score_var, life_count_var, egg):
eggs.remove(egg)
egg.delete()
lose_a_life(display, life_count_var)
if life_count_var.get() == 0:
#
# FIXME While the message box is shown there is still a task running
# creating new eggs.
#
messagebox.showinfo("Game Over", f"Punkte: {score_var.get()}")
display.quit()
def move_eggs(
display, score_var, life_count_var, eggs, egg_move_delay_var,
):
for egg in eggs:
egg.move(0, 10)
if egg.get_box().bottom > display.height:
on_uncatched_egg(display, eggs, score_var, life_count_var, egg)
display.after(
egg_move_delay_var.get(),
move_eggs,
display,
score_var,
life_count_var,
eggs,
egg_move_delay_var,
)
def increase_score(
display, score_var, egg_move_delay_var, egg_drop_interval_var
):
score_var.set(score_var.get() + 1)
#
# TODO Don't change the values of `egg_move_delay_var` and
# `egg_drop_interval_var` but calculate them from `score_var`.
#
egg_move_delay_var.set(int(egg_move_delay_var.get() * DIFFICULTY_FACTOR))
egg_drop_interval_var.set(
int(egg_drop_interval_var.get() * DIFFICULTY_FACTOR)
)
display.set_score(score_var.get())
def check_catch(
display,
score_var,
basket,
eggs,
egg_move_delay_var,
egg_drop_interval_var,
):
basket_box = basket.get_box()
for egg in eggs:
egg_box = egg.get_box()
if (
basket_box.left < egg_box.left
and basket_box.right > egg_box.right
and basket_box.bottom - egg_box.bottom < 40
):
eggs.remove(egg)
egg.delete()
increase_score(
display, score_var, egg_move_delay_var, egg_drop_interval_var
)
display.after(
100,
check_catch,
display,
score_var,
basket,
eggs,
egg_move_delay_var,
egg_drop_interval_var,
)
def move_basket_left(basket, _event):
if basket.get_box().left > 0:
basket.move(-20, 0)
def move_basket_right(display, basket, _event):
if basket.get_box().right < display.width:
basket.move(20, 0)
def main():
root = Tk()
display_width, display_height = (
root.winfo_screenwidth(),
root.winfo_screenheight(),
)
root.attributes("-fullscreen", True)
root.geometry(f"{display_width}x{display_height}+0+0")
egg_move_delay_var = IntVar(value=EGG_MOVE_DELAY)
egg_drop_interval_var = IntVar(value=EGG_DROP_INTERVAL)
score_var = IntVar(value=0)
life_count_var = IntVar(value=3)
eggs = list()
display = Display(root, display_width, display_height)
display.pack()
display.set_score(score_var.get())
display.set_life_count(life_count_var.get())
display_box = display.get_box()
basket_box = Box.from_size(BASKET_WIDTH, BASKET_HEIGHT)
basket_box.center_x = display_box.center_x
basket_box.bottom = display_box.bottom - 20
basket = Sprite.new_arc(
display,
basket_box,
start=200,
extent=140,
style=ARC,
outline=BASKET_COLOR,
width=3,
)
root.after(1000, create_egg, display, eggs, egg_drop_interval_var)
root.after(
1000,
move_eggs,
display,
score_var,
life_count_var,
eggs,
egg_move_delay_var,
)
#
# TODO This should not be an indepedent asynchronous task but called each
# time the eggs and/or the basket moved.
#
root.after(
1000,
check_catch,
display,
score_var,
basket,
eggs,
egg_move_delay_var,
egg_drop_interval_var,
)
display.bind("<Left>", partial(move_basket_left, basket))
display.bind("<Right>", partial(move_basket_right, display, basket))
display.focus_set()
root.mainloop()
if __name__ == "__main__":
main()
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
- __blackjack__
- User
- Beiträge: 13925
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Eine Klasse zur Verwaltung der Eier:
Code: Alles auswählen
#!/usr/bin/env python3
from functools import partial, total_ordering
from random import randrange
from tkinter import ARC, NE, NW, Canvas, IntVar, Tk, font, messagebox
DIFFICULTY_FACTOR = 0.95
EGG_WIDTH = 45
EGG_HEIGHT = 55
EGG_MOVE_DELAY = 500
EGG_DROP_INTERVAL = 4000
BASKET_COLOR = "blue"
BASKET_WIDTH = BASKET_HEIGHT = 100
class Box:
def __init__(self, left, top, right, bottom):
self._left = left
self._top = top
self._right = right
self._bottom = bottom
def __repr__(self):
return (
f"{self.__class__.__name__}"
f"{self.left, self.top, self.right, self.bottom}"
)
def __iter__(self):
yield self.left
yield self.top
yield self.right
yield self.bottom
@property
def left(self):
return self._left
@left.setter
def left(self, value):
self.move(value - self.left, 0)
@property
def top(self):
return self._top
@top.setter
def top(self, value):
self.move(0, value - self.top)
@property
def right(self):
return self._right
@right.setter
def right(self, value):
self.move(value - self.right, 0)
@property
def bottom(self):
return self._bottom
@bottom.setter
def bottom(self, value):
self.move(0, value - self.bottom)
@property
def width(self):
return self.right - self.left
@property
def height(self):
return self.bottom - self.top
@property
def center_x(self):
return self.width // 2 + self.left
@center_x.setter
def center_x(self, value):
self.move(value - self.center_x, 0)
def move(self, x_delta, y_delta):
self._left += x_delta
self._top += y_delta
self._right += x_delta
self._bottom += y_delta
@classmethod
def from_position_and_size(cls, x, y, width, height):
return cls(x, y, x + width, y + height)
@classmethod
def from_size(cls, width, height):
return cls.from_position_and_size(0, 0, width, height)
class Display(Canvas):
def __init__(self, master, width, height):
self.width = width
self.height = height
self._box = Box.from_size(self.width, self.height)
Canvas.__init__(
self,
master=master,
width=self.width,
height=self.height,
background="deep sky blue",
)
#
# Ground and sun.
#
# TODO Let sizes depend on display size.
#
self.create_rectangle(
-5,
self.height - 300,
self.width + 5,
self.height + 5,
fill="sea green",
width=0,
)
#
# TODO `Box.from_center_and_radius()`!?
#
self.create_oval(-80, -80, 120, 120, fill="orange", width=0)
game_font = font.nametofont("TkFixedFont")
game_font.config(size=18)
self._score_text_id = self.create_text(
10, 10, anchor=NW, font=game_font, fill="darkblue",
)
self._life_count_text_id = self.create_text(
self.width - 10, 10, anchor=NE, font=game_font, fill="darkblue",
)
self.set_score("-")
self.set_life_count("-")
def get_box(self):
return self._box
def set_score(self, value):
self.itemconfigure(self._score_text_id, text=f"Punktzahl: {value}")
def set_life_count(self, value):
self.itemconfigure(self._life_count_text_id, text=f"Leben {value}")
@total_ordering
class Sprite:
def __init__(self, display, item_id):
self.display = display
self.id = item_id
def __str__(self):
return str(self.id)
def __eq__(self, other):
return self.id == other.id
def __ne__(self, other):
return not self == other
def __lt__(self, other):
return self.id < other.id
def __hash__(self):
return hash(self.id)
def get_box(self):
return Box(*self.display.coords(self))
def move(self, x_delta, y_delta):
self.display.move(self, x_delta, y_delta)
def delete(self):
self.display.delete(self)
self.id = None
@classmethod
def new_arc(cls, display, box, **kwargs):
return cls(display, display.create_arc(*box, **kwargs))
@classmethod
def new_oval(cls, display, box, **kwargs):
return cls(display, display.create_oval(*box, **kwargs))
class Eggs:
def __init__(self, display, move_delay, drop_interval):
self._display = display
self.move_delay = move_delay
self.drop_interval = drop_interval
self._items = list()
def create_egg(self):
self._items.append(
Sprite.new_oval(
self._display,
Box.from_position_and_size(
randrange(10, self._display.width - EGG_WIDTH - 10),
40,
EGG_WIDTH,
EGG_HEIGHT,
),
fill="yellow",
width=0,
)
)
def _apply_filter_action(self, action):
remaining_eggs = list()
for egg in self._items:
if action(egg):
remaining_eggs.append(egg)
else:
egg.delete()
deleted_egg_count = len(self._items) - len(remaining_eggs)
self._items = remaining_eggs
return deleted_egg_count
def move(self):
def action(egg):
egg.move(0, 10)
return egg.get_box().bottom <= self._display.height
return self._apply_filter_action(action)
def check_catch(self, basket):
basket_box = basket.get_box()
def action(egg):
egg_box = egg.get_box()
return not (
basket_box.left < egg_box.left
and basket_box.right > egg_box.right
and basket_box.bottom - egg_box.bottom < 40
)
return self._apply_filter_action(action)
def create_egg(widget, eggs):
eggs.create_egg()
widget.after(eggs.drop_interval, create_egg, widget, eggs)
def move_eggs(display, score_var, life_count_var, eggs):
dropped_egg_count = eggs.move()
if dropped_egg_count:
life_count_var.set(life_count_var.get() - dropped_egg_count)
display.set_life_count(life_count_var.get())
if life_count_var.get() <= 0:
#
# FIXME While the message box is shown there is still a task running
# creating new eggs.
#
messagebox.showinfo("Game Over", f"Punkte: {score_var.get()}")
display.quit()
display.after(
eggs.move_delay, move_eggs, display, score_var, life_count_var, eggs
)
def check_catch(display, score_var, basket, eggs):
caught_egg_count = eggs.check_catch(basket)
if caught_egg_count:
score_var.set(score_var.get() + caught_egg_count)
eggs.move_delay = int(
EGG_MOVE_DELAY * DIFFICULTY_FACTOR ** score_var.get()
)
eggs.drop_interval = int(
EGG_DROP_INTERVAL * DIFFICULTY_FACTOR ** score_var.get()
)
display.set_score(score_var.get())
display.after(100, check_catch, display, score_var, basket, eggs)
def move_basket_left(basket, _event):
if basket.get_box().left > 0:
basket.move(-20, 0)
def move_basket_right(display, basket, _event):
if basket.get_box().right < display.width:
basket.move(20, 0)
def main():
root = Tk()
display_width, display_height = (
root.winfo_screenwidth(),
root.winfo_screenheight(),
)
root.attributes("-fullscreen", True)
root.geometry(f"{display_width}x{display_height}+0+0")
score_var = IntVar(value=0)
life_count_var = IntVar(value=3)
display = Display(root, display_width, display_height)
display.pack()
display.set_score(score_var.get())
display.set_life_count(life_count_var.get())
eggs = Eggs(display, EGG_MOVE_DELAY, EGG_DROP_INTERVAL)
display_box = display.get_box()
basket_box = Box.from_size(BASKET_WIDTH, BASKET_HEIGHT)
basket_box.center_x = display_box.center_x
basket_box.bottom = display_box.bottom - 20
basket = Sprite.new_arc(
display,
basket_box,
start=200,
extent=140,
style=ARC,
outline=BASKET_COLOR,
width=3,
)
root.after(1000, create_egg, root, eggs)
root.after(1000, move_eggs, display, score_var, life_count_var, eggs)
#
# TODO This should not be an indepedent asynchronous task but called each
# time the eggs and/or the basket moved.
#
root.after(1000, check_catch, display, score_var, basket, eggs)
display.bind("<Left>", partial(move_basket_left, basket))
display.bind("<Right>", partial(move_basket_right, display, basket))
display.focus_set()
root.mainloop()
if __name__ == "__main__":
main()
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware
- __blackjack__
- User
- Beiträge: 13925
- Registriert: Samstag 2. Juni 2018, 10:21
- Wohnort: 127.0.0.1
- Kontaktdaten:
Und nun eine, ich denke vorläufig letzte Version, mit einer Klasse für das Hauptfenster und dem `attr`-Modul für die Klassen, die nicht von `tkinter`-Typen abgeleitet sind:
Code: Alles auswählen
#!/usr/bin/env python3
from random import randrange
from tkinter import ARC, NE, NW, Canvas, Tk, font, messagebox
from attr import attrib, attrs
DIFFICULTY_FACTOR = 0.95
EGG_WIDTH = 45
EGG_HEIGHT = 55
EGG_MOVE_DELAY = 500
EGG_DROP_INTERVAL = 4000
BASKET_COLOR = "blue"
BASKET_WIDTH = BASKET_HEIGHT = 100
@attrs
class Box:
_left = attrib()
_top = attrib()
_right = attrib()
_bottom = attrib()
def __iter__(self):
yield self.left
yield self.top
yield self.right
yield self.bottom
@property
def left(self):
return self._left
@left.setter
def left(self, value):
self.move(value - self.left, 0)
@property
def top(self):
return self._top
@top.setter
def top(self, value):
self.move(0, value - self.top)
@property
def right(self):
return self._right
@right.setter
def right(self, value):
self.move(value - self.right, 0)
@property
def bottom(self):
return self._bottom
@bottom.setter
def bottom(self, value):
self.move(0, value - self.bottom)
@property
def width(self):
return self.right - self.left
@property
def height(self):
return self.bottom - self.top
@property
def center_x(self):
return self.width // 2 + self.left
@center_x.setter
def center_x(self, value):
self.move(value - self.center_x, 0)
def move(self, x_delta, y_delta):
self._left += x_delta
self._top += y_delta
self._right += x_delta
self._bottom += y_delta
@classmethod
def from_position_and_size(cls, x, y, width, height):
return cls(x, y, x + width, y + height)
@classmethod
def from_size(cls, width, height):
return cls.from_position_and_size(0, 0, width, height)
class Display(Canvas):
def __init__(self, master, width, height):
self.width = width
self.height = height
self._box = Box.from_size(self.width, self.height)
Canvas.__init__(
self,
master=master,
width=self.width,
height=self.height,
background="deep sky blue",
)
#
# Ground and sun.
#
# TODO Let sizes depend on display size.
#
self.create_rectangle(
-5,
self.height - 300,
self.width + 5,
self.height + 5,
fill="sea green",
width=0,
)
#
# TODO `Box.from_center_and_radius()`!?
#
self.create_oval(-80, -80, 120, 120, fill="orange", width=0)
game_font = font.nametofont("TkFixedFont")
game_font.config(size=18)
self._score_text_id = self.create_text(
10, 10, anchor=NW, font=game_font, fill="darkblue",
)
self._life_count_text_id = self.create_text(
self.width - 10, 10, anchor=NE, font=game_font, fill="darkblue",
)
self.set_score("-")
self.set_life_count("-")
def get_box(self):
return self._box
def set_score(self, value):
self.itemconfigure(self._score_text_id, text=f"Punktzahl: {value}")
def set_life_count(self, value):
self.itemconfigure(self._life_count_text_id, text=f"Leben {value}")
@attrs
class Sprite:
_display = attrib(eq=False)
_id = attrib()
def __str__(self):
return str(self._id)
def get_box(self):
return Box(*self._display.coords(self))
def move(self, x_delta, y_delta):
self._display.move(self, x_delta, y_delta)
def delete(self):
self._display.delete(self)
self._id = None
@classmethod
def new_arc(cls, display, box, **kwargs):
return cls(display, display.create_arc(*box, **kwargs))
@classmethod
def new_oval(cls, display, box, **kwargs):
return cls(display, display.create_oval(*box, **kwargs))
@attrs
class Eggs:
_display = attrib()
move_delay = attrib()
drop_interval = attrib()
_items = attrib(factory=list)
def create_egg(self):
self._items.append(
Sprite.new_oval(
self._display,
Box.from_position_and_size(
randrange(10, self._display.width - EGG_WIDTH - 10),
40,
EGG_WIDTH,
EGG_HEIGHT,
),
fill="yellow",
width=0,
)
)
def _apply_filter_action(self, action):
remaining_eggs = list()
for egg in self._items:
if action(egg):
remaining_eggs.append(egg)
else:
egg.delete()
deleted_egg_count = len(self._items) - len(remaining_eggs)
self._items = remaining_eggs
return deleted_egg_count
def move(self):
def action(egg):
egg.move(0, 10)
return egg.get_box().bottom <= self._display.height
return self._apply_filter_action(action)
def check_catch(self, basket):
basket_box = basket.get_box()
def action(egg):
egg_box = egg.get_box()
return not (
basket_box.left < egg_box.left
and basket_box.right > egg_box.right
and basket_box.bottom - egg_box.bottom < 40
)
return self._apply_filter_action(action)
class MainWindow(Tk):
def __init__(self):
Tk.__init__(self)
display_width, display_height = (
self.winfo_screenwidth(),
self.winfo_screenheight(),
)
self.attributes("-fullscreen", True)
self.geometry(f"{display_width}x{display_height}+0+0")
self.score = 0
self.life_count = 3
self.display = Display(self, display_width, display_height)
self.display.pack()
self.display.set_score(self.score)
self.display.set_life_count(self.life_count)
self.eggs = Eggs(self.display, EGG_MOVE_DELAY, EGG_DROP_INTERVAL)
display_box = self.display.get_box()
basket_box = Box.from_size(BASKET_WIDTH, BASKET_HEIGHT)
basket_box.center_x = display_box.center_x
basket_box.bottom = display_box.bottom - 20
self.basket = Sprite.new_arc(
self.display,
basket_box,
start=200,
extent=140,
style=ARC,
outline=BASKET_COLOR,
width=3,
)
self.create_egg_task_id = self.after(1000, self.create_egg)
self.move_eggs_task_id = self.after(1000, self.move_eggs)
self.display.bind("<Left>", self.move_basket_left)
self.display.bind("<Right>", self.move_basket_right)
self.display.focus_set()
def stop_all_tasks(self):
for task_id in [self.create_egg_task_id, self.move_eggs_task_id]:
self.after_cancel(task_id)
def create_egg(self):
self.eggs.create_egg()
self.create_egg_task_id = self.after(
self.eggs.drop_interval, self.create_egg
)
def check_catch(self):
caught_egg_count = self.eggs.check_catch(self.basket)
if caught_egg_count:
self.score += caught_egg_count
factor = DIFFICULTY_FACTOR ** self.score
self.eggs.move_delay = int(EGG_MOVE_DELAY * factor)
self.eggs.drop_interval = int(EGG_DROP_INTERVAL * factor)
self.display.set_score(self.score)
def move_eggs(self):
dropped_egg_count = self.eggs.move()
if dropped_egg_count:
self.life_count -= dropped_egg_count
self.display.set_life_count(self.life_count)
if self.life_count <= 0:
self.stop_all_tasks()
messagebox.showinfo("Game Over", f"Punkte: {self.score}")
self.quit()
self.check_catch()
self.move_eggs_task_id = self.after(
self.eggs.move_delay, self.move_eggs
)
def move_basket_left(self, _event):
if self.basket.get_box().left > 0:
self.basket.move(-20, 0)
self.check_catch()
def move_basket_right(self, _event):
if self.basket.get_box().right < self.display.width:
self.basket.move(20, 0)
self.check_catch()
def main():
window = MainWindow()
window.mainloop()
if __name__ == "__main__":
main()
“Java is a DSL to transform big Xml documents into long exception stack traces.”
— Scott Bellware
— Scott Bellware