Attachment '2013-12-13-greditor2.py'

Download

   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 Polynom(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         # TODO текущий цвет
 110         step, num, fr = 25, 0, 20
 111         w, h = scr.get_rect().w-2*fr, scr.get_rect().h-2*fr
 112         sz = int(sqrt((w*h)/(255/step+1)**3))
 113         for R in xrange(0,255,step):
 114             for G in xrange(0,255,step):
 115                 for B in xrange(0,255,step):
 116                     num+=1
 117                     x, y = fr+sz*(num%(w/sz)), fr+sz*(num/(w/sz))
 118                     scr.fill((R,G,B),(x,y,sz,sz))
 119         scr.fill(self.color, (fr, fr, sz, sz))
 120 
 121 def Edit(event):
 122     '''Основной режим работы'''
 123     global Mainloop, figures, debug
 124     if debug:
 125         print event
 126     if event.type == pygame.KEYDOWN:
 127         if event.unicode in Constructors:
 128             figures.append(Constructors[event.unicode]())
 129             Mainloop = FigureEdit
 130             pygame.mouse.set_visible(False)
 131         elif event.unicode == u' ':
 132             figures.append(ColorChooser())
 133             Mainloop = ColorChoose
 134         elif event.key == pygame.K_F1:
 135             debug = not debug
 136     return None
 137 
 138 def ColorChoose(event):
 139     '''Режим выбора цвета'''
 140     global color, Mainloop, figures, debug
 141     if event.type == pygame.MOUSEMOTION:
 142         figures[-1].color=screen.get_at(event.pos)
 143     if event.type == pygame.MOUSEBUTTONDOWN:
 144         color = screen.get_at(event.pos)
 145         figures.pop()
 146         Mainloop = Edit
 147 
 148 def FigureEdit(event):
 149     '''Режим ввода фигуры'''
 150     global pos, Mainloop, figures
 151     if event.type == pygame.MOUSEMOTION:
 152         pos = event.pos
 153     elif event.type == pygame.MOUSEBUTTONDOWN:
 154         pos = event.pos
 155         if figures:
 156             figures[-1].append(pos)
 157         if event.button != 1 and hasattr(figures[-1], 'complete'):
 158             figures[-1].complete()
 159     if not figures or figures[-1].is_complete():
 160         Mainloop = Edit
 161         pygame.mouse.set_visible(True)
 162     return pos
 163 
 164 Constructors={'d': Dot, 'l': Line, 'c': Circle, 's': Square, 'p': Polynom }
 165 
 166 def Redraw(scr, pos):
 167     '''Нарисовать поле сфигурами, координаты курсора — pos'''
 168     scr.fill(black)
 169     for figure in figures:
 170         figure.draw(scr, pos)
 171 
 172 size = width, height = 1000,700
 173 
 174 screen = pygame.display.set_mode(size)
 175 
 176 figures,Mainloop=[],Edit
 177 pos, again, debug = None, True, False
 178 while again:
 179     event = pygame.event.wait()
 180     # Общие события
 181     if event.type == pygame.QUIT:
 182         again = False
 183     Mainloop(event)
 184     Redraw(screen, pos)
 185     pygame.display.flip()

Attached Files

To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.

You are not allowed to attach a file to this page.