Mercurial > nagslang
comparison tools/area_editor.py @ 205:51f979ddddbb
Munge in interior wall drawing
author | Neil Muller <drnlmuller@gmail.com> |
---|---|
date | Tue, 03 Sep 2013 23:31:54 +0200 |
parents | 687459429550 |
children | 42c565c5ce76 |
comparison
equal
deleted
inserted
replaced
204:687459429550 | 205:51f979ddddbb |
---|---|
60 self.polygons.setdefault(poly_index, []) | 60 self.polygons.setdefault(poly_index, []) |
61 if not self.polygons[poly_index]: | 61 if not self.polygons[poly_index]: |
62 point = self.point_to_pymunk(self.round_point(pos)) | 62 point = self.point_to_pymunk(self.round_point(pos)) |
63 self.polygons[poly_index].append(point) | 63 self.polygons[poly_index].append(point) |
64 else: | 64 else: |
65 add_pos = self.fix_angle(poly_index, pos) | 65 add_pos = self.fix_poly_angle(poly_index, pos) |
66 self.polygons[poly_index].append(add_pos) | 66 self.polygons[poly_index].append(add_pos) |
67 | 67 |
68 def fix_angle(self, index, pos): | 68 def _fix_angle(self, point1, pos): |
69 # Last point | |
70 point1 = self.point_to_pygame(self.polygons[index][-1]) | |
71 pos = self.round_point(pos) | |
72 # We want the line (point1 to pos) to be an angle of | 69 # We want the line (point1 to pos) to be an angle of |
73 # 0, 45, 90, 135, 180, 225, 270, 305 | 70 # 0, 45, 90, 135, 180, 225, 270, 305 |
74 # However, we only need to consider half the circle | 71 # However, we only need to consider half the circle |
75 # This is a hack to approximate the right thing | 72 # This is a hack to approximate the right thing |
76 pos0 = (pos[0], point1[1]) | 73 pos0 = (pos[0], point1[1]) |
87 if dist < min_dist: | 84 if dist < min_dist: |
88 new_pos = cand | 85 new_pos = cand |
89 min_dist = dist | 86 min_dist = dist |
90 return self.point_to_pymunk(new_pos) | 87 return self.point_to_pymunk(new_pos) |
91 | 88 |
89 def fix_line_angle(self, start_pos, pos): | |
90 start_pos = self.round_point(start_pos) | |
91 pos = self.round_point(pos) | |
92 return self._fix_angle(start_pos, pos) | |
93 | |
94 def fix_poly_angle(self, index, pos): | |
95 # Last point | |
96 point1 = self.point_to_pygame(self.polygons[index][-1]) | |
97 pos = self.round_point(pos) | |
98 return self._fix_angle(point1, pos) | |
99 | |
92 def delete_point(self, index): | 100 def delete_point(self, index): |
93 if index in self.polygons and len(self.polygons[index]) > 0: | 101 if index in self.polygons and len(self.polygons[index]) > 0: |
94 self.polygons[index].pop() | 102 self.polygons[index].pop() |
95 | 103 |
96 def close_poly(self, index): | 104 def close_poly(self, index): |
100 it's limited as it's a magic point addition""" | 108 it's limited as it's a magic point addition""" |
101 if len(self.polygons[index]) < 2: | 109 if len(self.polygons[index]) < 2: |
102 # Too small | 110 # Too small |
103 return False | 111 return False |
104 first = self.polygons[index][0] | 112 first = self.polygons[index][0] |
105 if self.fix_angle(index, self.point_to_pygame(first)) == first: | 113 if self.fix_poly_angle(index, self.point_to_pygame(first)) == first: |
106 self.add_point(index, self.point_to_pygame(first)) | 114 self.add_point(index, self.point_to_pygame(first)) |
107 return True | 115 return True |
108 candidates = [(first[0] + 10 * i, first[1]) for | 116 candidates = [(first[0] + 10 * i, first[1]) for |
109 i in (-3, -2, -1, 1, 2, 3)] | 117 i in (-3, -2, -1, 1, 2, 3)] |
110 candidates.extend([(first[0], first[1] + 10 * i) for | 118 candidates.extend([(first[0], first[1] + 10 * i) for |
114 candidates.extend([(first[0] + 10 * i, first[1] - 10 * i) for | 122 candidates.extend([(first[0] + 10 * i, first[1] - 10 * i) for |
115 i in (-3, -2, -1, 1, 2, 3)]) | 123 i in (-3, -2, -1, 1, 2, 3)]) |
116 min_dist = 99999 | 124 min_dist = 99999 |
117 poss = None | 125 poss = None |
118 for cand in candidates: | 126 for cand in candidates: |
119 if self.fix_angle(index, self.point_to_pygame(cand)) == cand: | 127 if self.fix_poly_angle(index, self.point_to_pygame(cand)) == cand: |
120 dist = (first[0] - cand[0]) ** 2 + (first[1] - cand[1]) ** 2 | 128 dist = (first[0] - cand[0]) ** 2 + (first[1] - cand[1]) ** 2 |
121 if dist < min_dist: | 129 if dist < min_dist: |
122 poss = cand | 130 poss = cand |
123 if poss is not None: | 131 if poss is not None: |
124 self.add_point(index, self.point_to_pygame(poss)) | 132 self.add_point(index, self.point_to_pygame(poss)) |
125 self.add_point(index, self.point_to_pygame(first)) | 133 self.add_point(index, self.point_to_pygame(first)) |
126 return True | 134 return True |
127 return False | 135 return False |
128 | 136 |
129 def draw(self, mouse_pos, mouse_poly, filled): | 137 def add_line(self, start_pos, end_pos): |
138 endpoint = self.fix_line_angle(start_pos, end_pos) | |
139 startpoint = self.point_to_pymunk(self.round_point(start_pos)) | |
140 self.lines.append([startpoint, endpoint]) | |
141 | |
142 def draw(self, mouse_pos, mouse_poly, filled, draw_cand_line, start_pos): | |
130 self._draw_background(True) | 143 self._draw_background(True) |
131 # Draw polygons as needed for the editor | 144 # Draw polygons as needed for the editor |
132 if filled: | 145 if filled: |
133 self._draw_exterior(True) | 146 self._draw_exterior(True) |
134 for index, polygon in self.polygons.items(): | 147 for index, polygon in self.polygons.items(): |
135 color = POLY_COLORS[index] | 148 color = POLY_COLORS[index] |
136 if len(polygon) > 1: | 149 if len(polygon) > 1: |
137 pointlist = [self.point_to_pygame(p) for p in polygon] | 150 pointlist = [self.point_to_pygame(p) for p in polygon] |
138 pygame.draw.lines(self._surface, color, False, pointlist, 2) | 151 pygame.draw.lines(self._surface, color, False, pointlist, 2) |
139 if index == mouse_poly and mouse_pos: | 152 if index == mouse_poly and mouse_pos: |
140 endpoint = self.fix_angle(index, mouse_pos) | 153 endpoint = self.fix_poly_angle(index, mouse_pos) |
141 pygame.draw.line(self._surface, color, | 154 pygame.draw.line(self._surface, color, |
142 self.point_to_pygame(polygon[-1]), | 155 self.point_to_pygame(polygon[-1]), |
143 self.point_to_pygame(endpoint)) | 156 self.point_to_pygame(endpoint)) |
144 for line in self.lines: | 157 for line in self.lines: |
145 pointlist = [self.point_to_pygame(p) for p in line] | 158 pointlist = [self.point_to_pygame(p) for p in line] |
146 pygame.draw.lines(self._surface, LINE_COLOR, False, pointlist, 2) | 159 pygame.draw.lines(self._surface, LINE_COLOR, False, pointlist, 2) |
160 if draw_cand_line and start_pos and mouse_pos: | |
161 endpoint = self.fix_line_angle(start_pos, mouse_pos) | |
162 pointlist = [self.round_point(start_pos), | |
163 self.point_to_pygame(endpoint)] | |
164 pygame.draw.lines(self._surface, LINE_COLOR, False, pointlist, 1) | |
147 return self._surface.copy() | 165 return self._surface.copy() |
148 | 166 |
149 | 167 |
150 class LevelWidget(Widget): | 168 class LevelWidget(Widget): |
151 | 169 |
159 self.cur_poly = None | 177 self.cur_poly = None |
160 self._mouse_drag = False | 178 self._mouse_drag = False |
161 self._draw_objects = False | 179 self._draw_objects = False |
162 self._draw_enemies = False | 180 self._draw_enemies = False |
163 self._draw_lines = False | 181 self._draw_lines = False |
182 self._start_pos = None | |
164 | 183 |
165 def _level_coordinates(self, pos): | 184 def _level_coordinates(self, pos): |
166 # Move positions to level values | 185 # Move positions to level values |
167 if not pos: | 186 if not pos: |
168 return (0, 0) | 187 return (0, 0) |
193 def draw(self, surface): | 212 def draw(self, surface): |
194 if (self.cur_poly is not None and self.cur_poly in self.level.polygons | 213 if (self.cur_poly is not None and self.cur_poly in self.level.polygons |
195 and len(self.level.polygons[self.cur_poly])): | 214 and len(self.level.polygons[self.cur_poly])): |
196 # We have an active polygon | 215 # We have an active polygon |
197 mouse_pos = self._level_coordinates(self.mouse_pos) | 216 mouse_pos = self._level_coordinates(self.mouse_pos) |
217 elif self._draw_lines: | |
218 # Interior wall mode | |
219 mouse_pos = self._level_coordinates(self.mouse_pos) | |
198 else: | 220 else: |
199 mouse_pos = None | 221 mouse_pos = None |
200 level_surface = level.draw(mouse_pos, self.cur_poly, self.filled_mode) | 222 level_surface = level.draw(mouse_pos, self.cur_poly, self.filled_mode, |
223 self._draw_lines, self._start_pos) | |
201 if self._draw_objects: | 224 if self._draw_objects: |
202 for thing in self.level.drawables: | 225 for thing in self.level.drawables: |
203 if not isinstance(thing, Enemy): | 226 if not isinstance(thing, Enemy): |
204 thing.render(level_surface) | 227 thing.render(level_surface) |
205 if self._draw_enemies: | 228 if self._draw_enemies: |
217 | 240 |
218 def line_mode(self): | 241 def line_mode(self): |
219 self.cur_poly = None | 242 self.cur_poly = None |
220 self._draw_lines = True | 243 self._draw_lines = True |
221 self.filled_mode = False | 244 self.filled_mode = False |
245 self._start_pos = None | |
222 | 246 |
223 def key_down(self, ev): | 247 def key_down(self, ev): |
224 if ev.key == pgl.K_LEFT: | 248 if ev.key == pgl.K_LEFT: |
225 self._move_view((-10, 0)) | 249 self._move_view((-10, 0)) |
226 elif ev.key == pgl.K_RIGHT: | 250 elif ev.key == pgl.K_RIGHT: |
250 alert('Not all polygons closed, so not filling') | 274 alert('Not all polygons closed, so not filling') |
251 | 275 |
252 def mouse_move(self, ev): | 276 def mouse_move(self, ev): |
253 old_pos = self.mouse_pos | 277 old_pos = self.mouse_pos |
254 self.mouse_pos = ev.pos | 278 self.mouse_pos = ev.pos |
255 if self.cur_poly and old_pos != self.mouse_pos: | 279 if old_pos != self.mouse_pos and (self.cur_poly or self._draw_lines): |
256 self.invalidate() | 280 self.invalidate() |
257 | 281 |
258 def mouse_drag(self, ev): | 282 def mouse_drag(self, ev): |
259 if self._mouse_drag: | 283 if self._mouse_drag: |
260 old_pos = self.mouse_pos | 284 old_pos = self.mouse_pos |
265 self.invalidate() | 289 self.invalidate() |
266 | 290 |
267 def mouse_down(self, ev): | 291 def mouse_down(self, ev): |
268 if ev.button == 1: | 292 if ev.button == 1: |
269 if self._draw_lines: | 293 if self._draw_lines: |
270 pass | 294 if self._start_pos is None: |
295 self._start_pos = ev.pos | |
296 else: | |
297 self.level.add_line(self._start_pos, ev.pos) | |
298 self._start_pos = None | |
271 else: | 299 else: |
272 print "Click: %r" % ( | 300 print "Click: %r" % ( |
273 self.level.point_to_pymunk( | 301 self.level.point_to_pymunk( |
274 self._level_coordinates(ev.pos)),) | 302 self._level_coordinates(ev.pos)),) |
275 if ev.button == 4: # Scroll up | 303 if ev.button == 4: # Scroll up |