Hallo Leute,
Ich möchte mir einen screen mit animierten Buchstaben basteln.
Es sollen einfach Buchstaben (Grafiken) im Bild hoch und runter laufen.
Folgendes Programm funktioniert aber nicht und ich finde den Grund nicht.
Wenn ich das über Pfeiltasten (mit bind) programmiere, läuft es, aber in einer Schleife hab ich nur noch einen weißen, eingefrorenen Bildschirm.
import time
from tkinter import *
from PIL import ImageTk, Image
main = Tk()
main.title("Test")
main.iconbitmap("prgpix/WindowIcon.ico")
main.geometry("1920x1200+0+0")
# main.wm_minsize(width=640, height=400) # wenn resizable = false, braucht man das hier ja nicht wirklich
main.resizable(width = False, height = False)
#main.configure(bg = "black")
hauptcanvas = Canvas(main, width = 1920, height = 1200, bd = 0, bg = "black", highlightthickness = 0)
hauptcanvas.place(x = 0, y = 0)
def startgedrueckt():
introscreen = False
introscreen = True
e1_pos = 200
c_pos = 250
k_pos = 300
e2_pos = 250
s_pos = 200
e1_pos_add = 1
c_pos_add = 1
k_pos_add = 1
e2_pos_add = 1
s_pos_add = 1
e_img = PhotoImage(file = "Stammtisch\Intro-E.png")
c_img = PhotoImage(file = "Stammtisch\Intro-C.png")
k_img = PhotoImage(file = "Stammtisch\Intro-K.png")
s_img = PhotoImage(file = "Stammtisch\Intro-S.png")
move_e1 = hauptcanvas.create_image(600, e1_pos, image=e_img, anchor="nw", tag="e1")
move_c = hauptcanvas.create_image(750, c_pos, image=c_img, anchor="nw", tag="c")
move_k = hauptcanvas.create_image(900, k_pos, image=k_img, anchor="nw", tag="k")
move_e2 = hauptcanvas.create_image(1050, e2_pos, image=e_img, anchor="nw", tag="e2")
move_s = hauptcanvas.create_image(1200, s_pos, image=s_img, anchor="nw", tag="s")
startbutton_img = ImageTk.PhotoImage(file="Stammtisch\STARTbutton.png")
startbutton = Button(hauptcanvas, borderwidth=0, bg="black", command=startgedrueckt)
startbutton.config(image=startbutton_img, activebackground="black")
startbutton.place(x=830, y=990)
def ani():
global e1_pos, c_pos, k_pos, e2_pos, s_pos, e1_pos_add, c_pos_add, k_pos_add, e2_pos_add, s_pos_add
e1_pos += e1_pos_add
c_pos += c_pos_add
k_pos += k_pos_add
e2_pos += e2_pos_add
s_pos += s_pos_add
print (e1_pos)
if e1_pos > 700:
e1_pos_add = -1
if c_pos > 700:
c_pos_add = -1
if k_pos > 700:
k_pos_add = -1
if e2_pos > 700:
e2_pos_add = -1
if s_pos > 700:
s_pos_add = -1
if e1_pos < 100:
e1_pos_add = 1
if c_pos < 100:
c_pos_add = 1
if k_pos < 100:
k_pos_add = 1
if e2_pos < 100:
e2_pos_add = 1
if s_pos < 100:
s_pos_add = 1
hauptcanvas.move(move_e1, 0, e1_pos_add)
hauptcanvas.move(move_c, 0, e1_pos_add)
hauptcanvas.move(move_k, 0, e1_pos_add)
hauptcanvas.move(move_e2, 0, e1_pos_add)
hauptcanvas.move(move_s, 0, e1_pos_add)
while introscreen:
ani()
#clock.tick(40)
time.sleep(0.1)
Problem mit while-Schleife
So funktionieren GUIs nicht; GUIs sind ereignisgesteuert, lang laufende Schleifen darf es nicht geben. Bei Dir löst man das mit `after`.
Daneben solltest Du keine *-Importe benutzen und kein `global`. Variablen. Variablennamen müssen aussagekräftig sein.
Statt jeweils fünf mal den selben Code für jeden Buchstaben würde man eine Buchstabenklasse definieren.
Daneben solltest Du keine *-Importe benutzen und kein `global`. Variablen. Variablennamen müssen aussagekräftig sein.
Statt jeweils fünf mal den selben Code für jeden Buchstaben würde man eine Buchstabenklasse definieren.
Code: Alles auswählen
import tkinter as tk
from PIL import ImageTk, Image
class Character:
def __init__(self, canvas, x_position, y_position, filename):
self.y_position = y_position
self.canvas = canvas
self.image = ImageTk.PhotoImage(file=filename)
self.canvas_id = canvas.create_image(x_position, e1_pos, image=self.image, anchor="nw")
self.direction = 1
def move(self):
self.canvas.move(self.canvas_id, 0, self.direction)
self.y_position += self.direction
if self.y_position > 700:
self.direction = -1
elif self.y_position < 100:
self.direction = 1
def animation(root, characters):
for character in characters:
character.move()
root.after(100, animation, root, characters)
def main():
root = tk.Tk()
root.title("Test")
root.iconbitmap("prgpix/WindowIcon.ico")
root.resizable(width=False, height=False)
canvas = tk.Canvas(root, width=1920, height=1200, bd=0, bg="black", highlightthickness=0)
canvas.pack()
buchstaben = [
Character(canvas, 600, 200, "Stammtisch/Intro-E.png"),
Character(canvas, 750, 250, "Stammtisch/Intro-C.png"),
Character(canvas, 900, 300, "Stammtisch/Intro-K.png"),
Character(canvas, 1050, 250, "Stammtisch/Intro-E.png"),
Character(canvas, 1200, 200, "Stammtisch/Intro-S.png"),
]
startbutton_img = ImageTk.PhotoImage(file="Stammtisch/STARTbutton.png")
startbutton = tk.Button(canvas, borderwidth=0, bg="black")
startbutton.config(image=startbutton_img, activebackground="black")
startbutton.place(x=830, y=990)
animation(root, characters)
root.mainloop()
if __name__ == "__main__":
main()
Hab es jetzt auch mal so probiert - das läuft auch (hab das so gemacht, weil ich wollte, daß die Buchstaben unterschiedlich "hüpfen"):
import time
from tkinter import *
from PIL import ImageTk, Image
main = Tk()
main.title("Test")
main.iconbitmap("prgpix/WindowIcon.ico")
main.geometry("1920x1200+0+0")
# main.wm_minsize(width=640, height=400) # wenn resizable = false, braucht man das hier ja nicht wirklich
main.resizable(width = False, height = False)
#main.configure(bg = "black")
hauptcanvas = Canvas(main, width = 1920, height = 1200, bd = 0, bg = "black", highlightthickness = 0)
hauptcanvas.place(x = 0, y = 0)
def startgedrueckt():
introscreen = False
introscreen = True
e1_pos = 200
c_pos = 250
k_pos = 300
e2_pos = 250
s_pos = 200
e1_pos_add = 1.1
c_pos_add = 0.9
k_pos_add = 1.3
e2_pos_add = 0.7
s_pos_add = 1.4
e_img = PhotoImage(file = "Stammtisch\Intro-E.png")
c_img = PhotoImage(file = "Stammtisch\Intro-C.png")
k_img = PhotoImage(file = "Stammtisch\Intro-K.png")
s_img = PhotoImage(file = "Stammtisch\Intro-S.png")
move_e1 = hauptcanvas.create_image(600, e1_pos, image=e_img, anchor="nw")
move_c = hauptcanvas.create_image(750, c_pos, image=c_img, anchor="nw")
move_k = hauptcanvas.create_image(900, k_pos, image=k_img, anchor="nw")
move_e2 = hauptcanvas.create_image(1050, e2_pos, image=e_img, anchor="nw")
move_s = hauptcanvas.create_image(1200, s_pos, image=s_img, anchor="nw")
startbutton_img = ImageTk.PhotoImage(file="Stammtisch\STARTbutton.png")
startbutton = Button(hauptcanvas, borderwidth=0, bg="black", command=startgedrueckt)
startbutton.config(image=startbutton_img, activebackground="black")
startbutton.place(x=830, y=990)
def ani():
global e1_pos, c_pos, k_pos, e2_pos, s_pos, e1_pos_add, c_pos_add, k_pos_add, e2_pos_add, s_pos_add
e1_pos += e1_pos_add
c_pos += c_pos_add
k_pos += k_pos_add
e2_pos += e2_pos_add
s_pos += s_pos_add
print (e1_pos)
if e1_pos > 500:
e1_pos_add = -1.1
if c_pos > 500:
c_pos_add = -0.9
if k_pos > 500:
k_pos_add = -1.3
if e2_pos > 500:
e2_pos_add = -0.7
if s_pos > 500:
s_pos_add = -1.4
if e1_pos < 100:
e1_pos_add = 1.1
if c_pos < 100:
c_pos_add = 0.9
if k_pos < 100:
k_pos_add = 1.3
if e2_pos < 100:
e2_pos_add = 0.7
if s_pos < 100:
s_pos_add = 1.4
hauptcanvas.move(move_e1, 0, e1_pos_add)
hauptcanvas.move(move_c, 0, c_pos_add)
hauptcanvas.move(move_k, 0, k_pos_add)
hauptcanvas.move(move_e2, 0, e2_pos_add)
hauptcanvas.move(move_s, 0, s_pos_add)
main.after(1, ani)
import time
from tkinter import *
from PIL import ImageTk, Image
main = Tk()
main.title("Test")
main.iconbitmap("prgpix/WindowIcon.ico")
main.geometry("1920x1200+0+0")
# main.wm_minsize(width=640, height=400) # wenn resizable = false, braucht man das hier ja nicht wirklich
main.resizable(width = False, height = False)
#main.configure(bg = "black")
hauptcanvas = Canvas(main, width = 1920, height = 1200, bd = 0, bg = "black", highlightthickness = 0)
hauptcanvas.place(x = 0, y = 0)
def startgedrueckt():
introscreen = False
introscreen = True
e1_pos = 200
c_pos = 250
k_pos = 300
e2_pos = 250
s_pos = 200
e1_pos_add = 1.1
c_pos_add = 0.9
k_pos_add = 1.3
e2_pos_add = 0.7
s_pos_add = 1.4
e_img = PhotoImage(file = "Stammtisch\Intro-E.png")
c_img = PhotoImage(file = "Stammtisch\Intro-C.png")
k_img = PhotoImage(file = "Stammtisch\Intro-K.png")
s_img = PhotoImage(file = "Stammtisch\Intro-S.png")
move_e1 = hauptcanvas.create_image(600, e1_pos, image=e_img, anchor="nw")
move_c = hauptcanvas.create_image(750, c_pos, image=c_img, anchor="nw")
move_k = hauptcanvas.create_image(900, k_pos, image=k_img, anchor="nw")
move_e2 = hauptcanvas.create_image(1050, e2_pos, image=e_img, anchor="nw")
move_s = hauptcanvas.create_image(1200, s_pos, image=s_img, anchor="nw")
startbutton_img = ImageTk.PhotoImage(file="Stammtisch\STARTbutton.png")
startbutton = Button(hauptcanvas, borderwidth=0, bg="black", command=startgedrueckt)
startbutton.config(image=startbutton_img, activebackground="black")
startbutton.place(x=830, y=990)
def ani():
global e1_pos, c_pos, k_pos, e2_pos, s_pos, e1_pos_add, c_pos_add, k_pos_add, e2_pos_add, s_pos_add
e1_pos += e1_pos_add
c_pos += c_pos_add
k_pos += k_pos_add
e2_pos += e2_pos_add
s_pos += s_pos_add
print (e1_pos)
if e1_pos > 500:
e1_pos_add = -1.1
if c_pos > 500:
c_pos_add = -0.9
if k_pos > 500:
k_pos_add = -1.3
if e2_pos > 500:
e2_pos_add = -0.7
if s_pos > 500:
s_pos_add = -1.4
if e1_pos < 100:
e1_pos_add = 1.1
if c_pos < 100:
c_pos_add = 0.9
if k_pos < 100:
k_pos_add = 1.3
if e2_pos < 100:
e2_pos_add = 0.7
if s_pos < 100:
s_pos_add = 1.4
hauptcanvas.move(move_e1, 0, e1_pos_add)
hauptcanvas.move(move_c, 0, c_pos_add)
hauptcanvas.move(move_k, 0, k_pos_add)
hauptcanvas.move(move_e2, 0, e2_pos_add)
hauptcanvas.move(move_s, 0, s_pos_add)
main.after(1, ani)
Weil die verschleiern, woher ein Name kommt. Und gerade bei tkinter sind das mal so eben 200, die plötzlich in deinem Namensraum auftauchen. Inklusive so Dinge wie „END“, was man vielleicht auch mal anders definieren will.
ah ja - das stimmt natürlich.
Hab jetzt die Werte nochmal bisschen verändert und es sieht ganz lustig aus. Ich bin ja nicht der mega-Programmierer, aber Python macht irgendwie spaß.
In meinem Alter (ü50) werd' ich wohl keine großen Sachen mehr schaffen, aber es hält zumindest geistig etwas fit denke.
Vielen Dank !
Hab jetzt die Werte nochmal bisschen verändert und es sieht ganz lustig aus. Ich bin ja nicht der mega-Programmierer, aber Python macht irgendwie spaß.
In meinem Alter (ü50) werd' ich wohl keine großen Sachen mehr schaffen, aber es hält zumindest geistig etwas fit denke.
Vielen Dank !
Jetzt aber zum Problem mit der While-Schleife:
wenn man beispielsweise ein Game schreiben will, was ein Intro, einen Hauptteil und eine Ende hat, man aber keine While-Schleife zum Aufrufen der einzelnen Teile nutzen darf, wie kann man das dann realisieren ?
Mein Plan war ja in etwa so:
def intro():
code
def game():
code
def ende():
code
run = True
i = True
g = False
e = False
while run:
if i:
intro()
if g:
game()
if e:
ende():
aber das geht ja nicht wegen dem while.
wie also kann man das intro laufen lassen und die anderen sachen noch nicht und wie dann das intro beenden und das game starten ?
wenn man beispielsweise ein Game schreiben will, was ein Intro, einen Hauptteil und eine Ende hat, man aber keine While-Schleife zum Aufrufen der einzelnen Teile nutzen darf, wie kann man das dann realisieren ?
Mein Plan war ja in etwa so:
def intro():
code
def game():
code
def ende():
code
run = True
i = True
g = False
e = False
while run:
if i:
intro()
if g:
game()
if e:
ende():
aber das geht ja nicht wegen dem while.
wie also kann man das intro laufen lassen und die anderen sachen noch nicht und wie dann das intro beenden und das game starten ?
Genau, so geht das nicht. Spiele laufen ja meist nur in einem Fenster ab. Das heißt, für Intro, Game und Ende hast Du jeweils einen eigenen Frame, den Du einfach im Hauptfenster austauschen kannst. Also Du startest mit Intro, beim Drücken eines Knopfes wird der Intro-Frame aus dem Hauptfenster gelöscht und statt dessen der Game-Frame erzeugt und dargestellt.
Am besten schreibst Du für jeden der drei Teile jeweils eine Klasse, die von Frame erbt. Dann kannst Du das von der Hauptfensterklasse aus einfach steuern.
Am besten schreibst Du für jeden der drei Teile jeweils eine Klasse, die von Frame erbt. Dann kannst Du das von der Hauptfensterklasse aus einfach steuern.
Code: Alles auswählen
import tkinter as tk
class Intro(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
tk.Label(self, text="Intro").pack()
tk.Button(self, text="Weiter", command=parent.start_game).pack()
class Game(tk.Frame):
def __init__(self, parent):
tk.Frame.__init__(self, parent)
self.parent = parent
tk.Label(self, text="Game").pack()
tk.Button(self, text="Ende", command=parent.end_game).pack()
class MainWindow(tk.Tk):
def __init__(self):
tk.Tk.__init__(self)
self.current_frame = Intro(self)
self.current_frame.pack()
def start_game(self):
self.current_frame.pack_forget()
self.current_frame = Game(self)
self.current_frame.pack()
def end_game(self):
self.destroy()
def main()
root = MainWindow()
root.mainloop()
if __name__ == "__main__":
main()
Man teilt ein Programm so in Module auf, dass jedes Modul eine fachliche Einheit bildet.
Die Teile eines Programms packst Du in ein Package. Module schreibt man, wie Funktionen und Variablen auch, komplett klein.
Die Teile eines Programms packst Du in ein Package. Module schreibt man, wie Funktionen und Variablen auch, komplett klein.
Code: Alles auswählen
from das_tolle_spiel.intro import Intro