From b606a27d7ce7e91250c0c8795270bb1862e15e26 Mon Sep 17 00:00:00 2001 From: Raymond Hogenson Date: Sun, 16 Oct 2016 12:54:32 -0400 Subject: Create new sorts of fish to be displayed --- fish_show.py | 87 +--------------------- fish_types.py | 231 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 234 insertions(+), 84 deletions(-) create mode 100644 fish_types.py diff --git a/fish_show.py b/fish_show.py index 6677ddd..62a07c9 100644 --- a/fish_show.py +++ b/fish_show.py @@ -6,85 +6,7 @@ import constants from constants import * import math from show import Show - - - -class Fish(object): - """Object displayed on the bridge, probably a fish.""" - def __init__(self, x, y, width, height, color, step): - """Create fish with default parameters.""" - self.x = x - self.y = y - self.width = width - self.height = height - self.color = color - self.speed = step - self.step = step - - self.speed = Vector(0.1, 0) - self.drag = -0.09 - - self.tailAccelMag = 0.4 - self.tailAcceleration = Vector(self.tailAccelMag, 0) - self.tailDuration = 2 - self.tailMoving = False - self.tailThreshold = 0.7 - self.tailMoveCount = 0 - - def update(self): - """Swim gently to the other side of the bridge.""" - if self.x > constants.BRIDGE_WIDTH or self.x < -self.width: - return False - - self.speed += self.drag * self.speed - if abs(self.speed) < self.tailThreshold: - self.tailMoving = True - self.tailThreshold = rand_in_range(0.5, 1.4) - self.fix_direction() - if self.tailMoveCount > self.tailDuration: - self.tailMoveCount = 0 - self.tailMoving = False - if self.tailMoving: - self.speed += self.tailAcceleration - self.tailMoveCount += 1 - self.x += self.speed.components[0] - self.y += self.speed.components[1] - - return True - - def fix_direction(self): - min_theta = -0.32 - max_theta = 0.32 - if self.y < 0: - min_theta = 0 - if self.y > 1: - max_theta = 0 - - #theta = rand_in_range(min_theta, max_theta) - theta = random.gauss((max_theta+min_theta)/2, (max_theta - min_theta)/12) - self.tailAcceleration = Vector(self.tailAccelMag, 0).rot2d(theta) - - @classmethod - def by_type(cls, fish_type): - if (fish_type == 'jellyfish'): - return cls(0, 0.5, 23, 1.5, color.black, 1) - if fish_type == 'dolphin': - return cls(0, 0.5, 23, 1.5, color.black, 1) - if fish_type == 'boat': - return cls(0, 0.5, 23, 1.5, color.black, 1) - if fish_type == 'dory': - return cls(0, 0.5, 23, 1.5, color.black, 1) - if fish_type == 'nemo': - return cls(0, 0.5, 23, 1.5, color.black, 1) - if fish_type == 'whale': - return cls(0, 0.5, 23, 1.5, color.black, 1) - if fish_type == 'stingray': - return cls(0, 0.5, 23, 1.5, color.black, 1) - if fish_type == 'eel': - return cls(0, 0.5, 23, 1.5, color.black, 1) - if fish_type == 'shark': - return cls(0, 0.5, 23, 1.5, color.black, 1) - +from fish_types import Fish class Light(object): @@ -112,7 +34,8 @@ class Light(object): new_color = new_background for fish in fishes: coverage = compute_coverage(fish, self.x, self.y) - new_color = coverage * fish.color + (1 - coverage) * new_color + fish_color = fish.color_at(self.x, self.y) + new_color = coverage * fish_color + (1 - coverage) * new_color self.light.setRGBRaw( *map(lambda x: clamp(0, x, 1), new_color.components) ) @@ -194,7 +117,3 @@ class FishShow(Show): if self.depth > self.MAX_DEPTH: self.stop() - - -def rand_in_range(low, high): - return random.random() * (high - low) + low diff --git a/fish_types.py b/fish_types.py new file mode 100644 index 0000000..63e082e --- /dev/null +++ b/fish_types.py @@ -0,0 +1,231 @@ +from __future__ import division +import color as C +import functools +import constants +import random +import math + +class Fish(object): + """Object displayed on the bridge, probably a fish. + + Must override color (or color_at), drag, width, height, tailThreshold, + tailDuration, tailAccelMag + """ + def __init__(self, x=None, y=None): + """Create fish with default parameters.""" + if x is not None: + self.x = x + elif not hasattr(self, 'x'): + self.x = 0 + if x is not None: + self.y = y + elif not hasattr(self, 'y'): + self.y = 0.5 + self.speed = C.Vector(0, 0) + self.tailAcceleration = C.Vector(self.tailAccelMag, 0) + self.tailMoving = False + self.tailMoveCount = 0 + + @classmethod + def by_type(cls, fish_type): + if (fish_type == 'jellyfish'): + return Jellyfish() + if fish_type == 'dolphin': + return Dolphin() + if fish_type == 'boat': + return Boat() + if fish_type == 'dory': + return Dory() + if fish_type == 'nemo': + return Nemo() + if fish_type == 'whale': + return Whale() + if fish_type == 'stingray': + return Stingray() + if fish_type == 'eel': + return Eel() + if fish_type == 'shark': + return Shark() + + def update(self): + """Swim gently to the other side of the bridge.""" + if self.x > constants.BRIDGE_WIDTH or self.x < -self.width: + return False + + self.speed += self.drag * self.speed + if abs(self.speed) < self.tailThreshold: + self.tailMoving = True + self.tailThreshold = rand_in_range(0.5, 1.4) + self.fix_direction() + if self.tailMoveCount > self.tailDuration: + self.tailMoveCount = 0 + self.tailMoving = False + if self.tailMoving: + self.speed += self.tailAcceleration + self.tailMoveCount += 1 + self.x += self.speed.components[0] + self.y += self.speed.components[1] + + return True + + def fix_direction(self): + min_theta = -0.32 + max_theta = 0.32 + if self.y < 0: + min_theta = 0 + if self.y > 1: + max_theta = 0 + + #theta = rand_in_range(min_theta, max_theta) + theta = random.gauss( + (max_theta+min_theta)/2, (max_theta - min_theta)/12 + ) + self.tailAcceleration = C.Vector(self.tailAccelMag, 0).rot2d(theta) + + def color_at(self, x, y): + """May be overridden to provide multicolored fish.""" + return self.color + + +class Jellyfish(Fish): + color = C.HSV(298/360, 89/100, 53/100).to_RGB() + drag = -0.01 + width = 15 + height = 1.5 + tailThreshold = 0.001 + tailDuration = 4 + tailAccelMag = 0.001 + + +class Dolphin(Fish): + color = C.HSV(18/360, 0/100, 40/100).to_RGB() + drag = -0.09 + width = 35 + height = 1.5 + tailThreshold = 0.7 + tailDuration = 2 + tailAccelMag = 0.8 + gravity = C.Vector(0, -0.01) + + direction_fixed = False + def update(self): + """Swim gently to the other side of the bridge.""" + if self.x > constants.BRIDGE_WIDTH or self.x < -self.width: + return False + + if not self.direction_fixed: + self.tailAcceleration = self.tailAcceleration.rot2d(math.pi / 32) + self.direction_fixed = True + + self.speed += self.drag * self.speed + self.gravity + if self.y <= 0.25: + self.tailMoving = True + if self.tailMoveCount > self.tailDuration: + self.tailMoveCount = 0 + self.tailMoving = False + if self.tailMoving: + self.speed += self.tailAcceleration + self.tailMoveCount += 1 + self.x += self.speed.components[0] + self.y += self.speed.components[1] + + return True + + +class Boat(Fish): + color = C.HSV(24/360, 45/100, 44/100).to_RGB() + drag = 0 + width = 23 + height = 1 + tailDuration = 1 + tailAccelMag = 0.25 + tailThreshold = tailAccelMag + y = 1 + + def fix_direction(self): + pass + + +class Dory(Fish): + # Need to try this on the bridge + color = C.HSV(235/360, 100/100, 88/100).to_RGB() + drag = -0.1 + width = 23 + height = 1.5 + tailThreshold = 0.7 + tailDuration = 2 + tailAccelMag = 0.4 + + +class Nemo(Fish): + color = C.HSV(31/360, 100/100, 50/100).to_RGB() + drag = -0.09 + width = 23 + height = 1.5 + tailThreshold = 0.7 + tailDuration = 2 + tailAccelMag = 0.4 + + +class Whale(Fish): + drag = -0.2 + width = 50 + height = 2 + tailThreshold = 0.7 + tailDuration = 3 + tailAccelMag = 0.4 + + white_x_min = 30 + white_x_width = 8 + white_y_min = 1 + white_y_height = 1 + + def color_at(self, x, y): + """Mostly copied from compute_coverage. + + The point here is to render that white part of the Orca. + """ + white_x_min = self.white_x_min + self.x + white_x_max = white_x_min + self.white_x_width + white_y_min = self.white_y_min + self.y + white_y_max = white_y_min + self.white_y_height + min_x = min(max(x, white_x_min), x + 1) + max_x = max(min(x + 1, white_x_max), x) + min_y = min(max(y, white_y_min), y + 1) + max_y = max(min(y + 1, white_y_max), y) + coverage = (max_x - min_x) * (max_y - min_y) + return C.white * coverage + + +class Stingray(Fish): + color = C.HSV(0/360, 0/100, 50/100).to_RGB() + drag = -0.09 + width = 15 + height = 2 + tailThreshold = 0.7 + tailDuration = 2 + tailAccelMag = 0.2 + + +class Eel(Fish): + color = C.HSV(109/360, 83/100, 35/100).to_RGB() + drag = -0.09 + width = 23 + height = 1.5 + tailThreshold = 0.7 + tailDuration = 2 + tailAccelMag = 0.4 + + +class Shark(Fish): + color = C.HSV(0/360, 0/100, 50/100).to_RGB() + drag = -0.2 + width = 50 + height = 2 + tailThreshold = 0.7 + tailDuration = 3 + tailAccelMag = 0.4 + + +def rand_in_range(low, high): + return random.random() * (high - low) + low -- cgit v1.3.1