Прикреплённый файл «2013-12-20-greditor.py»
Загрузка 1 #!/usr/bin/env python
2 # coding: utf
3 '''
4 Примитивный графический редактор,
5 иллюстрирующий объектное планирование игрового пространства
6 '''
7
8 import pygame
9 from math import *
10
11 pygame.init()
12 black = pygame.Color("black")
13 tan = pygame.Color("tan")
14 red = pygame.Color("tomato")
15 green = pygame.Color("limegreen")
16
17 color = green
18
19 class Dot:
20 '''Точка'''
21 def __init__(self, size=3):
22 '''size — размер точки при рисовании'''
23 self.dots = []
24 self.ndots = 1
25 self.size = size
26 self.color = color
27
28 def append(self, dot):
29 '''Добавить точку'''
30 if not self.is_complete():
31 self.dots.append(dot)
32
33 def is_complete(self):
34 '''Редактирование фигуры закончено?'''
35 return len(self.dots) >= self.ndots
36
37 def draw(self, scr, pos=None):
38 '''Нарисовать точку по имеющимся координатам илив позиции pos'''
39 if self.is_complete():
40 pygame.draw.circle(scr, self.color, self.dots[0], self.size)
41 elif pos:
42 pygame.draw.circle(scr, self.color, pos, self.size)
43
44 class Line(Dot):
45 '''Отрезок'''
46 def __init__(self, size=2):
47 '''size — размер точки при рисовании'''
48 Dot.__init__(self, size)
49 self.ndots = 2
50
51 def shape(self, scr, pos1, pos2):
52 '''Нарисовать линию'''
53 pygame.draw.line(scr, self.color, pos1, pos2, self.size)
54
55 def draw(self, scr, pos=None):
56 '''Нарисовать в зависимости от количества введённых точек:
57 0 — точку в позиции pos
58 1 — фигуру по введённой опорной точке и pos
59 2 — фигуру по введённым опорной и второй точке'''
60 if self.is_complete():
61 self.shape(scr, self.dots[0], self.dots[1])
62 elif pos:
63 pygame.draw.circle(scr, self.color, pos, self.size)
64 if self.dots:
65 self.shape(scr, self.dots[0], pos)
66
67 class Polygon(Line):
68 def __init__(self, size=2):
69 '''size — размер точки при рисовании'''
70 Line.__init__(self, size)
71 self.ndots = 1000
72
73 def shape(self, scr, pos_unused, pos):
74 '''Нарисовать многоугольник, поле pos_unused не используется'''
75 if self.is_complete():
76 pygame.draw.polygon(scr, self.color, self.dots, self.size)
77 elif len(self.dots)>0:
78 pygame.draw.lines(scr, self.color, False, self.dots+[pos], self.size)
79
80 def complete(self):
81 '''Если точек больше двух, считать многоугольник готовым'''
82 if len(self.dots)>2:
83 self.ndots = len(self.dots)
84
85 class Circle(Line):
86 '''Окружность'''
87 def shape(self, scr, pos1, pos2):
88 '''Нарисовать окружность с центром в pos1 и проходящую черех pos2'''
89 r=sqrt((pos1[0]-pos2[0])**2+(pos1[1]-pos2[1])**2)
90 pygame.draw.circle(scr, self.color, pos1, int(r>self.size and r or self.size), self.size)
91
92 class Square(Line):
93 '''Квадрат'''
94 def shape(self, scr, pos1, pos2):
95 '''Нарисовать крадрат с диагональю pos1 - pos2'''
96 cx, cy = (pos1[0]+pos2[0])/2, (pos1[1]+pos2[1])/2
97 pos3 = cx+cy-pos1[1], cy+pos1[0]-cx
98 pos4 = cx+pos1[1]-cy, cy+cx-pos1[0]
99 pygame.draw.line(scr, self.color, pos1, pos3, self.size)
100 pygame.draw.line(scr, self.color, pos3, pos2, self.size)
101 pygame.draw.line(scr, self.color, pos2, pos4, self.size)
102 pygame.draw.line(scr, self.color, pos4, pos1, self.size)
103
104 class ColorChooser:
105 '''Панель выбора цвета'''
106 color = (0,0,0)
107 def draw(self, scr, pos=None):
108 '''Отобразить панель цветов'''
109 sz, fr = 25, 20
110 c = pygame.Color(0,0,0)
111 grect = scr.get_rect().inflate(-2*fr,-2*fr)
112 sx, sy = grect.w/sz, grect.h/sz
113 ds = dl = int(sqrt(grect.w/sz))
114 for y in xrange(sy):
115 for x in xrange(ds*dl):
116 H = y*360/(sy-1)
117 S = (x%ds)*100/(ds-1)
118 L = (x/ds)*100/(dl-1)
119 #print H,S,L, x,sx
120 c.hsla = H,S,L,100
121 scr.fill(c, (fr+x*sz, fr+y*sz, sz, sz))
122 scr.fill(self.color, (fr, fr, sz, sz))
123
124 def Edit(event):
125 '''Основной режим работы'''
126 global Mainloop, figures, debug, nearfig, neardot
127 if debug:
128 print event
129 if event.type == pygame.MOUSEMOTION:
130 if event.buttons[0] and nearfig:
131 i=nearfig.dots.index(neardot)
132 neardot=nearfig.dots[i]=event.pos
133 else:
134 nearfig, neardot = GetNear(event.pos)
135 elif event.type == pygame.MOUSEBUTTONDOWN:
136 nearfig, neardot = GetNear(event.pos)
137 elif event.type == pygame.KEYDOWN:
138 if event.unicode in Constructors:
139 figures.append(Constructors[event.unicode]())
140 Mainloop = FigureEdit
141 pygame.mouse.set_visible(False)
142 elif event.unicode == u' ':
143 figures.append(ColorChooser())
144 Mainloop = ColorChoose
145 elif event.key == pygame.K_F1:
146 debug = not debug
147 return None
148
149 def ColorChoose(event):
150 '''Режим выбора цвета'''
151 global color, Mainloop, figures, debug
152 if event.type == pygame.MOUSEMOTION:
153 figures[-1].color=screen.get_at(event.pos)
154 if event.type == pygame.MOUSEBUTTONDOWN:
155 color = screen.get_at(event.pos)
156 figures.pop()
157 Mainloop = Edit
158
159 def FigureEdit(event):
160 '''Режим ввода фигуры'''
161 global pos, Mainloop, figures
162 if event.type == pygame.MOUSEMOTION:
163 pos = event.pos
164 elif event.type == pygame.MOUSEBUTTONDOWN:
165 pos = event.pos
166 if figures:
167 figures[-1].append(pos)
168 if event.button != 1 and hasattr(figures[-1], 'complete'):
169 figures[-1].complete()
170 if not figures or figures[-1].is_complete():
171 Mainloop = Edit
172 pygame.mouse.set_visible(True)
173 return pos
174
175 def GetNear(pos):
176 '''Возвращает фигуру и точку в ней, ближайшую к pos.
177 None,None — если все точки слишком далеко'''
178 f, d = None, None
179 alldots = [((pos[0]-x)**2+(pos[1]-y)**2,f,(x,y)) for f in figures if hasattr(f,'dots')for x,y in f.dots]
180 if alldots:
181 l, f, d = min(alldots)
182 return f, d
183
184 Constructors={'d': Dot, 'l': Line, 'c': Circle, 's': Square, 'p': Polygon }
185
186 def Redraw(scr, pos):
187 '''Нарисовать поле сфигурами, координаты курсора — pos'''
188 scr.fill(black)
189 for figure in figures:
190 figure.draw(scr, pos)
191 if nearfig:
192 pygame.draw.circle(scr, black, neardot, 5)
193 pygame.draw.circle(scr, tan, neardot, 4)
194
195 size = width, height = 1000,700
196
197 screen = pygame.display.set_mode(size)
198
199 figures,Mainloop=[],Edit
200 nearfig, neardot = None, None
201 pos, again, debug = None, True, False
202 while again:
203 event = pygame.event.wait()
204 # Общие события
205 if event.type == pygame.QUIT:
206 again = False
207 Mainloop(event)
208 Redraw(screen, pos)
209 pygame.display.flip()
Прикреплённые файлы
Для ссылки на прикреплённый файл в тексте страницы напишите attachment:имяфайла, как показано ниже в списке файлов. Не используйте URL из ссылки «[получить]», так как он чисто внутренний и может измениться.- [получить | показать] (2013-12-27 11:30:53, 0.6 KB) [[attachment:2013-12-20-anna.py]]
- [получить | показать] (2013-12-27 11:31:26, 0.9 KB) [[attachment:2013-12-20-anna2.py]]
- [получить | показать] (2013-12-27 11:31:31, 7.4 KB) [[attachment:2013-12-20-greditor.py]]
Вам нельзя прикреплять файлы к этой странице.