diff --git a/01_dynamic_bsp_map.py b/01_dynamic_bsp_map.py new file mode 100644 index 0000000..51a94c2 --- /dev/null +++ b/01_dynamic_bsp_map.py @@ -0,0 +1,163 @@ +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() diff --git a/ground.png b/ground.png new file mode 100644 index 0000000..094c282 Binary files /dev/null and b/ground.png differ diff --git a/tiles.txt b/tiles.txt new file mode 100644 index 0000000..90d6aa3 --- /dev/null +++ b/tiles.txt @@ -0,0 +1,3 @@ +0: brick.png +1: road.png +2: ground.png