Created
December 12, 2015 22:16
-
-
Save offe/7269e9e3cff6ac88b584 to your computer and use it in GitHub Desktop.
tintedghosts.py
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# coding: utf-8 | |
from scene import * | |
import random | |
import math | |
import numpy as np | |
from colorsys import hsv_to_rgb | |
PROFILE = False | |
MODE_STILL = 0 # Don't do anything in update() | |
MODE_ONLY_CALCULATE = 1 # Only do numpy position updates | |
MODE_ONLY_COPY_POSITIONS = 2 # Only copy numpy positions into sprites | |
MODE_FULL = 3 # Calculate positions and copy them into sprites | |
RUN_MODE = MODE_FULL | |
MAX_FOR_FULL_FPS = { | |
MODE_STILL: 600, | |
MODE_ONLY_CALCULATE: 450, | |
MODE_ONLY_COPY_POSITIONS: 450, | |
MODE_FULL: 350 | |
} | |
SPRITE_SIZE = 80 | |
NUMBER_OF_SPRITES = MAX_FOR_FULL_FPS[RUN_MODE] | |
BORDER = 100 | |
def random_within_bounds(bounds): | |
return Point(random.uniform(bounds.min_x, bounds.max_x), | |
random.uniform(bounds.min_y, bounds.max_y)) | |
def random_direction(): | |
a = random.random() * 2 * math.pi | |
return Point(math.sin(a), math.cos(a)) | |
def normalize_ndarray(a): | |
d = np.sqrt((a*a).sum(1)) | |
return a/np.expand_dims(d,2) | |
class MyScene (Scene): | |
def setup(self): | |
self.background_color = '#313131' | |
self.ghosts_node = Node(position=(-BORDER, -BORDER), parent=self) | |
self.set_ghosts_node_size() | |
self.sprites = [self.new_sprite() for _ in xrange(NUMBER_OF_SPRITES)] | |
self.positions = np.random.rand(NUMBER_OF_SPRITES, 2) * self.ghosts_node.size | |
self.vels = 0 * self.positions | |
self.destination = 0 | |
self.set_sprite_positions_from_ndarray() | |
def set_ghosts_node_size(self): | |
self.ghosts_node.size = (self.size.width+2*BORDER, self.size.height+2*BORDER) | |
def new_sprite(self): | |
size = random.uniform(0.5, 1) | |
sprite = SpriteNode('emj:Ghost', | |
size=(SPRITE_SIZE*size, SPRITE_SIZE*size), | |
parent=self.ghosts_node) | |
sprite.color = hsv_to_rgb(random.random(), 0.1, 1.0) | |
sprite.alpha = 0.85 | |
#sprite.z_position = size | |
return sprite | |
def did_change_size(self): | |
self.set_ghosts_node_size() | |
def set_sprite_positions_from_ndarray(self): | |
ps = self.positions | |
for i, sprite in enumerate(self.sprites): | |
sprite.position = ps[i] | |
def update_positions(self): | |
self.vels *= 0.8 ** self.dt | |
max_dv = 1000 * self.dt | |
#self.vels += np.random.uniform(-max_dv, max_dv, (NUMBER_OF_SPRITES, 2)) | |
# Change velocity of sprites on one side of a random line | |
p = random_within_bounds(self.ghosts_node.bbox) | |
d = random_direction() | |
selected = ((self.positions - p) * d).sum(1) > 0 | |
self.vels[selected] -= 300 * self.dt * random_direction() | |
if self.destination: | |
destination = self.ghosts_node.point_from_scene(self.destination) | |
self.vels -= 1.0 * normalize_ndarray(self.positions - destination) | |
self.positions += self.vels * self.dt | |
self.positions %= self.ghosts_node.size | |
def update(self): | |
if RUN_MODE in [MODE_ONLY_CALCULATE, MODE_FULL]: | |
self.update_positions() | |
if RUN_MODE in [MODE_ONLY_COPY_POSITIONS, MODE_FULL]: | |
self.set_sprite_positions_from_ndarray() | |
def touch_began(self, touch): | |
self.destination = touch.location | |
def touch_moved(self, touch): | |
self.destination = touch.location | |
def touch_ended(self, touch): | |
self.destination = None | |
if __name__ == '__main__': | |
if PROFILE: | |
import cProfile | |
import pstats | |
cProfile.run('run(MyScene(), show_fps=True)', 'profiling') | |
p = pstats.Stats('profiling') | |
p.sort_stats('cumulative').print_stats(20) | |
else: | |
run(MyScene(), show_fps=True) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment