Ohne deepcopy oder alternativ die Hintergrundgrafik in jeder Runde neu zu öffnen, wurden nur die neuen Positionen zu den bereits vorhandenen hinzugefügt, also bei 100 Durchläufen 99-mal zusätzlich eingefügt, was höchstens interessant aussehen könnte, wenn man eine Umlaufbahn, Bremsspur oder ähnliches gebrauchen könnte. Bin mir nicht sicher, ob deepcopy sehr viel sparsamer ist als neu öffnen, mit größeren Grafiken habe ich es noch nicht probiert?
Als nächstes würde die Frage stehen, wie sich aus den Einzelbildern am günstigsten ein Video erstellen lässt.
Code: Alles auswählen
from tkinter import Tk, Frame, Label, Button, Checkbutton, Radiobutton, IntVar
from PIL import Image, ImageTk
from copy import deepcopy
class SimpleAnimation:
"""Eine Klasse für simple 2D Animationen mit Image-Objekten"""
def __init__(self, im_bg = None, im_01 = None, im_02 = None):
self.fenster = Tk()
self.fenster.title("Simple Animationen")
self.fenster.wm_iconbitmap("logo.ico")
self.fenster.config(bg = "#808080")
# Aufteilung in oberen und unteren Frame mit Buttons usw.
self.frame_o = Frame(self.fenster, bg = "#808080", padx = 10)
self.frame_u = Frame(self.fenster, bg = "#6f6352", padx = 10)
self.fenbild = Label(self.frame_o, bd = 0)
self.control = Label(
self.frame_u, bd = 4, bg = "#000", fg = "#40ff40",
width = 20, relief = "sunken", pady = 4)
self.speichr = IntVar()
self.checker = Checkbutton(
self.frame_u, text = "Mit Speicherung?",
bg = "#6f6352", fg = "#e2aa00",
variable = self.speichr,
command = self.setze_auswahl)
self.laufmal = IntVar()
self.radio01 = Radiobutton(
self.frame_u, text = "50", bg = "#6f6352",
fg = "#e2aa00", value = 50,
variable = self.laufmal,
command = self.setze_auswahl)
self.radio02 = Radiobutton(
self.frame_u, text = "100", bg = "#6f6352",
fg = "#e2aa00", value = 100,
variable = self.laufmal,
command = self.setze_auswahl)
self.radio03 = Radiobutton(
self.frame_u, text = "150", bg = "#6f6352",
fg = "#e2aa00", value = 150,
variable = self.laufmal,
command = self.setze_auswahl)
self.radio04 = Radiobutton(
self.frame_u, text = "200", bg = "#6f6352",
fg = "#e2aa00", value = 200,
variable = self.laufmal,
command = self.setze_auswahl)
self.starter = Button(
self.frame_u, text = "Start",
font = ("cambria", 10, "bold"), padx = 12,
command = self.bewege_objekte)
self.frame_o.pack(side = "top")
self.fenbild.pack(padx = 20, pady = 20)
self.frame_u.pack(side = "bottom", fill = "x")
self.control.pack(side = "left", padx = 20, pady = 4)
self.checker.pack(side = "left", padx = 2, pady = 4)
self.radio01.pack(side = "left")
self.radio02.pack(side = "left")
self.radio03.pack(side = "left")
self.radio04.pack(side = "left")
self.radio01.select()
self.starter.pack(side = "left", padx = 2, pady = 4)
# Images vor und nach dem Öffnen
self.iopen_bg = im_bg
self.iopen_01 = im_01
self.iopen_02 = im_02
self.image_bg = None
self.image_01 = None
self.image_02 = None
self.label_bg = None
self.img_temp = None
# Positionen bei Start und bei Veränderungen
self.posx_01 = 0
self.posy_01 = 0
self.posx_02 = 0
self.posy_02 = 0
self.startwt = 0
self.endwert = 0
self.speichg = 0
self.bildnum = 0
def main(self, px01 = None, py01 = None, px02 = None, py02 = None):
if self.iopen_bg != None:
self.image_bg = Image.open(self.iopen_bg)
if self.iopen_01 != None:
self.image_01 = Image.open(self.iopen_01).convert("RGBA")
if self.iopen_02 != None:
self.image_02 = Image.open(self.iopen_02).convert("RGBA")
if px01 != None:
self.posx_01 = px01
if py01 != None:
self.posy_01 = py01
if px02 != None:
self.posx_02 = px02
if py02 != None:
self.posy_02 = py02
if self.iopen_bg != None:
self.positioniere_objekte()
def positioniere_objekte(self):
self.img_temp = deepcopy(self.image_bg)
# Die bewegten Objekte in jeder Runde neu ausrichten.
if self.iopen_01 != None:
self.img_temp.paste(
self.image_01, (self.posx_01,self.posy_01), self.image_01)
if self.iopen_02 != None:
self.img_temp.paste(
self.image_02, (self.posx_02,self.posy_02), self.image_02)
# Speichern aller Einzelbilder einer Animation
if self.speichg == 1:
self.bildnum += 1
ablage = "temps/temp-{0:03d}.png".format(self.bildnum)
self.img_temp.save(ablage, "PNG")
if self.iopen_bg != None:
self.label_bg = ImageTk.PhotoImage(self.img_temp)
self.fenbild.config(image = self.label_bg)
def bewege_objekte(self):
if self.startwt < self.endwert:
self.fenster.after(200, self.bewege_objekte)
self.startwt += 1
# Berechnung der Bahnen
self.posy_01 += 1
self.posy_02 += 1
if self.startwt < 110:
self.posx_01 += 1
self.posx_02 -= 1
self.positioniere_objekte()
# Als Anzeige der laufenden Werte
ausg = "{0:d} - {1:d} | ".format(self.posx_01,self.posy_01)
ausg += "{0:d} - {1:d} | ".format(self.posx_02,self.posy_02)
ausg += "E {0:d}".format(self.endwert)
self.control["text"] = ausg
def setze_auswahl(self):
self.endwert = self.laufmal.get()
self.speichg = self.speichr.get()
objekt00 = "images/background.jpg"
objekt01 = "images/kugel-01.png"
objekt02 = "images/kugel-02.png"
if __name__ == "__main__":
instanz = SimpleAnimation(objekt00, objekt01, objekt02)
instanz.main(10,10,308,10)
instanz.fenster.mainloop()