Permalink
Fetching contributors…
Cannot retrieve contributors at this time
155 lines (125 sloc) 4.76 KB
"""This is an example on how the autogeometry can be used for deformable
terrain.
"""
__docformat__ = "reStructuredText"
import sys
import pygame
from pygame.locals import *
from pygame.color import *
import pymunk
from pymunk import Vec2d, BB
import pymunk.pygame_util
import pymunk.autogeometry
def draw_helptext(screen):
font = pygame.font.Font(None, 16)
text = ["LMB(hold): Draw pink color",
"LMB(hold) + Shift: Create balls",
"g: Generate segments from pink color drawing",
"r: Reset",
]
y = 5
for line in text:
text = font.render(line, 1,THECOLORS["black"])
screen.blit(text, (5,y))
y += 10
def generate_geometry(surface, space):
for s in space.shapes:
if hasattr(s, "generated") and s.generated:
space.remove(s)
def sample_func(point):
try:
p = int(point.x), int(point.y)
color = surface.get_at(p)
return color.hsla[2] # use lightness
except:
return 0
line_set = pymunk.autogeometry.PolylineSet()
def segment_func(v0, v1):
line_set.collect_segment(v0, v1)
pymunk.autogeometry.march_soft(
BB(0,0,599,599), 60, 60, 90, segment_func, sample_func)
for polyline in line_set:
line = pymunk.autogeometry.simplify_curves(polyline, 1.)
for i in range(len(line)-1):
p1 = line[i]
p2 = line[i+1]
shape = pymunk.Segment(space.static_body, p1, p2, 1)
shape.friction = .5
shape.color = pygame.color.THECOLORS["red"]
shape.generated = True
space.add(shape)
def main():
pygame.init()
screen = pygame.display.set_mode((600,600))
clock = pygame.time.Clock()
space = pymunk.Space()
space.gravity = 0,980
static= [
pymunk.Segment(space.static_body, (0, -50), (-50, 650), 5),
pymunk.Segment(space.static_body, (0, 650), (650, 650), 5),
pymunk.Segment(space.static_body, (650, 650), (650, -50), 5),
pymunk.Segment(space.static_body, (-50, -50), (650, -50), 5),
]
for s in static:
s.collision_type = 1
space.add(static)
def pre_solve(arb, space, data):
s = arb.shapes[0]
space.remove(s.body, s)
return False
space.add_collision_handler(0, 1).pre_solve = pre_solve
terrain_surface = pygame.Surface((600,600))
terrain_surface.fill(pygame.color.THECOLORS["white"])
color = pygame.color.THECOLORS["pink"]
pygame.draw.circle(terrain_surface, color, (450,120), 100)
generate_geometry(terrain_surface, space)
for x in range(25):
mass = 1
moment = pymunk.moment_for_circle(mass, 0, 10)
body = pymunk.Body(mass, moment)
body.position = 450, 120
shape = pymunk.Circle(body, 10)
shape.friction = .5
space.add(body, shape)
draw_options = pymunk.pygame_util.DrawOptions(screen)
pymunk.pygame_util.positive_y_is_up = False
fps = 60
while True:
for event in pygame.event.get():
if event.type == QUIT or \
event.type == KEYDOWN and (event.key in [K_ESCAPE, K_q]):
sys.exit(0)
elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 3:
pass
elif event.type == KEYDOWN and event.key == K_r:
terrain_surface.fill(pygame.color.THECOLORS["white"])
for s in space.shapes:
if hasattr(s, "generated") and s.generated:
space.remove(s)
elif event.type == KEYDOWN and event.key == K_g:
generate_geometry(terrain_surface, space)
elif event.type == KEYDOWN and event.key == K_p:
pygame.image.save(screen, "deformable.png")
if pygame.mouse.get_pressed()[0]:
if pygame.key.get_mods() & KMOD_SHIFT:
mass = 1
moment = pymunk.moment_for_circle(mass, 0, 10)
body = pymunk.Body(mass, moment)
body.position = event.pos
shape = pymunk.Circle(body, 10)
shape.friction = .5
space.add(body, shape)
else:
color = pygame.color.THECOLORS["pink"]
pos = pygame.mouse.get_pos()
pygame.draw.circle(terrain_surface, color, pos, 25)
space.step(1./fps)
screen.fill(pygame.color.THECOLORS["white"])
screen.blit(terrain_surface, (0,0))
space.debug_draw(draw_options)
draw_helptext(screen)
pygame.display.flip()
clock.tick(fps)
pygame.display.set_caption("fps: " + str(clock.get_fps()))
if __name__ == '__main__':
sys.exit(main())