Mercurial > nagslang
comparison tools/area_editor.py @ 407:314ddad2d6d2
Move points button
author | Neil Muller <drnlmuller@gmail.com> |
---|---|
date | Sat, 07 Sep 2013 12:10:42 +0200 |
parents | 9589e1db4433 |
children | ddff1f8668d5 |
comparison
equal
deleted
inserted
replaced
406:7fcde01ea50e | 407:314ddad2d6d2 |
---|---|
51 | 51 |
52 class TestWorld(object): | 52 class TestWorld(object): |
53 | 53 |
54 def __init__(self): | 54 def __init__(self): |
55 self.level_state = {} | 55 self.level_state = {} |
56 self.inventory = {} | |
57 | |
58 | |
59 def distance(tup1, tup2): | |
60 return (tup1[0] - tup2[0]) ** 2 + (tup1[1] - tup2[1]) ** 2 | |
56 | 61 |
57 | 62 |
58 class EditorLevel(Level): | 63 class EditorLevel(Level): |
59 | 64 |
60 def __init__(self, name, x=800, y=600): | 65 def __init__(self, name, x=800, y=600): |
62 super(EditorLevel, self).__init__(name, world) | 67 super(EditorLevel, self).__init__(name, world) |
63 self.x = x | 68 self.x = x |
64 self.y = y | 69 self.y = y |
65 # Lookup initiliasition info from the objects | 70 # Lookup initiliasition info from the objects |
66 self.lookup = {} | 71 self.lookup = {} |
72 self._move_poly = None | |
67 | 73 |
68 def round_point(self, pos): | 74 def round_point(self, pos): |
69 return (10 * (pos[0] // 10), 10 * (pos[1] // 10)) | 75 return (10 * (pos[0] // 10), 10 * (pos[1] // 10)) |
70 | 76 |
71 def load(self, space): | 77 def load(self, space): |
101 pos225 = (point1[0] - dist, point1[1] - dist) | 107 pos225 = (point1[0] - dist, point1[1] - dist) |
102 pos305 = (point1[0] - dist, point1[1] + dist) | 108 pos305 = (point1[0] - dist, point1[1] + dist) |
103 min_dist = 9999999 | 109 min_dist = 9999999 |
104 new_pos = point1 | 110 new_pos = point1 |
105 for cand in [pos0, pos90, pos45, pos135, pos225, pos305]: | 111 for cand in [pos0, pos90, pos45, pos135, pos225, pos305]: |
106 dist = (pos[0] - cand[0]) ** 2 + (pos[1] - cand[1]) ** 2 | 112 dist = distance(pos, cand) |
107 if dist < min_dist: | 113 if dist < min_dist: |
108 new_pos = cand | 114 new_pos = cand |
109 min_dist = dist | 115 min_dist = dist |
110 return self.point_to_pymunk(new_pos) | 116 return self.point_to_pymunk(new_pos) |
111 | 117 |
146 i in (-3, -2, -1, 1, 2, 3)]) | 152 i in (-3, -2, -1, 1, 2, 3)]) |
147 min_dist = 99999 | 153 min_dist = 99999 |
148 poss = None | 154 poss = None |
149 for cand in candidates: | 155 for cand in candidates: |
150 if self.fix_poly_angle(index, self.point_to_pygame(cand)) == cand: | 156 if self.fix_poly_angle(index, self.point_to_pygame(cand)) == cand: |
151 dist = (first[0] - cand[0]) ** 2 + (first[1] - cand[1]) ** 2 | 157 dist = distance(first, cand) |
152 if dist < min_dist: | 158 if dist < min_dist: |
153 poss = cand | 159 poss = cand |
154 if poss is not None: | 160 if poss is not None: |
155 self.add_point(index, self.point_to_pygame(poss)) | 161 self.add_point(index, self.point_to_pygame(poss)) |
156 self.add_point(index, self.point_to_pygame(first)) | 162 self.add_point(index, self.point_to_pygame(first)) |
160 def add_line(self, start_pos, end_pos): | 166 def add_line(self, start_pos, end_pos): |
161 endpoint = self.fix_line_angle(start_pos, end_pos) | 167 endpoint = self.fix_line_angle(start_pos, end_pos) |
162 startpoint = self.point_to_pymunk(self.round_point(start_pos)) | 168 startpoint = self.point_to_pymunk(self.round_point(start_pos)) |
163 self.lines.append([startpoint, endpoint]) | 169 self.lines.append([startpoint, endpoint]) |
164 | 170 |
165 def draw(self, mouse_pos, mouse_poly, filled, draw_cand_line, start_pos): | 171 def draw(self, mouse_pos, mouse_poly, filled, draw_cand_line, start_pos, |
172 move_point_mode, move_point): | |
166 self._draw_background(True) | 173 self._draw_background(True) |
167 # Draw polygons as needed for the editor | 174 # Draw polygons as needed for the editor |
168 if filled: | 175 if filled: |
169 self._draw_exterior(True) | 176 self._draw_exterior(True) |
170 for index, polygon in self.polygons.items(): | 177 for index, polygon in self.polygons.items(): |
171 color = POLY_COLORS[index] | 178 color = POLY_COLORS[index] |
172 if len(polygon) > 1: | 179 if move_point_mode and index == self._move_poly: |
180 pointlist = [p for p in polygon] | |
181 pointlist = [self.point_to_pygame(p) if p != move_point else | |
182 mouse_pos for p in pointlist] | |
183 pygame.draw.lines(self._surface, color, False, pointlist, 2) | |
184 elif len(polygon) > 1: | |
173 pointlist = [self.point_to_pygame(p) for p in polygon] | 185 pointlist = [self.point_to_pygame(p) for p in polygon] |
174 pygame.draw.lines(self._surface, color, False, pointlist, 2) | 186 pygame.draw.lines(self._surface, color, False, pointlist, 2) |
175 if index == mouse_poly and mouse_pos: | 187 elif index == mouse_poly and mouse_pos: |
176 endpoint = self.fix_poly_angle(index, mouse_pos) | 188 endpoint = self.fix_poly_angle(index, mouse_pos) |
177 pygame.draw.line(self._surface, color, | 189 pygame.draw.line(self._surface, color, |
178 self.point_to_pygame(polygon[-1]), | 190 self.point_to_pygame(polygon[-1]), |
179 self.point_to_pygame(endpoint)) | 191 self.point_to_pygame(endpoint)) |
192 line_found = False # Hack for sane behaviour if lines overlap | |
180 for line in self.lines: | 193 for line in self.lines: |
181 pointlist = [self.point_to_pygame(p) for p in line] | 194 pointlist = [self.point_to_pygame(p) for p in line] |
195 if move_point_mode and not self._move_poly and not line_found: | |
196 if move_point in line: | |
197 line_found = True | |
198 pointlist.remove(self.point_to_pygame(move_point)) | |
199 pointlist.append(mouse_pos) | |
182 pygame.draw.lines(self._surface, LINE_COLOR, False, pointlist, 2) | 200 pygame.draw.lines(self._surface, LINE_COLOR, False, pointlist, 2) |
183 if draw_cand_line and start_pos and mouse_pos: | 201 if draw_cand_line and start_pos and mouse_pos: |
184 endpoint = self.fix_line_angle(start_pos, mouse_pos) | 202 endpoint = self.fix_line_angle(start_pos, mouse_pos) |
185 pointlist = [self.round_point(start_pos), | 203 pointlist = [self.round_point(start_pos), |
186 self.point_to_pygame(endpoint)] | 204 self.point_to_pygame(endpoint)] |
233 # Search visible objects | 251 # Search visible objects |
234 for obj in self.drawables: | 252 for obj in self.drawables: |
235 if obj.get_shape().point_query(pymunk_pos): | 253 if obj.get_shape().point_query(pymunk_pos): |
236 return obj | 254 return obj |
237 return None | 255 return None |
256 | |
257 def find_vertex(self, mouse_pos): | |
258 # search for vertexes closest to where we've killed | |
259 mindist = 400 | |
260 move_point = None | |
261 search_point = self.point_to_pymunk(mouse_pos) | |
262 for index, polygon in self.polygons.items(): | |
263 for point in polygon: | |
264 dist = distance(point, search_point) | |
265 if dist < mindist: | |
266 mindist = dist | |
267 move_point = point | |
268 self._move_poly = index | |
269 # Also check lines | |
270 for line in self.lines: | |
271 for point in line: | |
272 dist = distance(point, search_point) | |
273 if dist < mindist: | |
274 mindist = dist | |
275 move_point = point | |
276 self._move_poly = None | |
277 return move_point | |
278 | |
279 def replace_vertex(self, old_point, new_point): | |
280 new_point = self.point_to_pymunk(new_point) | |
281 if self._move_poly: | |
282 new_polygon = [p if p != old_point else new_point for p in | |
283 self.polygons[self._move_poly]] | |
284 self.polygons[self._move_poly] = new_polygon | |
285 else: | |
286 for line in self.lines: | |
287 if old_point in line: | |
288 line.remove(old_point) | |
289 line.append(new_point) | |
290 break | |
238 | 291 |
239 | 292 |
240 class ObjectTable(TableView): | 293 class ObjectTable(TableView): |
241 | 294 |
242 columns = [TableColumn("Object", 690, 'l', '%r')] | 295 columns = [TableColumn("Object", 690, 'l', '%r')] |
397 self._draw_enemies = False | 450 self._draw_enemies = False |
398 self._draw_lines = False | 451 self._draw_lines = False |
399 self.sel_mode = False | 452 self.sel_mode = False |
400 self._start_pos = None | 453 self._start_pos = None |
401 self._parent = parent | 454 self._parent = parent |
455 self._move_point_mode = False | |
456 self._move_point = False | |
402 | 457 |
403 def _level_coordinates(self, pos): | 458 def _level_coordinates(self, pos): |
404 # Move positions to level values | 459 # Move positions to level values |
405 if not pos: | 460 if not pos: |
406 return (0, 0) | 461 return (0, 0) |
434 # We have an active polygon | 489 # We have an active polygon |
435 mouse_pos = self._level_coordinates(self.mouse_pos) | 490 mouse_pos = self._level_coordinates(self.mouse_pos) |
436 elif self._draw_lines: | 491 elif self._draw_lines: |
437 # Interior wall mode | 492 # Interior wall mode |
438 mouse_pos = self._level_coordinates(self.mouse_pos) | 493 mouse_pos = self._level_coordinates(self.mouse_pos) |
494 elif self._move_point_mode: | |
495 mouse_pos = self._level_coordinates(self.mouse_pos) | |
439 else: | 496 else: |
440 mouse_pos = None | 497 mouse_pos = None |
441 level_surface = level.draw(mouse_pos, self.cur_poly, self.filled_mode, | 498 level_surface = level.draw(mouse_pos, self.cur_poly, self.filled_mode, |
442 self._draw_lines, self._start_pos) | 499 self._draw_lines, self._start_pos, |
500 self._move_point_mode, self._move_point) | |
443 if self._draw_objects: | 501 if self._draw_objects: |
444 for thing in self.level.drawables: | 502 for thing in self.level.drawables: |
445 if not isinstance(thing, ne.Enemy): | 503 if not isinstance(thing, ne.Enemy): |
446 thing.render(level_surface) | 504 thing.render(level_surface) |
447 if self._draw_enemies: | 505 if self._draw_enemies: |
462 self.cur_poly = None | 520 self.cur_poly = None |
463 self._parent.reset_lit_buttons() | 521 self._parent.reset_lit_buttons() |
464 self._draw_lines = True | 522 self._draw_lines = True |
465 self.filled_mode = False | 523 self.filled_mode = False |
466 self._start_pos = None | 524 self._start_pos = None |
525 self._move_point_mode = False | |
467 | 526 |
468 def key_down(self, ev): | 527 def key_down(self, ev): |
469 if ev.key == pgl.K_LEFT: | 528 if ev.key == pgl.K_LEFT: |
470 self._move_view((-10, 0)) | 529 self._move_view((-10, 0)) |
471 elif ev.key == pgl.K_RIGHT: | 530 elif ev.key == pgl.K_RIGHT: |
483 elif ev.key == pgl.K_f: | 542 elif ev.key == pgl.K_f: |
484 self.set_filled() | 543 self.set_filled() |
485 elif ev.key == pgl.K_c: | 544 elif ev.key == pgl.K_c: |
486 self.close_poly() | 545 self.close_poly() |
487 | 546 |
547 def set_move_mode(self): | |
548 self._draw_lines = False | |
549 self._move_point_mode = True | |
550 self.filled_mode = False | |
551 self._parent.reset_lit_buttons() | |
552 self._move_point = None | |
553 | |
488 def set_filled(self): | 554 def set_filled(self): |
489 closed, _ = self.level.all_closed() | 555 closed, _ = self.level.all_closed() |
490 if closed: | 556 if closed: |
491 self.cur_poly = None | 557 self.cur_poly = None |
492 self._parent.reset_lit_buttons() | 558 self._parent.reset_lit_buttons() |
493 self.filled_mode = True | 559 self.filled_mode = True |
494 self._draw_lines = False | 560 self._draw_lines = False |
561 self._move_point_mode = False | |
495 else: | 562 else: |
496 alert('Not all polygons closed, so not filling') | 563 alert('Not all polygons closed, so not filling') |
497 | 564 |
498 def mouse_move(self, ev): | 565 def mouse_move(self, ev): |
499 old_pos = self.mouse_pos | 566 old_pos = self.mouse_pos |
500 self.mouse_pos = ev.pos | 567 self.mouse_pos = ev.pos |
501 if old_pos != self.mouse_pos and (self.cur_poly or self._draw_lines): | 568 if old_pos != self.mouse_pos and (self.cur_poly or self._draw_lines |
569 or self._move_point_mode): | |
502 self.invalidate() | 570 self.invalidate() |
503 | 571 |
504 def mouse_drag(self, ev): | 572 def mouse_drag(self, ev): |
505 if self._mouse_drag: | 573 if self._mouse_drag: |
506 old_pos = self.mouse_pos | 574 old_pos = self.mouse_pos |
509 -self.mouse_pos[1] + old_pos[1]) | 577 -self.mouse_pos[1] + old_pos[1]) |
510 self._move_view(diff) | 578 self._move_view(diff) |
511 self.invalidate() | 579 self.invalidate() |
512 | 580 |
513 def mouse_down(self, ev): | 581 def mouse_down(self, ev): |
582 corrected_pos = ev.pos[0] + self.pos[0], ev.pos[1] + self.pos[1] | |
514 if self.sel_mode and ev.button == 1: | 583 if self.sel_mode and ev.button == 1: |
515 corrected_pos = ev.pos[0] + self.pos[0], ev.pos[1] + self.pos[1] | |
516 obj = self.level.find_obj_at_pos(corrected_pos) | 584 obj = self.level.find_obj_at_pos(corrected_pos) |
517 if obj is not None: | 585 if obj is not None: |
518 self._edit_selected(obj) | 586 self._edit_selected(obj) |
587 elif self._move_point_mode and ev.button == 1: | |
588 if self._move_point: | |
589 # Place the current point | |
590 self.level.replace_vertex(self._move_point, corrected_pos) | |
591 self._move_point = None | |
592 self.invalidate() | |
593 else: | |
594 # find the current point | |
595 self._move_point = self.level.find_vertex(corrected_pos) | |
519 elif ev.button == 1: | 596 elif ev.button == 1: |
520 if self._draw_lines: | 597 if self._draw_lines: |
521 if self._start_pos is None: | 598 if self._start_pos is None: |
522 self._start_pos = ev.pos | 599 self._start_pos = ev.pos |
523 else: | 600 else: |
777 end_poly_but.rect = BUTTON_RECT.copy() | 854 end_poly_but.rect = BUTTON_RECT.copy() |
778 end_poly_but.rect.move_ip(MENU_LEFT, y) | 855 end_poly_but.rect.move_ip(MENU_LEFT, y) |
779 widgets.append(end_poly_but) | 856 widgets.append(end_poly_but) |
780 y += MENU_BUTTON_HEIGHT + MENU_PAD | 857 y += MENU_BUTTON_HEIGHT + MENU_PAD |
781 | 858 |
859 self.move_point_but = HighLightButton("Move Point", self, | |
860 action=self.move_point) | |
861 self.move_point_but.rect = BUTTON_RECT.copy() | |
862 self.move_point_but.rect.move_ip(MENU_LEFT, y) | |
863 widgets.append(self.move_point_but) | |
864 self._light_buttons.append(self.move_point_but) | |
865 y += MENU_BUTTON_HEIGHT + MENU_PAD | |
866 | |
782 self.draw_line_but = HighLightButton("Draw interior wall", self, | 867 self.draw_line_but = HighLightButton("Draw interior wall", self, |
783 action=self.set_line_mode) | 868 action=self.set_line_mode) |
784 self.draw_line_but.rect = BUTTON_RECT.copy() | 869 self.draw_line_but.rect = BUTTON_RECT.copy() |
785 self.draw_line_but.rect.move_ip(MENU_LEFT, y) | 870 self.draw_line_but.rect.move_ip(MENU_LEFT, y) |
786 widgets.append(self.draw_line_but) | 871 widgets.append(self.draw_line_but) |
967 else: | 1052 else: |
968 self.sel_mode_but.reset() | 1053 self.sel_mode_but.reset() |
969 | 1054 |
970 def mouse_move(self, ev): | 1055 def mouse_move(self, ev): |
971 self.level_widget.mouse_move(ev) | 1056 self.level_widget.mouse_move(ev) |
1057 | |
1058 def move_point(self): | |
1059 self.level_widget.set_move_mode() | |
1060 self.move_point_but.highlight() | |
972 | 1061 |
973 def draw(self, surface): | 1062 def draw(self, surface): |
974 # Update checkbox state | 1063 # Update checkbox state |
975 if self._menu_mode == 'drawing': | 1064 if self._menu_mode == 'drawing': |
976 self.level_widget.set_objects(self.show_objs.value) | 1065 self.level_widget.set_objects(self.show_objs.value) |