Skip to content

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
  • 9 commits
  • 5 files changed
  • 0 commit comments
  • 2 contributors
Showing with 556 additions and 439 deletions.
  1. +6 −2 README
  2. +223 −0 advanced_effects.py
  3. +18 −426 effects.py
  4. +274 −0 more_effects.py
  5. +35 −11 run.py
View
8 README
@@ -36,6 +36,10 @@ and height of the wall, pass the -w and -t options, e.g.:
python run.py -w 5 -t 10
-To run only specific effects, pass the effect names on the commandline. e.g.:
+To run advanced effects, pass the -a option, e.g.:
-python run.py Rainbow Twinkle KnightMoves
+python run.py -a
+
+To run only the advanced effects, pass the -a and -s options, e.g.:
+
+python run.py -a -s
View
223 advanced_effects.py
@@ -0,0 +1,223 @@
+import random
+import time
+from effects import colors
+
+"""
+advanced_effects use a class hierarchy to run on the wall.
+"""
+
+class Effect(object):
+ def __init__(self, wall):
+ self.wall = wall
+ self.wall.clear()
+
+ def run(self):
+ pass
+
+class KnightMoves(Effect):
+ def __init__(self, wall):
+ self.wall = wall
+ self.wall.clear()
+ for x in range(self.wall.width):
+ for y in range(self.wall.height):
+ if (x + y) % 2 == 0:
+ self.wall.set_pixel(x, y, colors["black"])
+ else:
+ self.wall.set_pixel(x, y, colors["white"])
+ # Pick a random starting location for the knight
+ self.knight_x = random.randint(0, self.wall.width - 1)
+ self.knight_y = random.randint(0, self.wall.height - 1)
+ self.wall.set_pixel(self.knight_x, self.knight_y, colors["red"])
+
+ def run(self):
+ if self.wall.width < 2 or self.wall.height < 2:
+ return
+
+ self.wall.draw()
+ start_time = time.time()
+ while time.time() - start_time < 12:
+ self.move()
+ self.wall.draw()
+ time.sleep(0.75)
+
+ def move(self):
+ """
+ Move the knight.
+ """
+ if (self.knight_x + self.knight_y) % 2 == 0:
+ self.wall.set_pixel(self.knight_x, self.knight_y, colors["black"])
+ else:
+ self.wall.set_pixel(self.knight_x, self.knight_y, colors["white"])
+ moves = self.getMoves()
+ # Select a move at random from the possible moves
+ self.knight_x, self.knight_y = moves[random.randint(0, len(moves) - 1)]
+ self.wall.set_pixel(self.knight_x, self.knight_y, colors["red"])
+
+ def getMoves(self):
+ """
+ Get all possible moves that the knight can make.
+ """
+ moves = []
+ # Don't want knight to wrap around the board because you can't
+ # do that in chess
+ if (self.knight_x - 2) >= 0 and (self.knight_y - 1) >= 0:
+ moves.append((self.knight_x - 2, self.knight_y - 1))
+ if (self.knight_x - 1) >= 0 and (self.knight_y - 2) >= 0:
+ moves.append((self.knight_x - 1, self.knight_y - 2))
+ if (self.knight_x - 2) >= 0 and (self.knight_y + 1) < self.wall.height:
+ moves.append((self.knight_x - 2, self.knight_y + 1))
+ if (self.knight_x + 1) < self.wall.width and (self.knight_y - 2) >= 0:
+ moves.append((self.knight_x + 1, self.knight_y - 2))
+ if (self.knight_x - 1) >= 0 and (self.knight_y + 2) < self.wall.height:
+ moves.append((self.knight_x - 1, self.knight_y + 2))
+ if (self.knight_x + 2) < self.wall.width and (self.knight_y - 1) >= 0:
+ moves.append((self.knight_x + 2, self.knight_y - 1))
+ if (self.knight_x + 2) < self.wall.width and \
+ (self.knight_y + 1) < self.wall.height:
+ moves.append((self.knight_x + 2, self.knight_y + 1))
+ if (self.knight_x + 1) < self.wall.width and \
+ (self.knight_y + 2) < self.wall.height:
+ moves.append((self.knight_x + 1, self.knight_y + 2))
+ return moves
+
+class Matrix(Effect):
+ class Column(object):
+ def __init__(self, wall):
+ self.wall = wall
+ self.cache = []
+ # Tail must be at least 1 pixel long
+ self.tail = max(1, random.randint(
+ self.wall.height / 2, self.wall.height * 2))
+ # Get a position somewhere above the wall (so it can trickle down
+ # onto the wall)
+ self.pos = (random.randint(0, self.wall.width - 1),
+ random.randint(-(self.wall.height * 3), 0))
+ self.green = .35
+
+ def step(self):
+ """
+ Advance the location of the head of the column and all pixels in the
+ tail.
+ """
+ self.cache.append(self.pos)
+ self.cache = self.cache[-self.tail:]
+ self.pos = [self.pos[0], self.pos[1] + 1]
+
+ def inside_wall(self, x, y, wall):
+ if x >= 0 and x < wall.width and y >= 0 and y < wall.height:
+ return True
+ return False
+
+ def draw(self, wall):
+ """
+ Set the pixel colors in this column for this step.
+
+ Returns the number of pixels making up this column that were
+ actually within the scope of the wall.
+ """
+ draw_cnt = 0
+ # Prepare the tail colors. The further from the head, the dimmer the
+ # pixel.
+ for index, pos in enumerate(self.cache):
+ x = pos[0]
+ y = pos[1]
+ if self.inside_wall(x, y, wall):
+ hsv = (self.green, 1, float(index)/self.tail)
+ wall.set_pixel(x, y, hsv)
+ draw_cnt += 1
+
+ # Prepare the head color
+ x = self.pos[0]
+ y = self.pos[1]
+ if self.inside_wall(x, y, wall):
+ hsv = (self.green, 1, 1)
+ wall.set_pixel(x, y, hsv)
+ draw_cnt += 1
+
+ return draw_cnt
+
+ def run(self):
+ cols = []
+ # Initialize 15 - 30 Matrix columns.
+ for i in range(random.randint(15, 30)):
+ col = self.Column(self.wall)
+ cols.append(col)
+ # Run the columns down the wall.
+ self.draw(cols)
+
+ def draw(self, cols):
+ """
+ Draw the advancing columns until no parts of any columns are left on the
+ wall.
+ """
+ timeout = 4
+ drawing = 0
+ while drawing or timeout:
+ self.wall.clear()
+ for col in cols:
+ col.step()
+ drawing += col.draw(self.wall)
+ self.wall.draw()
+ time.sleep(.05)
+ if not drawing:
+ timeout -= 1
+ drawing = 0
+
+class Bouncer(Effect):
+ class Ball(object):
+ def __init__(self, wall):
+ self.wall = wall
+ self.x = random.randint(0, self.wall.width - 1)
+ self.y = random.randint(0, self.wall.height - 1)
+ self.hue = random.random()
+ self.dx = self.dy = 0
+ while self.dx == 0 and self.dy == 0:
+ self.dx = random.choice([-1, 0, 1])
+ self.dy = random.choice([-1, 0, 1])
+ self.tail = []
+ self.tail_len = 4
+
+ def draw(self):
+ self.wall.set_pixel(self.x, self.y, (self.hue, 1, 1))
+ value = 0.6
+ val_step = float(value/(self.tail_len+1))
+ for x, y in self.tail:
+ value -= val_step
+ self.wall.set_pixel(x, y, (self.hue, 1, value))
+
+ def advance(self):
+ self.tail = [(self.x, self.y)] + self.tail[:self.tail_len-1]
+ self.x += self.dx
+ if self.x < 0:
+ self.x = 1
+ self.dx = -self.dx
+ elif self.x >= self.wall.width:
+ self.x = self.wall.width - 2
+ self.dx = -self.dx
+
+ self.y += self.dy
+ if self.y < 0:
+ self.y = 1
+ self.dy = -self.dy
+ elif self.y >= self.wall.height:
+ self.y = self.wall.height - 2
+ self.dy = -self.dy
+
+ def run(self):
+ if self.wall.width < 2 or self.wall.height < 2:
+ return
+
+ balls = []
+ for i in range(3):
+ balls.append(self.Ball(self.wall))
+
+ start_time = time.time()
+ while time.time() - start_time < 5:
+ self.wall.clear()
+ for ball in balls:
+ ball.draw()
+ ball.advance()
+ self.wall.draw()
+ time.sleep(.1)
+
+Effects = [Matrix, Bouncer]
View
444 effects.py
@@ -1,6 +1,4 @@
-import random
import time
-import ascii8x8
# A dictionary of hsv values for some common colors.
colors = {"black":(0, 0, 0), "white":(0, 0, 1), "gray":(0, 0, 0.5),
@@ -13,432 +11,26 @@
"light gray":(0, 0, 0.75), "maroon":(0, 1, 0.5),
"navy":(0.66, 1, 0.25)}
-class Effect(object):
- def __init__(self, wall):
- self.wall = wall
- self.wall.clear()
+def SolidColorTest(wall):
+ print "SolidColorTest"
- def run(self):
- pass
+ color = colors["blue"]
+ for x in range(wall.width):
+ for y in range(wall.height):
+ wall.set_pixel(x, y, color)
-class SolidColorTest(Effect):
- def run(self):
- hue = 1
- saturation = 1
- value = 1
+ wall.draw()
+ time.sleep(2)
- hsv = (hue, saturation, value)
- for x in range(self.wall.width):
- for y in range(self.wall.height):
- self.wall.set_pixel(x, y, hsv)
+def DictionaryTest(wall):
+ print "DictionaryTest"
- self.wall.draw()
- time.sleep(2)
+ for color in colors.keys():
+ for x in range(wall.width):
+ for y in range(wall.height):
+ wall.set_pixel(x, y, colors[color])
+ wall.draw()
+ time.sleep(0.5)
-class HueTest(Effect):
- def run(self):
- hue = random.random()
- start_time = time.time()
- while time.time() - start_time < 5:
- hsv = (hue, 1, 1)
- for x in range(self.wall.width):
- for y in range(self.wall.height):
- self.wall.set_pixel(x, y, hsv)
- self.wall.draw()
- hue = (hue + .01) % 1
- time.sleep(.05)
-
-class SaturationTest(Effect):
- def run(self):
- hue = random.random()
- saturation = 0
- start_time = time.time()
- while time.time() - start_time < 5:
- hsv = (hue, saturation, 1)
- for x in range(self.wall.width):
- for y in range(self.wall.height):
- self.wall.set_pixel(x, y, hsv)
- self.wall.draw()
- saturation = (saturation + .05) % 1
- time.sleep(.05)
-
-class ValueTest(Effect):
- def run(self):
- hue = random.random()
- value = 0
- start_time = time.time()
- while time.time() - start_time < 5:
- hsv = (hue, 1, value)
- for x in range(self.wall.width):
- for y in range(self.wall.height):
- self.wall.set_pixel(x, y, hsv)
- self.wall.draw()
- value = (value + .05) % 1
- time.sleep(.05)
-
-class DictionaryTest(Effect):
- def run(self):
- for color in colors.keys():
- for x in range(self.wall.width):
- for y in range(self.wall.height):
- self.wall.set_pixel(x, y, colors[color])
- self.wall.draw()
- time.sleep(0.5)
-
-class Checkerboards(Effect):
- def run(self):
- for i in range(10):
- for x in range(self.wall.width):
- for y in range(self.wall.height):
- if (x + y + i) % 2 == 0:
- self.wall.set_pixel(x, y, colors["black"])
- else:
- self.wall.set_pixel(x, y, colors["yellow"])
- self.wall.draw()
- time.sleep(0.5)
-
-class Columns(Effect):
- def run(self):
- hue = random.random()
- start_time = time.time()
- while time.time() - start_time < 5:
- for x in range(self.wall.width):
- for y in range(self.wall.height):
- hsv = (hue, 1, 1)
- self.wall.set_pixel(x, y, hsv)
- self.wall.draw()
- time.sleep(.02)
- self.wall.clear()
- hue = (hue + .05) % 1
-
-class Rainbow(Effect):
- def run(self):
- hue = random.random()
- hue_spacing = 1.0/(self.wall.width * self.wall.height)
- delay = .1
-
- # Draw rainbow stripes from right to left.
- for i in range(self.wall.width - 1, -1, -1):
- for j in range(self.wall.height - 1, -1, -1):
- hsv = (hue, 1, 1)
- self.wall.set_pixel(i, j, hsv)
- hue += hue_spacing
- # on python 2.5, having a hue value of > 1 will return None
- # when you try to convert HSV to RGB using colorsys
- #
- # in later versions, colorsys will treat a hue value of
- # > 1 as *just the truncated fractional part*, e.g.
- # 1.29 becomes 0.29.
- #
- # neither of these particularly make sense, but let's
- # emulate the behaviour of python 2.6+ here for compatibility's
- # sake.
- if hue > 1:
- hue -= int(hue)
- time.sleep(delay)
- self.wall.draw()
-
- time.sleep(1)
-
- # Shift the wall hues for a few seconds.
- start_time = time.time()
- while time.time() - start_time < 5:
- for i in range(self.wall.width):
- for j in range(self.wall.height):
- hsv = self.wall.get_pixel(i, j)
- new_hue = (hsv[0] + hue_spacing/4) % 1
- new_hsv = (new_hue, hsv[1], hsv[2])
- self.wall.set_pixel(i, j, new_hsv)
- self.wall.draw()
-
- time.sleep(1)
-
-
-class Twinkle(Effect):
- def run(self):
- start_time = time.time()
- while time.time() - start_time < 5:
- x = random.randint(0, self.wall.width - 1)
- y = random.randint(0, self.wall.height - 1)
- # Stick to blueish colors.
- hue = .65 + random.uniform(-1, 1) * .1
- value = random.random()
- hsv = (hue, 1, value)
- self.wall.set_pixel(x, y, hsv)
- self.wall.draw()
- time.sleep(.01)
-
-class KnightMoves(Effect):
- def __init__(self, wall):
- self.wall = wall
- self.wall.clear()
- for x in range(self.wall.width):
- for y in range(self.wall.height):
- if (x + y) % 2 == 0:
- self.wall.set_pixel(x, y, colors["black"])
- else:
- self.wall.set_pixel(x, y, colors["white"])
- # Pick a random starting location for the knight
- self.knight_x = random.randint(0, self.wall.width - 1)
- self.knight_y = random.randint(0, self.wall.height - 1)
- self.wall.set_pixel(self.knight_x, self.knight_y, colors["red"])
-
- def run(self):
- if self.wall.width < 2 or self.wall.height < 2:
- return
-
- self.wall.draw()
- start_time = time.time()
- while time.time() - start_time < 12:
- self.move()
- self.wall.draw()
- time.sleep(0.75)
-
- def move(self):
- """
- Move the knight.
- """
- if (self.knight_x + self.knight_y) % 2 == 0:
- self.wall.set_pixel(self.knight_x, self.knight_y, colors["black"])
- else:
- self.wall.set_pixel(self.knight_x, self.knight_y, colors["white"])
- moves = self.getMoves()
- # Select a move at random from the possible moves
- self.knight_x, self.knight_y = moves[random.randint(0, len(moves) - 1)]
- self.wall.set_pixel(self.knight_x, self.knight_y, colors["red"])
-
- def getMoves(self):
- """
- Get all possible moves that the knight can make.
- """
- moves = []
- # Don't want knight to wrap around the board because you can't
- # do that in chess
- if (self.knight_x - 2) >= 0 and (self.knight_y - 1) >= 0:
- moves.append((self.knight_x - 2, self.knight_y - 1))
- if (self.knight_x - 1) >= 0 and (self.knight_y - 2) >= 0:
- moves.append((self.knight_x - 1, self.knight_y - 2))
- if (self.knight_x - 2) >= 0 and (self.knight_y + 1) < self.wall.height:
- moves.append((self.knight_x - 2, self.knight_y + 1))
- if (self.knight_x + 1) < self.wall.width and (self.knight_y - 2) >= 0:
- moves.append((self.knight_x + 1, self.knight_y - 2))
- if (self.knight_x - 1) >= 0 and (self.knight_y + 2) < self.wall.height:
- moves.append((self.knight_x - 1, self.knight_y + 2))
- if (self.knight_x + 2) < self.wall.width and (self.knight_y - 1) >= 0:
- moves.append((self.knight_x + 2, self.knight_y - 1))
- if (self.knight_x + 2) < self.wall.width and \
- (self.knight_y + 1) < self.wall.height:
- moves.append((self.knight_x + 2, self.knight_y + 1))
- if (self.knight_x + 1) < self.wall.width and \
- (self.knight_y + 2) < self.wall.height:
- moves.append((self.knight_x + 1, self.knight_y + 2))
- return moves
-
-class Matrix(Effect):
- class Column(object):
- def __init__(self, wall):
- self.wall = wall
- self.cache = []
- # Tail must be at least 1 pixel long
- self.tail = max(1, random.randint(
- self.wall.height / 2, self.wall.height * 2))
- # Get a position somewhere above the wall (so it can trickle down
- # onto the wall)
- self.pos = (random.randint(0, self.wall.width - 1),
- random.randint(-(self.wall.height * 3), 0))
- self.green = .35
-
- def step(self):
- """
- Advance the location of the head of the column and all pixels in the
- tail.
- """
- self.cache.append(self.pos)
- self.cache = self.cache[-self.tail:]
- self.pos = [self.pos[0], self.pos[1] + 1]
-
- def inside_wall(self, x, y, wall):
- if x >= 0 and x < wall.width and y >= 0 and y < wall.height:
- return True
- return False
-
- def draw(self, wall):
- """
- Set the pixel colors in this column for this step.
-
- Returns the number of pixels making up this column that were
- actually within the scope of the wall.
- """
- draw_cnt = 0
- # Prepare the tail colors. The further from the head, the dimmer the
- # pixel.
- for index, pos in enumerate(self.cache):
- x = pos[0]
- y = pos[1]
- if self.inside_wall(x, y, wall):
- hsv = (self.green, 1, float(index)/self.tail)
- wall.set_pixel(x, y, hsv)
- draw_cnt += 1
-
- # Prepare the head color
- x = self.pos[0]
- y = self.pos[1]
- if self.inside_wall(x, y, wall):
- hsv = (self.green, 1, 1)
- wall.set_pixel(x, y, hsv)
- draw_cnt += 1
-
- return draw_cnt
-
- def run(self):
- cols = []
- # Initialize 15 - 30 Matrix columns.
- for i in range(random.randint(15, 30)):
- col = self.Column(self.wall)
- cols.append(col)
- # Run the columns down the wall.
- self.draw(cols)
-
- def draw(self, cols):
- """
- Draw the advancing columns until no parts of any columns are left on the
- wall.
- """
- timeout = 4
- drawing = 0
- while drawing or timeout:
- self.wall.clear()
- for col in cols:
- col.step()
- drawing += col.draw(self.wall)
- self.wall.draw()
- time.sleep(.05)
- if not drawing:
- timeout -= 1
- drawing = 0
-
-class LetterTest(Effect):
- """
- Cycle through the letters of the alphabet.
-
- Minimum wall size: 8 x 8.
- """
- def run(self):
- if self.wall.width < 8 or self.wall.height < 8:
- return
-
- color = random.random()
- foreground = (color, 1, 1)
- # Make the foreground and background complementary colors.
- background = ((color + .5) % 1, 1, 1)
-
- # Center the letters on the wall
- x_offset = int((self.wall.width - 8) / 2)
- y_offset = int((self.wall.height - 8) / 2)
-
- # Display upper and lower case letters. The break between 90 and 97 is
- # for non-letter keyboard characters.
- for ord in range(65, 91) + range(97, 123):
- self.wall.clear()
-
- # Set every pixel to the background color, since ascii8x8 will only
- # color an 8x8 section.
- for x in range(self.wall.width):
- for y in range(self.wall.height):
- self.wall.set_pixel(x, y, background)
-
- # Color the letter.
- ascii8x8.draw_chr(chr(ord), self.wall, foreground, background,
- x_offset, y_offset)
- self.wall.draw()
- time.sleep(.1)
-
-class Bouncer(Effect):
- class Ball(object):
- def __init__(self, wall):
- self.wall = wall
- self.x = random.randint(0, self.wall.width - 1)
- self.y = random.randint(0, self.wall.height - 1)
- self.hue = random.random()
- self.dx = self.dy = 0
- while self.dx == 0 and self.dy == 0:
- self.dx = random.choice([-1, 0, 1])
- self.dy = random.choice([-1, 0, 1])
- self.tail = []
- self.tail_len = 4
-
- def draw(self):
- self.wall.set_pixel(self.x, self.y, (self.hue, 1, 1))
- value = 0.6
- val_step = float(value/(self.tail_len+1))
- for x, y in self.tail:
- value -= val_step
- self.wall.set_pixel(x, y, (self.hue, 1, value))
-
- def advance(self):
- self.tail = [(self.x, self.y)] + self.tail[:self.tail_len-1]
- self.x += self.dx
- if self.x < 0:
- self.x = 1
- self.dx = -self.dx
- elif self.x >= self.wall.width:
- self.x = self.wall.width - 2
- self.dx = -self.dx
-
- self.y += self.dy
- if self.y < 0:
- self.y = 1
- self.dy = -self.dy
- elif self.y >= self.wall.height:
- self.y = self.wall.height - 2
- self.dy = -self.dy
-
- def run(self):
- if self.wall.width < 2 or self.wall.height < 2:
- return
-
- balls = []
- for i in range(3):
- balls.append(self.Ball(self.wall))
-
- start_time = time.time()
- while time.time() - start_time < 5:
- self.wall.clear()
- for ball in balls:
- ball.draw()
- ball.advance()
- self.wall.draw()
- time.sleep(.1)
-
-class Message(Effect):
- message = [
- ' ',
- ' ** * * *** * * ** * * * ** ** ** ** * * * ',
- ' * * * * * * * * * ** * * * * * * * * * * * ',
- ' ** * * *** * * * ** * * * * * * * * * * ',
- ' * * * * * * * * * * * * * * * * * ',
- ' * * * * * ** * * * ** ** ** ** *** * * ',
- ]
-
- def run(self):
- if self.wall.height < 6 or self.wall.width < 2:
- return
-
- col = 0
- start_time = time.time()
- while time.time() - start_time < 10:
- self.wall.clear()
- for x in range(self.wall.width):
- for y in range(self.wall.height):
- if y >= len(self.message):
- break
- dot = self.message[y][(x+col) % len(self.message[0])]
- if dot != ' ':
- self.wall.set_pixel(x, y, (.333, 1, 1))
- self.wall.draw()
- col += 1
- time.sleep(0.07)
-
-Effects = [SolidColorTest, HueTest, SaturationTest, ValueTest, DictionaryTest,
- LetterTest, Checkerboards, Columns, Rainbow, Twinkle, KnightMoves,
- Matrix, Bouncer, Message]
+def RainbowTest(wall):
+ print "RainbowTest"
View
274 more_effects.py
@@ -0,0 +1,274 @@
+import ascii8x8
+import random
+import time
+from effects import colors
+
+def HueTest(wall):
+ print "HueTest"
+ wall.clear()
+
+ hue = 0
+ while hue < 1:
+ hsv = (hue, 1, 1)
+ for x in range(wall.width):
+ for y in range(wall.height):
+ wall.set_pixel(x, y, hsv)
+ wall.draw()
+ hue = hue + .01
+ time.sleep(.05)
+
+def SaturationTest(wall):
+ print "SaturationTest"
+ wall.clear()
+
+ hue = random.random()
+ saturation = 0
+ while saturation < 1:
+ hsv = (hue, saturation, 1)
+ for x in range(wall.width):
+ for y in range(wall.height):
+ wall.set_pixel(x, y, hsv)
+ wall.draw()
+ saturation = saturation + .01
+ time.sleep(.05)
+
+def ValueTest(wall):
+ print "ValueTest"
+ wall.clear()
+
+ hue = random.random()
+ value = 0
+ while value < 1:
+ hsv = (hue, 1, value)
+ for x in range(wall.width):
+ for y in range(wall.height):
+ wall.set_pixel(x, y, hsv)
+ wall.draw()
+ value = value + .01
+ time.sleep(.05)
+
+def Checkerboards(wall):
+ print "Checkerboards"
+ wall.clear()
+
+ for i in range(10):
+ for x in range(wall.width):
+ for y in range(wall.height):
+ if (x + y + i) % 2 == 0:
+ wall.set_pixel(x, y, colors["black"])
+ else:
+ wall.set_pixel(x, y, colors["yellow"])
+ wall.draw()
+ time.sleep(0.5)
+
+def Columns(wall):
+ print "Columns"
+ wall.clear()
+
+ hue = random.random()
+ start_time = time.time()
+ while time.time() - start_time < 5:
+ for x in range(wall.width):
+ for y in range(wall.height):
+ hsv = (hue, 1, 1)
+ wall.set_pixel(x, y, hsv)
+ wall.draw()
+ time.sleep(.02)
+ wall.clear()
+ hue = (hue + .05) % 1
+
+def Rainbow(wall):
+ print "Rainbow"
+ wall.clear()
+
+ hue = random.random()
+ hue_spacing = 1.0/(wall.width * wall.height)
+ delay = .1
+
+ # Draw rainbow stripes from right to left.
+ for i in range(wall.width - 1, -1, -1):
+ for j in range(wall.height - 1, -1, -1):
+ hsv = (hue, 1, 1)
+ wall.set_pixel(i, j, hsv)
+ hue += hue_spacing
+ # on python 2.5, having a hue value of > 1 will return None
+ # when you try to convert HSV to RGB using colorsys
+ #
+ # in later versions, colorsys will treat a hue value of
+ # > 1 as *just the truncated fractional part*, e.g.
+ # 1.29 becomes 0.29.
+ #
+ # neither of these particularly make sense, but let's
+ # emulate the behaviour of python 2.6+ here for compatibility's
+ # sake.
+ if hue > 1:
+ hue -= int(hue)
+ time.sleep(delay)
+ wall.draw()
+
+ time.sleep(1)
+
+ # Shift the wall hues for a few seconds.
+ start_time = time.time()
+ while time.time() - start_time < 5:
+ for i in range(wall.width):
+ for j in range(wall.height):
+ hsv = wall.get_pixel(i, j)
+ new_hue = (hsv[0] + hue_spacing/4) % 1
+ new_hsv = (new_hue, hsv[1], hsv[2])
+ wall.set_pixel(i, j, new_hsv)
+ wall.draw()
+
+ time.sleep(1)
+
+
+def Twinkle(wall):
+ print "Twinkle"
+ wall.clear()
+
+ start_time = time.time()
+ while time.time() - start_time < 5:
+ x = random.randint(0, wall.width - 1)
+ y = random.randint(0, wall.height - 1)
+ # Stick to blueish colors.
+ hue = .65 + random.uniform(-1, 1) * .1
+ value = random.random()
+ hsv = (hue, 1, value)
+ wall.set_pixel(x, y, hsv)
+ wall.draw()
+ time.sleep(.01)
+
+def KnightMoves(wall):
+ if wall.width < 2 or wall.height < 2:
+ return
+
+ print "KnightMoves"
+ wall.clear()
+
+ for x in range(wall.width):
+ for y in range(wall.height):
+ if (x + y) % 2 == 0:
+ wall.set_pixel(x, y, colors["black"])
+ else:
+ wall.set_pixel(x, y, colors["white"])
+ # Pick a random starting location for the knight
+ knight_x = random.randint(0, wall.width - 1)
+ knight_y = random.randint(0, wall.height - 1)
+ wall.set_pixel(knight_x, knight_y, colors["red"])
+ wall.draw()
+
+ def move(knight_x, knight_y):
+ """
+ Move the knight.
+ """
+
+ def getMoves(knight_x, knight_y):
+ """
+ Get all possible moves that the knight can make.
+ """
+ moves = []
+ # Don't want knight to wrap around the board because you can't
+ # do that in chess
+ if (knight_x - 2) >= 0 and (knight_y - 1) >= 0:
+ moves.append((knight_x - 2, knight_y - 1))
+ if (knight_x - 1) >= 0 and (knight_y - 2) >= 0:
+ moves.append((knight_x - 1, knight_y - 2))
+ if (knight_x - 2) >= 0 and (knight_y + 1) < wall.height:
+ moves.append((knight_x - 2, knight_y + 1))
+ if (knight_x + 1) < wall.width and (knight_y - 2) >= 0:
+ moves.append((knight_x + 1, knight_y - 2))
+ if (knight_x - 1) >= 0 and (knight_y + 2) < wall.height:
+ moves.append((knight_x - 1, knight_y + 2))
+ if (knight_x + 2) < wall.width and (knight_y - 1) >= 0:
+ moves.append((knight_x + 2, knight_y - 1))
+ if (knight_x + 2) < wall.width and \
+ (knight_y + 1) < wall.height:
+ moves.append((knight_x + 2, knight_y + 1))
+ if (knight_x + 1) < wall.width and \
+ (knight_y + 2) < wall.height:
+ moves.append((knight_x + 1, knight_y + 2))
+ return moves
+
+ start_time = time.time()
+ while time.time() - start_time < 12:
+ # Update the knight's position
+ if (knight_x + knight_y) % 2 == 0:
+ wall.set_pixel(knight_x, knight_y, colors["black"])
+ else:
+ wall.set_pixel(knight_x, knight_y, colors["white"])
+ moves = getMoves(knight_x, knight_y)
+ # Select a move at random from the possible moves
+ knight_x, knight_y = moves[random.randint(0, len(moves) - 1)]
+ wall.set_pixel(knight_x, knight_y, colors["red"])
+
+ wall.draw()
+ time.sleep(0.75)
+
+def LetterTest(wall):
+ """
+ Cycle through the letters of the alphabet.
+
+ Minimum wall size: 8 x 8.
+ """
+ print "LetterTest"
+ wall.clear()
+
+ if wall.width < 8 or wall.height < 8:
+ return
+
+ color = random.random()
+ foreground = (color, 1, 1)
+ # Make the foreground and background complementary colors.
+ background = ((color + .5) % 1, 1, 1)
+
+ # Center the letters on the wall
+ x_offset = int((wall.width - 8) / 2)
+ y_offset = int((wall.height - 8) / 2)
+
+ # Display upper and lower case letters. The break between 90 and 97 is
+ # for non-letter keyboard characters.
+ for ord in range(65, 91) + range(97, 123):
+ wall.clear()
+
+ # Set every pixel to the background color, since ascii8x8 will only
+ # color an 8x8 section.
+ for x in range(wall.width):
+ for y in range(wall.height):
+ wall.set_pixel(x, y, background)
+
+ # Color the letter.
+ ascii8x8.draw_chr(chr(ord), wall, foreground, background,
+ x_offset, y_offset)
+ wall.draw()
+ time.sleep(.1)
+
+def Message(wall):
+ print "Message"
+ wall.clear()
+
+ message = [
+ ' ',
+ ' ** * * *** * * ** * * * ** ** ** ** * * * ',
+ ' * * * * * * * * * ** * * * * * * * * * * * ',
+ ' ** * * *** * * * ** * * * * * * * * * * ',
+ ' * * * * * * * * * * * * * * * * * ',
+ ' * * * * * ** * * * ** ** ** ** *** * * ',
+ ]
+
+ if wall.height < 6 or wall.width < 2:
+ return
+
+ col = 0
+ start_time = time.time()
+ while time.time() - start_time < 10:
+ wall.clear()
+ for x in range(wall.width):
+ for y in range(wall.height):
+ if y >= len(message):
+ break
+ dot = message[y][(x+col) % len(message[0])]
+ if dot != ' ':
+ wall.set_pixel(x, y, (.333, 1, 1))
+ wall.draw()
+ col += 1
+ time.sleep(0.07)
View
46 run.py
@@ -3,7 +3,7 @@
import optparse, sys
from wall import Wall
-import effects
+import effects, more_effects, advanced_effects
"""
"""
@@ -12,21 +12,45 @@
parser = optparse.OptionParser("""Usage: %prog [options]""")
parser.add_option("-w", "--width", type="int",
action="store", dest="width",
- default=8, help="wall width")
+ default=8, help="Sets the wall width.")
parser.add_option("-t", "--height", type="int",
action="store", dest="height",
- default=8, help="wall height")
+ default=8, help="Sets the wall height.")
+ parser.add_option("-a", "--advanced", action="store_true",
+ dest="advanced",
+ help="Runs the advanced effects.")
+ parser.add_option("-s", "--skip-normal", action="store_true",
+ dest="skip_normal",
+ help="Skips running normal effects.")
(opts, args) = parser.parse_args(sys.argv[1:])
wall = Wall(opts.width, opts.height)
- if args:
- effects_to_run = [getattr(effects, a) for a in args \
- if hasattr(effects, a)]
+ if opts.skip_normal:
+ print "***Skipping normal effects***"
else:
- effects_to_run = effects.Effects
+ print "***Normal effects follow***"
+ effects.SolidColorTest(wall)
+ effects.DictionaryTest(wall)
+ effects.RainbowTest(wall)
+
+ more_effects.HueTest(wall)
+ more_effects.SaturationTest(wall)
+ more_effects.ValueTest(wall)
+ more_effects.Checkerboards(wall)
+ more_effects.Columns(wall)
+ more_effects.Rainbow(wall)
+ more_effects.Twinkle(wall)
+ more_effects.KnightMoves(wall)
+ more_effects.LetterTest(wall)
+ more_effects.Message(wall)
- for effect in effects_to_run:
- new_effect = effect(wall)
- print new_effect.__class__.__name__
- new_effect.run()
+ if opts.advanced:
+ print "***Advanced effects follow***"
+ effects_to_run = advanced_effects.Effects
+ for effect in effects_to_run:
+ new_effect = effect(wall)
+ print new_effect.__class__.__name__
+ new_effect.run()
+ else:
+ print "***Skipping advanced effects***"

No commit comments for this range

Something went wrong with that request. Please try again.