segment
[e-sieve] / scale_sieve / ScaleSieve.py
1 from random import randint, randrange, choice
2
3 from pygame import Surface, PixelArray
4
5 from scale_sieve.pgfw.Game import Game
6 from scale_sieve.pgfw.GameChild import GameChild
7 from scale_sieve.pgfw.Sprite import Sprite
8
9 class ScaleSieve(Game):
10
11 def __init__(self):
12 Game.__init__(self)
13 self.background = Surface(self.display.screen.get_size())
14 self.background.fill((255, 80, 190))
15
16 def set_children(self):
17 Game.set_children(self)
18 self.sieve = Sieve(self)
19 self.triangles = Triangles(self)
20
21 def update(self):
22 self.display.screen.blit(self.background, (0, 0))
23 self.triangles.update()
24 self.sieve.update()
25
26
27 class Strip(Sprite):
28
29 LEFT, RIGHT = range(2)
30
31 def __init__(self, parent):
32 Sprite.__init__(self, parent)
33 self.display_surface = self.get_display_surface()
34 self.delegate = self.get_game().delegate
35 self.shifts = Shift(self, 1), Shift(self, -1)
36 self.shift_nodeset = self.get_game().interpolator.get_nodeset("shift")
37 self.add_frames()
38 self.subscribe(self.respond)
39
40 def add_frames(self):
41 pass
42
43 def respond(self, event):
44 compare = self.delegate.compare
45 if compare(event, "left") or compare(event, "left", True):
46 self.shifts[self.LEFT].active = not event.cancel
47 elif compare(event, "right") or compare(event, "right", True):
48 self.shifts[self.RIGHT].active = not event.cancel
49
50 def update(self):
51 for shift in self.shifts:
52 shift.update()
53 if shift.time:
54 self.move(shift.get_dx())
55 # if self.location.left > 0:
56 # self.location.left = 0
57 # self.shifts[self.LEFT].time = 0
58 # elif self.location.right < self.display_surface.get_width():
59 # self.location.right = self.display_surface.get_width()
60 # self.shifts[self.RIGHT].time = 0
61 Sprite.update(self)
62
63
64 class Shift(GameChild):
65
66 def __init__(self, parent, direction):
67 GameChild.__init__(self, parent)
68 self.direction = direction
69 self.active = False
70 self.time = 0
71 self.timer = self.get_game().time_filter
72 self.nodeset = self.get_game().interpolator.get_nodeset("shift-2")
73
74 def update(self):
75 least, greatest = self.nodeset[0].x, self.nodeset[-1].x
76 if self.active and self.time < greatest:
77 self.time = min(self.time + self.timer.get_last_frame_duration(),
78 greatest)
79 elif not self.active and self.time > least:
80 self.time = max(self.time - self.timer.get_last_frame_duration(),
81 least)
82
83 def get_dx(self):
84 return self.nodeset.get_y(self.time) * self.direction
85
86
87 class Sieve(Strip):
88
89 def __init__(self, parent):
90 Strip.__init__(self, parent)
91 self.location.center = self.display_surface.get_rect().center
92 self.electric = Electric(self)
93 self.add_location(offset=(self.location.w, 0))
94
95 def add_frames(self):
96 bar_locations = []
97 x = 0
98 nodeset = self.get_game().interpolator.get_nodeset("scale")
99 self.bar_w = bar_w = 3
100 self.gaps = gaps = []
101 while x < nodeset[-1].x:
102 bar_locations.append(x)
103 gaps.append(nodeset.get_y(x, natural=True))
104 x += gaps[-1]
105 surface = Surface((x, 30))
106 transparent_color = (255, 0, 255)
107 surface.fill(transparent_color)
108 surface.set_colorkey(transparent_color)
109 frames = surface, surface.copy()
110 colors = (0, 255, 0), (153, 0, 204)
111 for x in bar_locations:
112 for ii, frame in enumerate(frames):
113 frame.fill(colors[ii], (x, 0, bar_w, surface.get_height()))
114 frame.fill(colors[ii - 1], (x + 1, 1, 1,
115 surface.get_height() - 2))
116 for frame in frames:
117 self.add_frame(frame)
118
119 def update(self):
120 if self.location.left > 0:
121 self.move(-self.location.w)
122 if self.locations[1].right < self.display_surface.get_width():
123 self.move(self.location.w)
124 self.electric.location.centery = self.location.centery
125 self.electric.update()
126 Strip.update(self)
127
128
129 class Electric(Sprite):
130
131 def __init__(self, parent):
132 Sprite.__init__(self, parent)
133 self.display_surface = self.get_display_surface()
134 self.add_frames()
135
136 def add_frames(self):
137 surface = Surface((self.display_surface.get_width(),
138 self.parent.location.h - 10))
139 frames = surface, surface.copy()
140 colors = (255, 255, 0), (100, 89, 213)
141 pixel_arrays = PixelArray(frames[0]), PixelArray(frames[1])
142 for x in xrange(len(pixel_arrays[0])):
143 for y in xrange( len(pixel_arrays[0][0])):
144 pixel_arrays[0][x][y] = colors[(y + x) % 2]
145 pixel_arrays[1][x][y] = colors[(y + x + 1) % 2]
146 for pixels in pixel_arrays:
147 del pixels
148 for frame in frames:
149 self.add_frame(frame)
150
151
152 class Triangles(GameChild, list):
153
154 def __init__(self, parent):
155 GameChild.__init__(self, parent)
156 list.__init__(self, [])
157 self.set_next_gap()
158
159 def set_next_gap(self):
160 self.next_gap = randint(128, 512)
161
162 def update(self):
163 if not self or self[-1].location.top > self.next_gap:
164 self.append(Triangle(self))
165 self.set_next_gap()
166 if self[0].location.collidelist(self.parent.sieve.locations) != -1:
167 self.remove(self[0])
168 for triangle in self:
169 triangle.update()
170
171
172 class Triangle(Sprite):
173
174 def __init__(self, parent):
175 Sprite.__init__(self, parent)
176 mark = randint(64, 256)
177 sieve = self.parent.parent.sieve
178 gaps = sieve.gaps
179 start = randrange(0, len(gaps))
180 widths = [gaps[start]]
181 while sum(widths) < mark:
182 widths.append(gaps[(start + len(widths)) % len(gaps)])
183 surface = Surface((sum(widths), 20))
184 transparent_color = (255, 0, 255)
185 surface.fill(transparent_color)
186 surface.set_colorkey(transparent_color)
187 x = 0
188 margin = 6
189 for width in widths:
190 surface.fill((102, 82, 99), (x + sieve.bar_w + margin / 2, 0,
191 width - sieve.bar_w - margin,
192 surface.get_height()))
193 x += width
194 self.add_frame(surface)
195 self.location.centerx = self.get_display_surface().get_rect().centerx
196
197 def update(self):
198 self.move(dy=1)
199 Sprite.update(self)