import pyglet from pyglet.window import key import sys import re import random # constants TILE_SIZE_X = 16 TILE_SIZE_Y = 16 MIN_LEAF_SIZE = 4 class Leaf: """ Leaf of the BSP """ def __init__(self, x, y, w, h, id): self.id = id self.x = x self.y = y self.width = w self.height = h self.left_leaf = None self.right_leaf = None def print_leaf(self): print(str(self.id) + ': (' + str(self.x) + '), (' + str(self.y) + ')' + ' - ' + str(self.width) + 'x' + str(self.height) ) def split(self): """ :return: True if the leaf has been split """ self.print_leaf() # choose direction # TODO: if leaf is not so square, split along the long side # if width > XX% height (25, 33 ?) -> split vertical if random.random() < 0.5: # x if self.width < MIN_LEAF_SIZE * 2: # leaf is too small return False split_point = random.randint(MIN_LEAF_SIZE, self.width - MIN_LEAF_SIZE) self.left_leaf = Leaf(self.x, self.y, split_point, self.height, self.id+1) self.right_leaf = Leaf(self.x + split_point-1, self.y, self.width - split_point+1, self.height, self.id+2) else: # y if self.height < MIN_LEAF_SIZE * 2: # leaf is too small return False split_point = random.randint(MIN_LEAF_SIZE, self.height - MIN_LEAF_SIZE) self.left_leaf = Leaf(self.x, self.y, self.width, split_point, self.id+1) self.right_leaf = Leaf(self.x, self.y + split_point-1, self.width, self.height - split_point+1, self.id+2) return True def draw(self, wall, ground): # first wall for x in range(0, self.width): wall.blit((self.x+x)*TILE_SIZE_X, self.y*TILE_SIZE_Y) # middle for y in range(1, self.height-1): wall.blit(self.x*TILE_SIZE_X, (self.y+y)*TILE_SIZE_Y) for x in range(1, self.width - 1): ground.blit((self.x + x)*TILE_SIZE_X, (self.y+y)*TILE_SIZE_Y) wall.blit((self.x+self.width-1)*TILE_SIZE_X, (self.y+y)*TILE_SIZE_Y) # end for x in range(0, self.width): wall.blit((self.x+x)*TILE_SIZE_X, (self.y + self.height-1)*TILE_SIZE_Y) def generate_tree(): # init tree tree = [Leaf(0, 0, 24, 24, 0)] #tree = [Leaf(0, 0, 10, 10, 0)] #tree = [Leaf(0, 0, 5, 5, 0)] # split leaves until none succeed split_done = True while split_done: split_done = False for l in tree: if l.left_leaf == None and l.right_leaf == None: if (l.split()): tree.append(l.left_leaf) tree.append(l.right_leaf) split_done = True return tree ## # main ## # main window window = pyglet.window.Window() @window.event def on_key_press(symbol, modifiers): #TODO: ugly hack global level_tree if symbol == key.Q: print('Will quit') if symbol == key.R: print('Regeneration') level_tree = generate_tree() window.invalid = True elif symbol == key.LEFT: print('Left arrow') elif symbol == key.ENTER: print('Enter !') @window.event def on_draw(): window.clear() draw_tree(level_tree) label.draw() def draw_tree(t): """ :param t: each leave of t will be draw() """ for l in t: # draw only last leaves if l.left_leaf == None and l.right_leaf == None: l.draw(tiles[TILE_WALL], tiles[TILE_GROUND]) # init random #TODO add seed mode (how ?) random.seed() label = pyglet.text.Label('Plop World', x = window.width*3/4, y = window.height*3/4, anchor_x='center', anchor_y='center') # load images tiles = [] resource_file = open('tiles.txt') line = resource_file.readline().strip() while line: tile_file = re.compile('\d: ').split(line)[1] print('loading tile: ' + str(tile_file)) tiles.append(pyglet.resource.image(tile_file)) line = resource_file.readline().strip() TILE_WALL = 0 TILE_GROUND = 2 level_tree = generate_tree() # artificial tree to test drawing # troot = Leaf(0, 0, 24, 24, 0) # tll = Leaf(0, 0, 16, 24, 1) # trl = Leaf(16, 0, 8, 24, 2) # troot.left_leaf = tll # troot.right_leaf = trl # tllvl = Leaf(0, 0, 16, 4, 3) # tllvr = Leaf(0, 4, 16, 20, 4) # level_tree = [troot, tll, trl, tllvl, tllvr] pyglet.app.run()