From 882a9d5a8799016f98a34cba1deae11b3aad8c66 Mon Sep 17 00:00:00 2001 From: group1 Date: Sun, 9 Oct 2016 23:31:23 -0400 Subject: Choose a random hue when a fish is spawned --- fish_show.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'fish_show.py') diff --git a/fish_show.py b/fish_show.py index 7cd8300..e4f24dd 100644 --- a/fish_show.py +++ b/fish_show.py @@ -147,7 +147,9 @@ class FishShow(Show): self.lights = [Light(x, y, self.bridge.get_light(x, y)) for y in xrange(self.bridge.HEIGHT) for x in xrange(self.bridge.WIDTH)] - self.fish = Fish(0, 0.5, 23, 1.5, color.black, 1) + random_hue = random.random() + fish_color = color.HSV(random_hue, 1, 20/100).to_RGB() + self.fish = Fish(0, 0.5, 23, 1.5, fish_color, 1) def update(self): -- cgit v1.3.1 From 198dcfc6f43724a3240496259e2bcda8b6bf6e8d Mon Sep 17 00:00:00 2001 From: Aaron Perley Date: Tue, 11 Oct 2016 01:09:08 -0400 Subject: Add support for multiple fish --- fish_show.py | 21 ++++++++++----------- 1 file changed, 10 insertions(+), 11 deletions(-) (limited to 'fish_show.py') diff --git a/fish_show.py b/fish_show.py index e4f24dd..51693e4 100644 --- a/fish_show.py +++ b/fish_show.py @@ -78,7 +78,7 @@ class Light(object): self.x = x self.y = y - def update(self, fish): + def update(self, fishes): """Change color depending on where the fish is.""" if abs(self.transitioning_to - self.color) <= self.step: self.transitioning_to = pick_HSV().to_RGB() @@ -87,14 +87,12 @@ class Light(object): new_background = transition( self.color, self.transitioning_to, self.step ) - coverage = compute_coverage(fish, self.x, self.y) - #coverage *= coverage - new_color = coverage * fish.color + (1 - coverage) * new_background - #new_color = new_background + self.color = new_background - if self.x == 30 and self.y == 0: - pass - #print(self.color.r(), self.color.g(), self.color.b()) + 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 self.light.setRGBRaw( *map(lambda x: clamp(0, x, 1), new_color.components) ) @@ -149,13 +147,14 @@ class FishShow(Show): for x in xrange(self.bridge.WIDTH)] random_hue = random.random() fish_color = color.HSV(random_hue, 1, 20/100).to_RGB() - self.fish = Fish(0, 0.5, 23, 1.5, fish_color, 1) + self.fishes = [Fish(0, 0.5, 23, 1.5, fish_color, 1), Fish(100, 0.5, 23, 1.5, fish_color, 1)] def update(self): - self.fish.update() + for fish in self.fishes: + fish.update() for light in self.lights: - light.update(self.fish) + light.update(self.fishes) def rand_in_range(low, high): return random.random() * (high - low) + low -- cgit v1.3.1 From 2d37dd487f0571ce94a0e4e966931dd6697d685f Mon Sep 17 00:00:00 2001 From: Aaron Perley Date: Tue, 11 Oct 2016 02:03:49 -0400 Subject: Add event passing between webapp and show --- ShowRunner.py | 16 ++++++++++++++++ bridge.py | 7 ------- fish_show.py | 13 +++++++++---- show.py | 15 ++++++++++++++- webapp/app/__init__.py | 5 +++++ webapp/app/templates/index.html | 2 ++ webapp/app/views.py | 23 ++++++++++++++++------- webapp/run.py | 10 ++++++++-- 8 files changed, 70 insertions(+), 21 deletions(-) create mode 100644 ShowRunner.py (limited to 'fish_show.py') diff --git a/ShowRunner.py b/ShowRunner.py new file mode 100644 index 0000000..5a43a99 --- /dev/null +++ b/ShowRunner.py @@ -0,0 +1,16 @@ +from bridge import Bridge +from fish_show import FishShow +from constants import * + +import sys +sys.path.append('webapp') +from run import server_thread, send_queue, recv_queue + +def run_show(): + server_thread.start() + bridge = Bridge() + show = FishShow(bridge, send_queue=recv_queue, recv_queue=send_queue) + #show = SunriseShow(bridge) + show.run(framerate=FRAME_RATE) + +run_show() \ No newline at end of file diff --git a/bridge.py b/bridge.py index 26beb24..91e81fb 100755 --- a/bridge.py +++ b/bridge.py @@ -36,10 +36,3 @@ class Bridge(object): -def main(): - bridge = Bridge() - show = FishShow(bridge) - #show = SunriseShow(bridge) - show.run(framerate=FRAME_RATE) - -main() diff --git a/fish_show.py b/fish_show.py index 51693e4..d42e520 100644 --- a/fish_show.py +++ b/fish_show.py @@ -52,7 +52,7 @@ class Fish(object): if self.x < -self.width: self.x = constants.BRIDGE_WIDTH - print(self.x, self.y) + #print(self.x, self.y) def fix_direction(self): min_theta = -0.32 @@ -145,12 +145,17 @@ class FishShow(Show): self.lights = [Light(x, y, self.bridge.get_light(x, y)) for y in xrange(self.bridge.HEIGHT) for x in xrange(self.bridge.WIDTH)] - random_hue = random.random() - fish_color = color.HSV(random_hue, 1, 20/100).to_RGB() - self.fishes = [Fish(0, 0.5, 23, 1.5, fish_color, 1), Fish(100, 0.5, 23, 1.5, fish_color, 1)] + self.fishes = [] + self.send_event('new creature', {'name': 'test fishy'}) def update(self): + event = self.recv_event() + if event and event[0] == 'spawn': + random_hue = random.random() + fish_color = color.HSV(random_hue, 1, 20/100).to_RGB() + self.fishes.append(Fish(0, 0.5, 23, 1.5, fish_color, 1)) + for fish in self.fishes: fish.update() for light in self.lights: diff --git a/show.py b/show.py index f8544c9..19066c0 100644 --- a/show.py +++ b/show.py @@ -1,5 +1,6 @@ from __future__ import division, print_function import time +import Queue class Clock(object): def __init__(self): @@ -18,10 +19,12 @@ class Clock(object): class Show(object): - def __init__(self, bridge): + def __init__(self, bridge, send_queue, recv_queue): self.bridge = bridge self.clock = Clock() self.running = True + self.send_queue = send_queue + self.recv_queue = recv_queue self.init() def run(self, framerate=40): @@ -30,6 +33,16 @@ class Show(object): self.bridge.update() self.clock.tick(framerate) + def send_event(self, event_name, data=None): + self.send_queue.put((event_name, data)) + + def recv_event(self): + try: + msg = self.recv_queue.get_nowait() + return msg + except Queue.Empty: + return None + def init(self): """Override me""" raise NotImplementedError diff --git a/webapp/app/__init__.py b/webapp/app/__init__.py index 29cd22b..3e188ec 100644 --- a/webapp/app/__init__.py +++ b/webapp/app/__init__.py @@ -1,6 +1,11 @@ from flask import Flask import socketio +import Queue + +recv_queue = Queue.Queue() +send_queue = Queue.Queue() + sio = socketio.Server(async_mode='threading') app = Flask(__name__) app.wsgi_app = socketio.Middleware(sio, app.wsgi_app) diff --git a/webapp/app/templates/index.html b/webapp/app/templates/index.html index b0d9bb3..d4d1853 100644 --- a/webapp/app/templates/index.html +++ b/webapp/app/templates/index.html @@ -43,6 +43,8 @@ socket.on('disconnect', function() { console.log('disconnected'); }); + + socket.emit('ready'); }); diff --git a/webapp/app/views.py b/webapp/app/views.py index 4aa2c05..1c68688 100644 --- a/webapp/app/views.py +++ b/webapp/app/views.py @@ -1,11 +1,9 @@ from flask import render_template, request -from app import app, sio +from app import app, sio, send_queue, recv_queue import time import threading -thread = None - @app.route('/') @app.route('/index') def index(): @@ -22,6 +20,14 @@ def connect(sid, environ): @sio.on('spawn', namespace='/spawn') def message(sid, data): print("message ", data) + send_queue.put(('spawn', data)) + +@sio.on('ready', namespace='/spawn') +def ready(sid): + print("got ready message from ", sid) + for event in received_events: + print "sending missed event", event + sio.emit(event[0], event[1], room=sid, namespace='/spawn') @sio.on('disconnect', namespace='/spawn') def disconnect(sid): @@ -29,9 +35,12 @@ def disconnect(sid): connections.remove(sid) +received_events = [] +def recv_events(): + while True: + event = recv_queue.get() + sio.emit(event[0], event[1], namespace='/spawn') + received_events.append(event) -def add_creature(): - time.sleep(5) - sio.emit('new creature', {'name': 'fish1'}, namespace='/spawn') -thread = sio.start_background_task(add_creature) +thread = sio.start_background_task(recv_events) diff --git a/webapp/run.py b/webapp/run.py index b5c8c6f..2290f41 100755 --- a/webapp/run.py +++ b/webapp/run.py @@ -3,5 +3,11 @@ import sys sys.path.append('packages') -from app import app -app.run(threaded=True, host='', port=8000) +import threading + +from app import app, send_queue, recv_queue + +def run_server(): + app.run(threaded=True, host='', port=8000) + +server_thread = threading.Thread(target=run_server) -- cgit v1.3.1 From 26ed0bd9400a888b2603db734d47e9ea64c6c3d7 Mon Sep 17 00:00:00 2001 From: Aaron Perley Date: Thu, 13 Oct 2016 21:17:59 -0400 Subject: Update fish show with increasing depth and fish type handling --- fish_show.py | 81 +++++++++++++++++++++++++++++------------ show.py | 3 ++ webapp/app/templates/index.html | 2 +- 3 files changed, 62 insertions(+), 24 deletions(-) (limited to 'fish_show.py') diff --git a/fish_show.py b/fish_show.py index d42e520..6677ddd 100644 --- a/fish_show.py +++ b/fish_show.py @@ -7,6 +7,8 @@ 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): @@ -31,6 +33,9 @@ class Fish(object): 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 @@ -44,15 +49,8 @@ class Fish(object): self.tailMoveCount += 1 self.x += self.speed.components[0] self.y += self.speed.components[1] - # - # THIS NEEDS TO CHANGE - # - if self.x > constants.BRIDGE_WIDTH: - self.x = -self.width - if self.x < -self.width: - self.x = constants.BRIDGE_WIDTH - #print(self.x, self.y) + return True def fix_direction(self): min_theta = -0.32 @@ -65,7 +63,29 @@ class Fish(object): #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) + + class Light(object): """Represent a bridge light and its state.""" @@ -78,10 +98,10 @@ class Light(object): self.x = x self.y = y - def update(self, fishes): + def update(self, depth, fishes): """Change color depending on where the fish is.""" if abs(self.transitioning_to - self.color) <= self.step: - self.transitioning_to = pick_HSV().to_RGB() + self.transitioning_to = pick_HSV(depth).to_RGB() self.step = (random_change() * abs(self.color - self.transitioning_to)) new_background = transition( @@ -111,10 +131,12 @@ def compute_coverage(fish, x, y): return coverage * scale -def pick_HSV(): +def pick_HSV(depth): """Return a random color in an appropriate interval.""" - hue = random.random() * (constants.MAX_HUE - constants.MIN_HUE) + constants.MIN_HUE - saturation = random.random() * (MAX_SATURATION - MIN_SATURATION) + MIN_SATURATION + min_hue = constants.MIN_HUE + (10/360)*depth + min_saturation = constants.MIN_SATURATION + 0.05*depth + hue = random.random() * (constants.MAX_HUE - min_hue) + min_hue + saturation = random.random() * (MAX_SATURATION - min_saturation) + min_saturation value = random.random() * (MAX_VALUE - MIN_VALUE) + MIN_VALUE return color.HSV(hue, saturation, value) @@ -141,25 +163,38 @@ def clamp(low, x, high): return max(low, min(x, high)) class FishShow(Show): + # 1 minute show + TICKS_PER_DEPTH = FRAME_RATE * 10 + MAX_DEPTH = 6 + def init(self): self.lights = [Light(x, y, self.bridge.get_light(x, y)) for y in xrange(self.bridge.HEIGHT) for x in xrange(self.bridge.WIDTH)] - self.fishes = [] - self.send_event('new creature', {'name': 'test fishy'}) - + self.fishes = set() + self.tick_count = 0 + self.depth = 0 def update(self): event = self.recv_event() if event and event[0] == 'spawn': - random_hue = random.random() - fish_color = color.HSV(random_hue, 1, 20/100).to_RGB() - self.fishes.append(Fish(0, 0.5, 23, 1.5, fish_color, 1)) + new_fish = Fish.by_type(event[1]['type']) + self.fishes.add(new_fish) - for fish in self.fishes: - fish.update() + for fish in list(self.fishes): + if not fish.update(): + self.fishes.remove(fish) for light in self.lights: - light.update(self.fishes) + light.update(self.depth, self.fishes) + + self.tick_count += 1 + if self.tick_count % self.TICKS_PER_DEPTH == 0: + self.depth += 1 + print("DEPTH: ", self.depth) + + if self.depth > self.MAX_DEPTH: + self.stop() + def rand_in_range(low, high): return random.random() * (high - low) + low diff --git a/show.py b/show.py index 19066c0..5749863 100644 --- a/show.py +++ b/show.py @@ -33,6 +33,9 @@ class Show(object): self.bridge.update() self.clock.tick(framerate) + def stop(self): + self.running = False + def send_event(self, event_name, data=None): self.send_queue.put((event_name, data)) diff --git a/webapp/app/templates/index.html b/webapp/app/templates/index.html index a8e3479..3592985 100644 --- a/webapp/app/templates/index.html +++ b/webapp/app/templates/index.html @@ -106,7 +106,7 @@ }; self.click = function() { - self.socket.emit('spawn', {name:self.name}); + self.socket.emit('spawn', {type:self.name}); } } -- cgit v1.3.1