Mercurial > nagslang
diff tools/area_editor.py @ 241:ec567098cf41
Merge
author | David Sharpe |
---|---|
date | Wed, 04 Sep 2013 01:23:43 +0200 |
parents | 42c565c5ce76 |
children | 06c52529e2ed |
line wrap: on
line diff
--- a/tools/area_editor.py Wed Sep 04 01:23:32 2013 +0200 +++ b/tools/area_editor.py Wed Sep 04 01:23:43 2013 +0200 @@ -23,11 +23,13 @@ from albow.root import RootWidget from albow.widget import Widget -from albow.controls import Button +from albow.controls import Button, Label, CheckBox from albow.dialogs import alert +from nagslang.options import parse_args from nagslang.constants import SCREEN -from nagslang.level import Level, POLY_COLORS +from nagslang.level import Level, POLY_COLORS, LINE_COLOR +from nagslang.enemies import Enemy # layout constants @@ -60,13 +62,10 @@ point = self.point_to_pymunk(self.round_point(pos)) self.polygons[poly_index].append(point) else: - add_pos = self.fix_angle(poly_index, pos) + add_pos = self.fix_poly_angle(poly_index, pos) self.polygons[poly_index].append(add_pos) - def fix_angle(self, index, pos): - # Last point - point1 = self.point_to_pygame(self.polygons[index][-1]) - pos = self.round_point(pos) + def _fix_angle(self, point1, pos): # We want the line (point1 to pos) to be an angle of # 0, 45, 90, 135, 180, 225, 270, 305 # However, we only need to consider half the circle @@ -87,6 +86,17 @@ min_dist = dist return self.point_to_pymunk(new_pos) + def fix_line_angle(self, start_pos, pos): + start_pos = self.round_point(start_pos) + pos = self.round_point(pos) + return self._fix_angle(start_pos, pos) + + def fix_poly_angle(self, index, pos): + # Last point + point1 = self.point_to_pygame(self.polygons[index][-1]) + pos = self.round_point(pos) + return self._fix_angle(point1, pos) + def delete_point(self, index): if index in self.polygons and len(self.polygons[index]) > 0: self.polygons[index].pop() @@ -100,7 +110,7 @@ # Too small return False first = self.polygons[index][0] - if self.fix_angle(index, self.point_to_pygame(first)) == first: + if self.fix_poly_angle(index, self.point_to_pygame(first)) == first: self.add_point(index, self.point_to_pygame(first)) return True candidates = [(first[0] + 10 * i, first[1]) for @@ -114,7 +124,7 @@ min_dist = 99999 poss = None for cand in candidates: - if self.fix_angle(index, self.point_to_pygame(cand)) == cand: + if self.fix_poly_angle(index, self.point_to_pygame(cand)) == cand: dist = (first[0] - cand[0]) ** 2 + (first[1] - cand[1]) ** 2 if dist < min_dist: poss = cand @@ -124,7 +134,12 @@ return True return False - def draw(self, surface, topleft, mouse_pos, mouse_poly, filled): + def add_line(self, start_pos, end_pos): + endpoint = self.fix_line_angle(start_pos, end_pos) + startpoint = self.point_to_pymunk(self.round_point(start_pos)) + self.lines.append([startpoint, endpoint]) + + def draw(self, mouse_pos, mouse_poly, filled, draw_cand_line, start_pos): self._draw_background(True) # Draw polygons as needed for the editor if filled: @@ -135,12 +150,19 @@ pointlist = [self.point_to_pygame(p) for p in polygon] pygame.draw.lines(self._surface, color, False, pointlist, 2) if index == mouse_poly and mouse_pos: - endpoint = self.fix_angle(index, mouse_pos) + endpoint = self.fix_poly_angle(index, mouse_pos) pygame.draw.line(self._surface, color, self.point_to_pygame(polygon[-1]), self.point_to_pygame(endpoint)) - surface_area = pygame.rect.Rect(topleft, SCREEN) - surface.blit(self._surface, (0, 0), surface_area) + for line in self.lines: + pointlist = [self.point_to_pygame(p) for p in line] + pygame.draw.lines(self._surface, LINE_COLOR, False, pointlist, 2) + if draw_cand_line and start_pos and mouse_pos: + endpoint = self.fix_line_angle(start_pos, mouse_pos) + pointlist = [self.round_point(start_pos), + self.point_to_pygame(endpoint)] + pygame.draw.lines(self._surface, LINE_COLOR, False, pointlist, 1) + return self._surface.copy() class LevelWidget(Widget): @@ -154,6 +176,10 @@ self.mouse_pos = None self.cur_poly = None self._mouse_drag = False + self._draw_objects = False + self._draw_enemies = False + self._draw_lines = False + self._start_pos = None def _level_coordinates(self, pos): # Move positions to level values @@ -173,21 +199,51 @@ new_pos[1] = self.pos[1] self.pos = tuple(new_pos) + def set_objects(self, value): + if self._draw_objects != value: + self._draw_objects = value + self.invalidate() + + def set_enemies(self, value): + if self._draw_enemies != value: + self._draw_enemies = value + self.invalidate() + def draw(self, surface): if (self.cur_poly is not None and self.cur_poly in self.level.polygons and len(self.level.polygons[self.cur_poly])): # We have an active polygon mouse_pos = self._level_coordinates(self.mouse_pos) + elif self._draw_lines: + # Interior wall mode + mouse_pos = self._level_coordinates(self.mouse_pos) else: mouse_pos = None - level.draw(surface, self.pos, mouse_pos, self.cur_poly, - self.filled_mode) + level_surface = level.draw(mouse_pos, self.cur_poly, self.filled_mode, + self._draw_lines, self._start_pos) + if self._draw_objects: + for thing in self.level.drawables: + if not isinstance(thing, Enemy): + thing.render(level_surface) + if self._draw_enemies: + for thing in self.level.drawables: + if isinstance(thing, Enemy): + thing.render(level_surface) + surface_area = pygame.rect.Rect(self.pos, SCREEN) + surface.blit(level_surface, (0, 0), surface_area) def change_poly(self, new_poly): self.cur_poly = new_poly + self._draw_lines = False if self.cur_poly is not None: self.filled_mode = False + def line_mode(self): + self.cur_poly = None + self._draw_lines = True + self.filled_mode = False + self._start_pos = None + def key_down(self, ev): if ev.key == pgl.K_LEFT: self._move_view((-10, 0)) @@ -213,13 +269,14 @@ if closed: self.cur_poly = None self.filled_mode = True + self._draw_lines = False else: alert('Not all polygons closed, so not filling') def mouse_move(self, ev): old_pos = self.mouse_pos self.mouse_pos = ev.pos - if self.cur_poly and old_pos != self.mouse_pos: + if old_pos != self.mouse_pos and (self.cur_poly or self._draw_lines): self.invalidate() def mouse_drag(self, ev): @@ -233,8 +290,16 @@ def mouse_down(self, ev): if ev.button == 1: - print "Click: %r" % ( - self.level.point_to_pymunk(self._level_coordinates(ev.pos)),) + if self._draw_lines: + if self._start_pos is None: + self._start_pos = ev.pos + else: + self.level.add_line(self._start_pos, ev.pos) + self._start_pos = None + else: + print "Click: %r" % ( + self.level.point_to_pymunk( + self._level_coordinates(ev.pos)),) if ev.button == 4: # Scroll up self._move_view((0, -10)) elif ev.button == 5: # Scroll down @@ -304,12 +369,21 @@ button_rect = pygame.rect.Rect(0, 0, MENU_WIDTH, MENU_BUTTON_HEIGHT) + check_rect = pygame.rect.Rect(0, 0, MENU_BUTTON_HEIGHT // 2, + MENU_BUTTON_HEIGHT // 2) + end_poly_but = PolyButton(None, self.level_widget) end_poly_but.rect = button_rect.copy() end_poly_but.rect.move_ip(MENU_LEFT, y) self.add(end_poly_but) y += MENU_BUTTON_HEIGHT + MENU_PAD + draw_line = Button("Draw interior wall", self.level_widget.line_mode) + draw_line.rect = button_rect.copy() + draw_line.rect.move_ip(MENU_LEFT, y) + self.add(draw_line) + y += MENU_BUTTON_HEIGHT + MENU_PAD + fill_but = Button('Fill exterior', action=self.level_widget.set_filled) fill_but.rect = button_rect.copy() fill_but.rect.move_ip(MENU_LEFT, y) @@ -329,6 +403,25 @@ self.add(close_poly_but) y += MENU_BUTTON_HEIGHT + MENU_PAD + white = pygame.color.Color("white") + self.show_objs = CheckBox(fg_color=white) + self.show_objs.rect = check_rect.copy() + self.show_objs.rect.move_ip(MENU_LEFT, y) + label = Label("Show Objects", fg_color=white) + label.rect.move_ip(MENU_LEFT + MENU_BUTTON_HEIGHT // 2 + MENU_PAD, y) + self.add(self.show_objs) + self.add(label) + y += label.rect.height + MENU_PAD + + self.show_enemies = CheckBox(fg_color=white) + self.show_enemies.rect = check_rect.copy() + self.show_enemies.rect.move_ip(MENU_LEFT, y) + label = Label("Show enemy start pos", fg_color=white) + label.rect.move_ip(MENU_LEFT + MENU_BUTTON_HEIGHT // 2 + MENU_PAD, y) + self.add(self.show_enemies) + self.add(label) + y += label.rect.height + MENU_PAD + quit_but = Button('Quit', action=self.quit) quit_but.rect = button_rect.copy() quit_but.rect.move_ip(MENU_LEFT, y) @@ -355,11 +448,19 @@ def mouse_move(self, ev): self.level_widget.mouse_move(ev) + def draw(self, surface): + # Update checkbox state + self.level_widget.set_objects(self.show_objs.value) + self.level_widget.set_enemies(self.show_enemies.value) + super(EditorApp, self).draw(surface) + if __name__ == "__main__": if len(sys.argv) not in [2, 4]: print 'Please supply a levelname or levelname and level size' sys.exit() + # Need to ensure we have defaults for rendering + parse_args([]) pygame.display.init() pygame.font.init() pygame.display.set_mode((SCREEN[0] + MENU_WIDTH, SCREEN[1]),