Also entweder Du setzt ein sleep(0) in Deine pollschleife rein, auch wenn das keiner wahrhaben will, oder Du nimmst das. Das bezieht sich aber auf Deinen Eingangspost und ich habe auch das seitwärts korrigiert. Allerdings einen anderen Thread hast Du dann nicht mehr, obwohl die Locks noch drin sind:Üpsilon hat geschrieben:Leute, so hatte ich das Pythonforum aber nicht in Erinnerung, dass hier Threads für schwer verständliche Diskussionen über Technikalitäten gehijacket werden. Mögt ihr vielleicht den ganzen Kreppes abtrennen und auf meine Frage viewtopic.php?f=18&t=40957#p312752 eingehen?
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
gedrueckt = self.on_gedrueckt()
self.ball[0] += gedrueckt*SEITWAERTS_GESCHWINDIGKEIT
if self.ball[0] < 0 or self.ball[0] > SPIELFELD_GROESSE:
self.ball[0] -= 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()
Also, mit IO Operationen ist es so, wenn Du etwa ein input einfügst, dann wartet der Thread nicht etwa, bis Du Deine Eingabe gemacht hast, sondern das Betriebssystem schaltet dann sofort auf einen anderen Thread um. Erst Nach Drücken von Enter kommt dann der Thread wieder dran. Bei Print und anderen IO Operationen ist es ähnlich. Das Betriebssystem schaltet richtig um und berücksichtigt auch den GUI Thread. Python mit Endlosschleife tut das aber nicht.
Python schaltet nach einer Maximalzeit dann den Thread um aber nur, wenn es in einem anderen Thread auch auf Python Ebene etwas zu tun gibt. Und das ist dann im GUI Thread aber nicht der Fall.