Created
September 20, 2014 13:23
-
-
Save pkulev/eb88ed29eae0235d2aa6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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