git.fiddlerwoaroof.com
Raw Blame History
import libtcodpy as tc
import numpy as np

class Player(object):
	@property
	def pos(self):
		return self.x, self.y

	def __init__(self, x,y, map):
		self.x = x
		self.y = y
		self.char = ord('@')
		self.color = tc.Color(255,255,255)
		self.map = map

	def draw(self):
		self.map.add(self)

	def move(self, dx, dy):
		print self.pos,
		dx, dy = self.map.move(self, dx,dy)
		self.x += dx
		self.y += dy
		print self.pos

class ArrowHandler(object):
	def __init__(self, player, eh):
		self.player = player
		eh.register(tc.KEY_LEFT,self.left)
		eh.register(tc.KEY_RIGHT,self.right)
		eh.register(tc.KEY_UP,self.up)
		eh.register(tc.KEY_DOWN,self.down)
	def left(self):
		print 'left'
		self.player.move(-1, 0)
	def right(self):
		print 'right'
		self.player.move(1, 0)
	def up(self):
		print 'up'
		self.player.move(0, -1)
	def down(self):
		print 'down'
		self.player.move(0, 1)

class Console(object):
	# TBI: must have a self.con member with the console to be drawn on
	pass

class Screen(object):
	def __init__(self, w, h):
		self.width = w
		self.height = h
		self.con = 0
	def init(self, title, fullscreen=False):
		tc.console_init_root(self.width, self.height, title, fullscreen, 2)
		return self

def squeeze(val, low, high):
	return min(max(val, low), high)

class Map(object):
	def __init__(self, w, h):
		self.width = w
		self.height = h
		self.map = np.random.random_integers(ord('a'), ord('z'), (w,h) )
		self.map[3,5] = ord('*')
		self.map[::10, ::10] = ord('#')
		self.fgcolors = np.random.random_integers(100,255, (w,h,3) )
		self.fgcolors[::10,::10] = (0,0,0)
		self.bgcolors = np.random.random_integers(0,100, (w,h,3) )
		self.bgcolors[::10,::10] = (255,255,255)
		self.overlays = {} # (x,y): { set( object, ... ) }

	def add(self, object):
		self.overlays.setdefault(object.pos,[]).append(object)

	def move(self, object, dx,dy):
		print self.overlays,
		self.overlays[object.pos].remove(object)
		ox,oy = object.pos
		x = squeeze(ox+dx, 0, self.width)
		y = squeeze(oy+dy, 0, self.height)
		self.overlays.setdefault((x,y), []).append(object)
		self.update_overlay(ox,oy)
		return x-ox, y-oy

	def update_overlay(self, x=None, y=None):
		if x is None or y is None: pass
		else:
			if (x,y) in self.overlays and self.overlays[x,y] == []:
				self.overlays.pop((x,y))

	def get_rgb(self, fg=True,slices=(slice(0),slice(0))):
		if fg:
			result = np.rollaxis(self.fgcolors[slices], 2)
		else:
			result = np.rollaxis(self.bgcolors[slices], 2)
		return [x.transpose() for x in result]

	def draw(self, con, tl=(0,0)):
		br = tl[0]+con.width, tl[1]+con.height
		slices = slice(tl[0], tl[0]+con.width), slice(tl[1], tl[1]+con.height)
		tc.console_fill_foreground(con.con, *self.get_rgb(slices=slices))
		tc.console_fill_background(con.con, *self.get_rgb(False,slices=slices))

		chars = np.copy(self.map[slices])
		for x,y in self.overlays:
			screen_x = x-tl[0]
			screen_y = y-tl[1]
			if 0 <= screen_x < con.width and 0 <= screen_y < con.height:
				obj = self.overlays[x,y][-1]
				chars[screen_x,screen_y] = obj.char
				tc.console_set_char_foreground(con.con, screen_x,screen_y, tc.black)
				tc.console_set_char_background(con.con, screen_x,screen_y, tc.white)
		tc.console_fill_char(con.con, chars.transpose())

class EventHandler(object):
	def __init__(self):
		self.key = tc.Key()
		self.mouse = tc.Mouse()
		self.cbs = {}

	def register(self, event, cb):
		self.cbs.setdefault(event,[]).append(cb)

	def tick(self):
		tc.sys_check_for_event(tc.EVENT_KEY_PRESS|tc.EVENT_MOUSE|tc.KEY_PRESSED,
			self.key, self.mouse
		)

		char = chr(self.key.c)
		if char != '\x00' and char in self.cbs:
			for cb in self.cbs[char]:
				cb()

		elif self.key.vk in self.cbs:
			for cb in self.cbs[self.key.vk]:
				cb()



class Application(object):
	def __init__(self):
		self.screen = Screen(200,125)
		self.map = Map(200,125)
		self.player = Player(4,5, self.map)
		self.events = EventHandler()
		ArrowHandler(self.player, self.events)

		tc.sys_set_fps(60)

	def init(self):
		self.screen.init("test")
		self.player.draw()

	def run(self):
		while not tc.console_is_window_closed():
			self.events.tick()
			self.map.draw(self.screen)
			tc.console_print(0, 0,1, '%d' % tc.sys_get_fps())
			tc.console_flush()


if __name__ == '__main__':
	app = Application()
	app.init()
	app.run()