Skip to content

Instantly share code, notes, and snippets.

@pkulev
Created September 20, 2014 13:23
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pkulev/eb88ed29eae0235d2aa6 to your computer and use it in GitHub Desktop.
Save pkulev/eb88ed29eae0235d2aa6 to your computer and use it in GitHub Desktop.
#!/usr/bin/env python
from __future__ import print_function
import curses
import functools
import sys
class Settings(object):
def __init__(self, **kwargs):
self.config = dict()
self.config.update(kwargs)
def __getattr__(self, name):
return self.config.get(name)
class Application(object):
def __init__(self, settings):
assert isinstance(settings, Settings)
self._settings = settings
self._handlers = list()
self._working = False
def registerHandler(self, handler):
self._handlers.append(handler)
def start(self):
self._working = True
while self._working:
for handler in self._handlers:
handler.handle()
def stop(self):
self._working = False
class O(object):
visible = True
x = 40
y = 12
image = 'O'
controllable = True
def __init__(self, world, x=None, y=None, image=None):
self._world = world
if x is None:
self.x = self._world.settings.x/2
else:
self.x = x
if y is None:
self.y = self._world.settings.y/2
else:
self.y = y
if image is not None:
self.image = image
def move_right(self):
"""
if self.x + 2 < self._world.settings.x:
self.visible = True
else:
self.visible = False
"""
self.x +=1
def move_left(self):
"""
if 0 < self.x - 1:
self.visible = True
else:
self.visible = False
"""
self.x -=1
def move_up(self):
"""
if 0 < self.y - 1:
self.visible = True
else:
self.visible = False
"""
self.y -=1
def move_down(self):
"""
if self.y + 2 < self._world.settings.y:
self.visible = True
else:
self.visible = False
"""
self.y +=1
class S(object):
visible = True
x = 40
y = 12
image = [[None, None, None, 'C'],
['X', 'Y', 'Z', 'A'],
[None, None, None, 'B']]
controllable = True
def __init__(self, world, x=None, y=None):
self._world = world
if x is None:
self.x = self._world.settings.x/2
if y is None:
self.y = self._world.settings.y/2
x, y = self.x, self.y
self.c = list()
for _x, l in enumerate(self.image):
for _y, image in enumerate(l):
if image is not None:
_o = O(world, x+_x, y+_y, image)
self.c.append(_o)
self._world.entities.append(_o)
def __getattr__(self, name):
def test():
for entity in self.c:
getattr(entity, name)()
return test
class World(object):
entities = []
def __init__(self, settings):
self._settings = settings
self.init()
self.entitiesClasses = [S]
S(self)
def init(self):
# INFO: nobody knows wtfisit
curses.initscr()
curses.curs_set(0)
self._screen = curses.newwin(self.settings.y, self.settings.x, 10, 10)
self._screen.nodelay(1)
curses.cbreak()
self._screen.border(0)
def deinit(self):
self._screen.nodelay(0)
curses.nocbreak()
curses.curs_set(1)
curses.endwin()
def getch(self):
return self.screen.getch()
@property
def settings(self):
return self._settings
@property
def screen(self):
return self._screen
class Key(object):
def __init__(self, key, map):
self.key = key
self.map = map
def __call__(self, func):
self.map[self.key] = func
@functools.wraps(func)
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
class KeyboardHandler(object):
MAP = dict()
K_ESCAPE = 27
K_D = ord('d')
K_A = ord('a')
K_W = ord('w')
K_S = ord('s')
@Key(K_ESCAPE, MAP)
def do_escape(self):
# because we doesn't have signals it's temporary here, sorry
self._world.deinit()
sys.exit(1)
@Key(K_D, MAP)
def do_right(self):
# because we doesn't have signals it's temporary here, sorry
for entity in self._world.entities:
if entity.controllable:
entity.move_right()
@Key(K_A, MAP)
def do_left(self):
# because we doesn't have signals it's temporary here, sorry
for entity in self._world.entities:
if entity.controllable:
entity.move_left()
@Key(K_W, MAP)
def do_up(self):
# because we doesn't have signals it's temporary here, sorry
for entity in self._world.entities:
if entity.controllable:
entity.move_up()
@Key(K_S, MAP)
def do_down(self):
# because we doesn't have signals it's temporary here, sorry
for entity in self._world.entities:
if entity.controllable:
entity.move_down()
def __init__(self, world):
self._world = world
def _handle(self, key):
h = self.MAP.get(key)
if h is not None:
h(self)
def handle(self):
self._handle(self._world.getch())
class ScreenHandler(object):
def __init__(self, world):
self._world = world
def handle(self):
self._world.screen.erase()
self._world.screen.border(0)
for entity in self._world.entities:
if entity.visible:
if isinstance(entity, S):
continue
if all([entity.x + 2 <= self._world.settings.x,
0 <= entity.x - 1,
0 <= entity.y - 1,
entity.y + 2 <= self._world.settings.y]):
self._world.screen.addch(entity.y, entity.x, entity.image)
self._world.screen.refresh()
def main():
settings = Settings(x=80, y=25)
world = World(settings)
keyboard = KeyboardHandler(world)
screen = ScreenHandler(world)
application = Application(settings)
application.registerHandler(keyboard)
application.registerHandler(screen)
application.start()
if __name__ == '__main__':
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment