3
« on: July 20, 2010, 05:00:00 pm »
And what would you think of including a base class for event-based applications?
# inspired by ircbot
import sfml
STR_EVENTS = {sfml.CLOSED: "closed", sfml.RESIZED: "resized",
sfml.LOST_FOCUS: "lost_focus", sfml.GAINED_FOCUS: "gained_focus",
sfml.TEXT_ENTERED: "text_entered",
sfml.KEY_PRESSED: "key_pressed", sfml.KEY_RELEASED: "key_released",
#...
}
class StopMainLoop(Exception): pass
class EventManager:
def __init__(self, window):
"""Initializes self.window object."""
self.window = window
def process_queue(self):
"""Processes events in the queue calling self.on_X(event) where X is the event type."""
for event in self.window.iterevents():
if hasattr(self, "on_" + STR_EVENTS[event.type]):
handler = getattr(self, "on_" + STR_EVENTS[event.type])
handler(event)
def prepare_frame(self):
"""Use this method to do some stuff before drawing."""
pass
def draw(self):
"""Use this method to draw the current frame on the self.window object."""
pass
def main_loop(self):
"""Calls self.prepare_frame(), self.draw() and self.process_queue() in a loop."""
try:
while True:
self.prepare_frame()
self.window.clear()
self.draw()
self.window.display()
self.process_queue()
except StopMainLoop:
pass
def stop(self):
"""Call this method to stop the main loop."""
if self.window.is_opened():
self.window.close()
raise StopMainLoop
Users would not be forced to use it but it could help. An sample code would be:
import sfml
MOVE_PIXELS = {sfml.DOWN: (0,1), sfml.LEFT: (-1,0), sfml.UP: (0,1), sfml.RIGHT: (1,0)}
class MyApp(sfml.EventManager):
def __init__(self, background, player):
sfml.EventManager.__init__(self, sfml.RenderWindow())
background_img = sfml.Image(background)
vm = sfml.VideoMode(background_img.width(), background_img.height(), 32)
self.window.create(vm, "MyApp")
self.background = sfml.Sprite(background_img)
self.player = sfml.Sprite(sfml.Image(background))
def draw(self):
self.window.draw(self.background)
self.window.draw(self.player)
def on_closed(self, _):
self.stop()
def on_key_pressed(self, event):
if event.key.code == sfml.ESCAPE:
self.stop()
elif event.key.code in MOVE_PIXELS:
self.player.move(*MOVE_PIXELS[event.key.code])
if __name__ == "__main__":
MyApp("background.png", "player.png").main_loop()