gate
[hoa] / hair_on_arm / HairOnArm.py
index e8bb915..5686349 100644 (file)
@@ -2,11 +2,14 @@
 
 from random import randint, randrange, random, choice
 from math import pi, sin, cos, atan, copysign, sqrt
+from os import listdir
+from os.path import join
 
 from pygame import Rect, Surface
-from pygame.draw import line, circle
+from pygame.draw import line, circle, polygon, aaline
 from pygame.mixer import find_channel, Sound, set_num_channels
 from pygame.font import Font
+from pygame.image import load, save
 from pygame.locals import *
 
 from hair_on_arm.pgfw.Game import Game
@@ -24,6 +27,7 @@ class HairOnArm(Game):
 
     def set_children(self):
         Game.set_children(self)
+        self.gate = Gate(self)
         self.title = Title(self)
         self.tour = Tour(self)
 
@@ -37,7 +41,7 @@ class Title(GameChild):
     def __init__(self, parent):
         GameChild.__init__(self, parent)
         self.delegate = self.get_game().delegate
-        self.menu = Menu(self, (500, 350), 18,
+        self.menu = Menu(self, (500, 400), 18,
                          ("level", self.start, ["all"] + range(1, 11), True,
                           self.set_gate_index),
                          ("invert", self.set_invert, ("off", "on"), True),
@@ -50,7 +54,9 @@ class Title(GameChild):
         self.deactivate()
 
     def set_gate_index(self, index):
-        print "set gate " + str(index)
+        if index == "all":
+            index = 0
+        self.parent.gate.set_image_index(index - 1)
 
     def set_invert(self, invert):
         self.parent.invert = False if invert == "off" else True
@@ -74,6 +80,7 @@ class Title(GameChild):
 
     def update(self):
         self.get_display_surface().fill((255, 255, 0))
+        self.parent.gate.update()
         self.menu.update()
 
 
@@ -228,7 +235,7 @@ class Tour(GameChild):
         self.nodes = [Node(self) for _ in xrange(12)]
         self.loops = [Loop(self, choice(range(8, 12))) for _ in xrange(16)]
         self.drums = Sound(self.get_resource("audio", "plastic"))
-        self.drums.set_volume(.65)
+        self.drums.set_volume(.85)
         self.subscribe(self.respond)
         self.deactivate()
 
@@ -293,7 +300,11 @@ class Tour(GameChild):
             line(ds, (255, 255, 0), (cx, cy), (cx + x * 25, cy + y * 25), 1)
             for node in self.nodes:
                 node.rotate(x, y, max_magnitude)
+            drawn = False
             for node in sorted(self.nodes, key=lambda n: n.z):
+                if node.z >= 0 and not drawn:
+                    self.parent.gate.update()
+                    drawn = True
                 node.update()
             self.music_elapsed += self.get_game().time_filter. \
                                   get_last_frame_duration()
@@ -420,3 +431,90 @@ class Loop(Samples):
                         break
                     ii += 1
         return samples
+
+
+class Gate(Animation):
+
+    def __init__(self, parent):
+        Animation.__init__(self, parent, self.show_next_image, 200)
+        self.display_surface = ds = self.get_display_surface()
+        root = self.get_resource("image", "gate")
+        self.images = images = []
+        for name in sorted(listdir(root)):
+            images.append(load(join(root, name)))
+        self.image_index = 0
+        self.image_rect = image_rect = images[0].get_rect()
+        image_rect.center = ds.get_rect().center
+        bevel_width = 2
+        frame_width = 3
+        border_width = 1
+        self.border = border = Sprite(self, 200)
+        for ii in xrange(3):
+            inflation = bevel_width * 2 + frame_width * 2 + border_width * 2
+            surface = Surface(image_rect.inflate(inflation, inflation).size)
+            surface.fill(((255, 255, 0), (255, 0, 0), (34, 139, 34))[ii])
+            border.add_frame(surface)
+        border.location.center = image_rect.center
+        self.frame_background = load(self.get_resource("image", "hand"))
+        inflation = bevel_width * 2 + frame_width * 2
+        self.frame_surface = Surface(image_rect.inflate(inflation, inflation). \
+                                     size)
+        self.frame_rect = self.frame_surface.get_rect()
+        self.frame_rect.center = image_rect.center
+        self.frame_background_offset = 0
+        self.bevel_surface = Surface(image_rect.inflate(bevel_width * 2,
+                                                        bevel_width * 2).size)
+        self.bevel_rect = self.bevel_surface.get_rect()
+        self.bevel_rect.center = image_rect.center
+        self.bevel_surface.fill((150, 212, 150))
+        points = (0, 0), (self.bevel_rect.w - 1, 0), (0, self.bevel_rect.h - 1)
+        polygon(self.bevel_surface, (40, 120, 40), points)
+        aaline(self.bevel_surface, (150, 212, 150), (0, self.bevel_rect.h - 1),
+               (self.bevel_rect.w - 1, 0))
+        save(self.bevel_surface, "/tmp/bevel_surface.png")
+        self.screen = screen = Sprite(self, 100)
+        screen.set_alpha(40)
+        components = []
+        for ii in xrange(3):
+            surface = Surface((4, 2))
+            surface.fill(((255, 0, 0), (0, 255, 0), (0, 0, 255))[ii])
+            components.append(surface)
+        component_rect = components[0].get_rect()
+        for frame_ii in xrange(3):
+            frame = Surface(image_rect.size)
+            for yi, y in enumerate(xrange(0, image_rect.h, component_rect.h)):
+                offset = (0, -2)[y % 2]
+                for xi, x in enumerate(xrange(offset, image_rect.w,
+                                              component_rect.w)):
+                    frame.blit(components[(frame_ii + yi + xi) % 3], (x, y))
+            screen.add_frame(frame)
+        screen.location.center = image_rect.center
+
+    def show_next_image(self):
+        self.image_index += 1
+        if self.image_index == len(self.images):
+            self.image_index = 0
+
+    def set_image_index(self, index):
+        if index == -1:
+            self.play()
+        else:
+            self.halt()
+            self.image_index = index
+
+    def update(self):
+        Animation.update(self)
+        self.border.update()
+        self.frame_background_offset -= 2
+        if self.frame_background_offset < -self.frame_background.get_width():
+            self.frame_background_offset += self.frame_background.get_width()
+        self.frame_surface.blit(self.frame_background,
+                                (self.frame_background_offset, 0))
+        self.frame_surface.blit(self.frame_background,
+                                (self.frame_background_offset + \
+                                 self.frame_background.get_width(), 0))
+        self.display_surface.blit(self.frame_surface, self.frame_rect)
+        self.display_surface.blit(self.bevel_surface, self.bevel_rect)
+        self.display_surface.blit(self.images[self.image_index],
+                                  self.image_rect)
+        self.screen.update()