Natürlich sind die Locks nötig. Aber sie sind falsch implementiert. Diese Implementierung ist sinnlos.Sirius3 hat geschrieben:@Alfons Mittelmeyer: jetzt hast Du den endgültigen Beweis geliefert, dass Du von Parallel-Programmierung keine Ahnung hast. Locks sind immer dann nötig, wenn mehrere Prozesse/Threads (oder wie Du es auch immer nennen magst; ist im wesentlichen das selbe), auf das selbe Objekt zugreifen, hier `self.gedrueckt`.
Wenn Du etwas von Locks verstehen würdest, wüßtest Du dass man das so implementieren muss:
Code: Alles auswählen
#!/usr/bin/env python3
from canvas_screen import Screen
from random import randint, choice
from time import time
from threading import Lock, Thread
from time import sleep
SPIELFELD_GROESSE = 500
BALKEN_AUF_EINMAL = 5
BALKEN_BREITE = 100
BALL_RADIUS = 20
SCROLL_GESCHWINDIGKEIT = 2 # Pixel pro Schritt
SEITWAERTS_GESCHWINDIGKEIT = 10
FPS = 50
class Rapid_Roll:
def __init__(self):
# linke Ecke der Balken als Koordinatentupel
self.balken = [(randint(0, SPIELFELD_GROESSE-BALKEN_BREITE),
SPIELFELD_GROESSE/BALKEN_AUF_EINMAL*i)
for i in range(1,BALKEN_AUF_EINMAL+1)]
# Mittelpunkt vom Ball
self.ball = choice(self.balken)
self.ball = [self.ball[0]+BALKEN_BREITE/2, self.ball[1]-BALL_RADIUS]
self.gedrueckt = 0 # -1 für links, +1 für rechts
self.gedrueckt_lock = Lock()
self.spiel_laeuft = True
self.screen = Screen(SPIELFELD_GROESSE, SPIELFELD_GROESSE)
self.screen.window.bind('<Button-1>', lambda event: self.on_gedrueckt(-1))
self.screen.window.bind('<Button-3>', lambda event: self.on_gedrueckt(1))
self.screen.window.bind('<ButtonRelease-1>', lambda event: self.on_gedrueckt(0))
self.screen.window.bind('<ButtonRelease-3>', lambda event: self.on_gedrueckt(0))
def on_gedrueckt(self,value=None):
self.gedrueckt_lock.acquire()
if value != None:
self.gedrueckt = value
return_value = self.gedrueckt
self.gedrueckt_lock.release()
return return_value
def schritt(self):
# Ball seitwärts
self.ball[0] += self.on_gedrueckt()*SEITWAERTS_GESCHWINDIGKEIT
if self.ball[0] < 0 or self.ball[0] > SPIELFELD_GROESSE:
self.ball[0] -= self.on_gedrueckt()*SEITWAERTS_GESCHWINDIGKEIT
# Herausfinden, ob der Ball auf einem Balken liegt
liegt_auf = any(b[0] <= self.ball[0] <= b[0]+BALKEN_BREITE and b[1]-BALL_RADIUS <= self.ball[1] <= b[1] for b in self.balken)
# Ball hochziehen oder fallen lassen
if liegt_auf:
self.ball[1] -= SCROLL_GESCHWINDIGKEIT
else:
self.ball[1] += 2*SCROLL_GESCHWINDIGKEIT
# Balken scrollen
self.balken = [(x, y-SCROLL_GESCHWINDIGKEIT) for (x,y) in self.balken if y>SCROLL_GESCHWINDIGKEIT]
while len(self.balken) <= BALKEN_AUF_EINMAL: # wenn ein Balken oben rausgerutscht ist
self.balken.append((randint(0, SPIELFELD_GROESSE-BALKEN_BREITE),
self.balken[-1][1]+SPIELFELD_GROESSE/BALKEN_AUF_EINMAL))
# prüfen ob der Ball noch im Feld ist
if self.ball[1] < 0 or self.ball[1] > SPIELFELD_GROESSE:
self.spiel_laeuft = False
def ausgabe(self):
for i, b in enumerate(self.balken):
self.screen.input.put({'type':'line', 'name':i, 'bbox':(b[0], b[1], b[0]+BALKEN_BREITE, b[1])}),
self.screen.input.put({'type':'circle', 'name':'ball', 'M':self.ball, 'r':BALL_RADIUS})
'''
def hauptschleife(self):
zeit = time()
while self.spiel_laeuft:
while time()-zeit < 1/FPS:
sleep(0)
#pass
zeit += 1/FPS
self.schritt()
self.ausgabe()
'''
def hauptschleife(self):
if self.spiel_laeuft:
self.screen.window.after(int(1000/FPS),self.hauptschleife)
self.schritt()
self.ausgabe()
rr = Rapid_Roll()
##Thread(target=rr.hauptschleife).start()
rr.hauptschleife()
rr.screen.mainloop()