Problem "Flow in Games" Umsetzung mit Tkinter
Verfasst: Donnerstag 15. März 2007, 21:59
Hallo,
ich habe mal versucht, die Performance von Tkinter/Canvas und damit seine Eignung für den Flow-in-Games Klon zu testen. Ich habe folgenden Ansatz geschrieben:
Wenn ich den Code ausführe, stürzt Python meistens ab. Wenn man doch alles sichtbare Plankton gefressen hat, bleiben immernoch zwei im Stack. Habt ihr dasselbe Problem und wenn ja, könnt ihr euch vorstellen, woran das liegt?
Vielen Dank für eure Gedanken dazu,
Michael
ich habe mal versucht, die Performance von Tkinter/Canvas und damit seine Eignung für den Flow-in-Games Klon zu testen. Ich habe folgenden Ansatz geschrieben:
Code: Alles auswählen
from Tkinter import * ## ich hasse den Sternchenimport ja auch, aber...
from random import randint
from thread import start_new_thread as snThread
import time
class ME:
def __init__(self, wCanvas, sBBox):
self.wCanvas = wCanvas
self.iItem = wCanvas.create_oval(sBBox)
def get_bbox(self):
return self.wCanvas.bbox(self.iItem)
def get_center(self):
x1, y1, x2, y2 = self.get_bbox()
return ((x1+x2)/2, (y1+y2)/2)
def next_frame(self):
iMoX, iMoY = self.wCanvas.Mouse.x, self.wCanvas.Mouse.y
iMeX, iMeY = self.get_center()
dX = iMoX - iMeX
dY = iMoY - iMeY
self.wCanvas.move(self.iItem, dX, dY)
x1, y1, x2, y2 = self.get_bbox()
lFoundItems = self.wCanvas.find_overlapping(x1, y1, x2, y2)
for iFoundItem in lFoundItems:
if iFoundItem != 1:
self.wCanvas.remove_plankton(iFoundItem)
self.wCanvas.delete(iFoundItem)
class MOUSE:
def __init__(self, wCanvas):
self.isbuttonpressed = False
self.isinrange = False
self.x = 0
self.y = 0
wCanvas.bind("<Enter>", self.event_enter, "+")
wCanvas.bind("<Leave>", self.event_leave, "+")
wCanvas.bind("<1>", self.event_button_press_1, "+")
wCanvas.bind("<ButtonRelease-1>", self.event_button_release_1, "+")
wCanvas.bind("<Motion>", self.event_motion, "+")
def event_enter(self, Event): self.isinrange=True
def event_leave(self, Event): self.isinrange=False
def event_button_press_1(self, Event): self.isbuttonpressed=True
def event_button_release_1(self, Event): self.isbuttonpressed=False
def event_motion(self, Event): self.x, self.y = Event.x, Event.y
class PLANKTON:
def __init__(self, wCanvas, tPos=(-1, -1), iSize=2):
self.wCanvas = wCanvas
if tPos == (-1, -1):
tPos = (randint(50, 250), randint(50, 250))
x, y = tPos
self.iItem = wCanvas.create_oval("%i %i %i %i"%(x-iSize, y-iSize, x+iSize, y+iSize))
def next_frame(self):
self.wCanvas.move(self.iItem, randint(-2, 2), randint(-2, 2))
class My_Canvas(Canvas):
def __init__(self, wMaster):
Canvas.__init__(self, wMaster, width=400, height=300, bg="#7bf")
self.grid()
self.dPlankton = {}
self.Me = ME(self, "10 10 20 20") ## Spielerobjekt anlegen
self.Mouse = MOUSE(self) ## Infos ueber Maus auf dem Canvas
def remove_plankton(self, iItem):
if iItem in self.dPlankton:
self.master.unregister(self.dPlankton[iItem])
del self.dPlankton[iItem]
class Hour_Glass(Tk):
def __init__(self, iFPS):
Tk.__init__(self)
self.iDelay = 1000 / iFPS
self.isrunning = False
self.lObjects = []
self.fLast = time.clock()
def start(self):
self.isrunning = True
snThread(self.loop_starter, ())
def stop(self):
self.isrunning = False
def register(self, Object):
if not Object in self.lObjects:
self.lObjects.append(Object)
def unregister(self, Object):
if Object in self.lObjects:
self.lObjects.remove(Object)
print "Restliches Plankton:", len(self.lObjects)-1, self.lObjects
if len(self.lObjects)==0: raise SystemExit("alles Plankton gefressen")
def loop_starter(self):
while self.isrunning:
self.next_loop()
def next_loop(self):
fStartTime = time.clock() ## starte Stoppuhr
for Object in self.lObjects:
try:
Object.next_frame()
except Exception, sMessage: ## wenn Fehler auftritt, entferne das Objekt
if isinstance(Object, PLANKTON):
self.unregister(Object)
else:
print "Objekt", Object,"entfernt:", sMessage
iDauer = int((time.clock() - fStartTime) * 1000) ## Dauer der Verarbeitung ausrechnen in ms
iRest = max(self.iDelay - iDauer, 0) ## Restdauer des Frames in ms
time.sleep(0.001*iRest)
wRoot = Hour_Glass(25)
wCanvas = My_Canvas(wRoot)
wRoot.register(wCanvas.Me) ## Registriere Spieler in Update-Liste
for i in xrange(50):
Plankton = PLANKTON(wCanvas)
wCanvas.dPlankton[i] = Plankton
wRoot.register(Plankton)
wRoot.start()
wRoot.mainloop()
Vielen Dank für eure Gedanken dazu,
Michael