forked from tstriker/hamster-experiments
-
Notifications
You must be signed in to change notification settings - Fork 0
/
many_lines.py
executable file
·102 lines (72 loc) · 3.21 KB
/
many_lines.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
#!/usr/bin/env python
# - coding: utf-8 -
# Copyright (C) 2010 Toms Bauģis <toms.baugis at gmail.com>
"""
Ported from javascript via chrome experiments.
Most addictive. There are some params to adjust in the Scene class.
Color and number of particles reduced due to performance
Without fadeout this becomes a mess soon, drawing/storing whole window seems
to be bit expensive though. Although scales lineary. Check earlier code of this
same file for some snippets, if you want to go that way.
Super Simple Particle System
Eric Ishii Eckhardt for Adapted
http://adaptedstudio.com
"""
import gtk
from lib import graphics
from random import random
import collections
class Particle(object):
def __init__(self, x, y, color):
self.x, self.y = x, y
self.color = color
self.prev_x, self.prev_y = x, y
# bouncyness - set to 1 to disable
self.speed_mod_x = random() * 20 + 8
self.speed_mod_y = random() * 20 + 8
# random force of atraction towards target (0.1 .. 0.5)
self.accel_mod_x = random() * 0.5 + 0.1
self.accel_mod_y = random() * 0.5 + 0.1
self.speed_x, self.speed_y = 0, 0
def update(self, mouse_x, mouse_y):
self.prev_x, self.prev_y = self.x, self.y
# two random x/y directions make the motion square
# should be angle diff and spead instead
target_accel_x = (mouse_x - self.x) * self.accel_mod_x
target_accel_y = (mouse_y - self.y) * self.accel_mod_y
self.speed_x = self.speed_x + (target_accel_x - self.speed_x) / self.speed_mod_x
self.speed_y = self.speed_y + (target_accel_y - self.speed_y) / self.speed_mod_y
self.x = self.x + self.speed_x * 0.5 #TODO should fix the speed math instead
self.y = self.y + self.speed_y * 0.5
class Scene(graphics.Scene):
def __init__(self):
graphics.Scene.__init__(self)
self.set_double_buffered(False) # cheap way how to get to continuous draw!
self.connect("on-enter-frame", self.on_enter_frame)
self.particles = []
self.paths = collections.deque()
self.particle_count = 50 # these are the flies
self.fade_step = 1 # the smaller is this the "ghostier" it looks (and slower too)
def on_enter_frame(self, scene, context):
g = graphics.Graphics(context)
g.fill_area(0, 0, self.width, self.height, "#fff", 0.08)
if not self.particles:
for i in range(self.particle_count):
color = (random() * 0.8, random() * 0.8, random() * 0.8)
self.particles.append(Particle(random() * self.width, random() * self.height, color))
g.set_line_style(width=0.3)
for particle in self.particles:
particle.update(self.mouse_x, self.mouse_y)
g.move_to(particle.prev_x, particle.prev_y)
g.line_to(particle.x, particle.y)
g.stroke(particle.color)
self.redraw()
class BasicWindow:
def __init__(self):
window = gtk.Window(gtk.WINDOW_TOPLEVEL)
window.set_size_request(1000, 650)
window.connect("delete_event", lambda *args: gtk.main_quit())
window.add(Scene())
window.show_all()
example = BasicWindow()
gtk.main()