Initial work, pong paddles move, lots of the groundwork for multiplayer or alternate displays is already done

This commit is contained in:
2013-12-14 22:54:21 -05:00
commit 26eb57c61d
9 changed files with 445 additions and 0 deletions

115
display.py Executable file
View File

@@ -0,0 +1,115 @@
from common import *
import event
import game
import registry
class Display(event.EventHandler, registry.Registerable):
# --- Static methods
@staticmethod
def CurrentDisplay():
return getattr(Display, '__currentDisplay__')
@staticmethod
def NewDisplay(displayType):
display = globals()["{}Display".format(displayType.title())]()
setattr(Display, '__currentDisplay__', display)
return display
@staticmethod
def StaticRefresh():
display = Display.CurrentDisplay()
display.refresh()
# --- Member methods
def __init__(self, *args, **kwargs):
registry.Registerable.__init__(self, *args, **kwargs)
event.EventHandler.__init__(self, *args, **kwargs)
self.__lock_actors__ = threading.RLock()
self.__lock_timer__ = threading.RLock()
self.__lock_drawing__ = threading.RLock()
self.__actors__ = {}
self.__setDrawTimer__()
def __setDrawTimer__(self):
self.__drawTimer__ = threading.Timer(FRAMERATE, Display.StaticRefresh)
self.__drawTimer__.start()
def cleanup(self):
self.__drawTimer__.cancel()
# ---
def checkInput(self):
raise Exception("lol implement me")
def refresh(self):
try:
with self.__lock_drawing__:
self.__screen__.clear()
for actor in self.__actors__.values():
self.drawActor(actor)
self.__setDrawTimer__()
except Exception, e:
game.Game.CurrentGame().addEvent(('endGame', traceback.format_exc()))
def addActor(self, actor):
logger = logging.getLogger()
with self.__lock_actors__:
if not actor.uuid in self.__actors__.keys():
logger.debug("Added actor {}".format(actor.uuid))
self.__actors__[actor.uuid] = actor
def delActor(self, actor):
with self.__lock_actors__:
try:
del(self.__actors__, actor.uuid)
except KeyError, e:
return
class CursesDisplay(Display):
def __init__(self, *args, **kwargs):
self.logger = logging.getLogger()
self.logger.info("CursesDisplay starting")
Display.__init__(self, *args, **kwargs)
self.__screen__ = curses.initscr()
self.__screen__.keypad(1)
try:
curses.curs_set(0)
except:
logger.warn("I couldn't make the cursor invisible - I'm sorry")
curses.noecho()
curses.cbreak()
def cleanup(self):
self.logger.info("CursesDisplay cleaning up")
curses.nocbreak()
self.__screen__.keypad(0)
curses.echo()
curses.endwin()
Display.cleanup(self)
def refresh(self):
Display.refresh(self)
self.__screen__.refresh()
def checkInput(self):
key = self.__screen__.getch()
if key == ord('q'):
raise event.EventBubble(('endGame',
'User terminated the game',
'/Game/uuid/*'))
elif key == ord('w'):
raise event.EventBubble(('moveUp', '', '/Player/cn/player1'))
elif key == ord('s'):
raise event.EventBubble(('moveDown', '', '/Player/cn/player1'))
elif key == curses.KEY_UP:
raise event.EventBubble(('moveUp', '', '/Player/cn/player2'))
elif key == curses.KEY_DOWN:
raise event.EventBubble(('moveDown', '', '/Player/cn/player2'))
def drawActor(self, actor):
# Curses displays have it easy; actors return us a function to call
# with a reference to ourselves, and they draw on us.
actor.frame(self)(self)