Initial work, pong paddles move, lots of the groundwork for multiplayer or alternate displays is already done
This commit is contained in:
115
display.py
Executable file
115
display.py
Executable 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)
|
||||
|
||||
Reference in New Issue
Block a user