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