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