Skip to content

Commit 3ebb812

Browse files
committed
colors examples
1 parent 23477a6 commit 3ebb812

File tree

5 files changed

+792
-326
lines changed

5 files changed

+792
-326
lines changed

dump/colors_logo.py

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,169 @@
1+
"""
2+
An example of the determinism of pymunk by coloring balls according to their
3+
position, and then respawning them to verify each ball ends up in the same
4+
place. Inspired by Pymunk user Nam Dao.
5+
"""
6+
7+
8+
import os
9+
import random
10+
11+
import pygame
12+
13+
import pymunk
14+
import pymunk.pygame_util
15+
16+
17+
def new_space():
18+
space = pymunk.Space()
19+
space.gravity = 0, 900
20+
static_body = space.static_body
21+
walls = [
22+
pymunk.Segment(static_body, (0, -500), (600, -500), 100), # top -
23+
pymunk.Segment(static_body, (-30, -500), (-50, 650), 100), # left |
24+
pymunk.Segment(static_body, (-50, 650), (600, 650), 100), # bottom -
25+
pymunk.Segment(static_body, (650, 650), (630, -500), 100), # right |
26+
]
27+
for wall in walls:
28+
wall.elasticity = 0.9
29+
30+
space.add(*walls)
31+
32+
random.seed(0)
33+
return space
34+
35+
36+
def set_colors(color_dict, logo_img, space):
37+
color_dict.clear()
38+
w = logo_img.get_width()
39+
h = logo_img.get_height()
40+
logo_img.lock()
41+
for shape in space.shapes:
42+
if not isinstance(shape, pymunk.Circle):
43+
continue
44+
r = shape.body.position.x / 600 * 255
45+
g = max((shape.body.position.y - 400) / 200 * 255, 0)
46+
if r < 0 or r > 255 or g < 0 or g > 255:
47+
print(shape.body.position)
48+
shape.color = (255, 255, 255, 255)
49+
continue
50+
shape.color = (r, g, 150, 255)
51+
p = shape.body.position
52+
x = int(p.x) - (600 - w) // 2
53+
y = int(p.y - 600 + h + 40)
54+
if x >= 0 and x < w and y > 0 and y < h:
55+
color = logo_img.get_at([x, y])
56+
if color.a > 200:
57+
shape.color = color.r, color.g, color.b, 255
58+
color_dict[shape.data] = shape.color
59+
logo_img.unlock()
60+
61+
62+
pygame.init()
63+
screen = pygame.display.set_mode((600, 600))
64+
clock = pygame.time.Clock()
65+
font = pygame.font.SysFont("Arial", 14)
66+
text = font.render(
67+
"Press r to reset and respawn all balls."
68+
" Press c to set color of each ball according to its position.",
69+
True,
70+
pygame.Color("darkgray"),
71+
)
72+
73+
logo_img = pygame.image.load(
74+
os.path.join(os.path.dirname(os.path.abspath(__file__)), "pymunk_logo_sphinx.png")
75+
)
76+
box_surf = pygame.Surface((6, 6))
77+
box_surf.fill(pygame.Color("white"))
78+
draw_options = pymunk.pygame_util.DrawOptions(screen)
79+
80+
color_dict = {}
81+
space = new_space()
82+
cnt = max_cnt = 3000
83+
84+
while True:
85+
for event in pygame.event.get():
86+
if event.type == pygame.QUIT:
87+
exit()
88+
elif event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE:
89+
exit()
90+
elif event.type == pygame.KEYDOWN and event.key == pygame.K_p:
91+
pygame.image.save(screen, "colors.png")
92+
elif event.type == pygame.KEYDOWN and event.key == pygame.K_r:
93+
if not color_dict:
94+
set_colors(color_dict, logo_img, space)
95+
space = new_space()
96+
cnt = max_cnt
97+
elif event.type == pygame.KEYDOWN and event.key == pygame.K_c:
98+
set_colors(color_dict, logo_img, space)
99+
elif event.type == pygame.KEYDOWN and event.key == pygame.K_x:
100+
exp_p = pymunk.Vec2d(300, 450)
101+
query_info = space.point_query(exp_p, 50, shape_filter=pymunk.ShapeFilter())
102+
print(len(query_info))
103+
for info in query_info:
104+
if info.shape is None:
105+
continue
106+
impulse = (
107+
(info.shape.body.position - exp_p).normalized()
108+
* (1 / info.distance)
109+
* 100000
110+
)
111+
112+
info.shape.body.apply_impulse_at_local_point(impulse, (0, 0))
113+
114+
if cnt > 0:
115+
for _ in range(15):
116+
cnt -= 1
117+
if cnt < 1:
118+
continue
119+
body = pymunk.Body(1, 1)
120+
x = random.randint(550, 570)
121+
y = random.randint(30, 100)
122+
body.position = x, y
123+
shape = pymunk.Circle(body, 2.5)
124+
# shape.mass = 1
125+
shape.data = cnt
126+
shape.elasticity = 0.9
127+
if color_dict != None and cnt in color_dict:
128+
shape.color = color_dict[cnt]
129+
space.add(body, shape)
130+
elif cnt == -10 and False:
131+
cnt -= 1
132+
exp_p = pymunk.Vec2d(300, 450)
133+
query_info = space.point_query(exp_p, 50, shape_filter=pymunk.ShapeFilter())
134+
print(len(query_info))
135+
for info in query_info:
136+
if info.shape is None:
137+
continue
138+
impulse = (
139+
(info.shape.body.position - exp_p).normalized()
140+
* (1 / info.distance)
141+
* 25000
142+
)
143+
impulse = impulse.x, abs(impulse.y)
144+
info.shape.body.apply_impulse_at_local_point(impulse, (0, 0))
145+
146+
### Update physics
147+
dt = 1.0 / 60.0
148+
for _ in range(1):
149+
space.step(dt / 1)
150+
151+
### Draw stuff
152+
screen.fill(pygame.Color("white"))
153+
154+
color = pygame.Color("blue")
155+
for shape in space.shapes:
156+
if not isinstance(shape, pymunk.Circle):
157+
continue
158+
if hasattr(shape, "color"):
159+
color = shape.color
160+
161+
box_surf.fill(color)
162+
screen.blit(box_surf, shape.body.position)
163+
164+
screen.blit(text, (25, 2))
165+
166+
### Flip screen
167+
pygame.display.flip()
168+
clock.tick(50)
169+
pygame.display.set_caption("fps: " + str(clock.get_fps()))

0 commit comments

Comments
 (0)