Hey every one, the code above below a user to draw lines and create circles that will collide with the lines and have them roll down the lines. The problem im having is geting the screen to follow the circles. Also im having a problem having the user be able to click and drag the screen to a new area, for example if a user creates a number of lines and wants to continue i would like them to able to click and drag the screen to the end of their lines so they can continue building.
Does any one know of any way of doing this?
Thanks
import pygame
from pygame.locals import *
from pygame.color import *
import pymunk as pm
from pymunk import Vec2d
import math
import sys
X,Y = 0,1
### Physics collision types
COLLTYPE_DEFAULT = 0
COLLTYPE_MOUSE = 1
def flipy(y):
"""Small hack to convert chipmunk physics to pygame coordinates"""
return -y+600
def mouse_coll_func(space, arbiter):
"""Simple callback that increases the radius of circles touching the mouse"""
s1,s2 = arbiter.shapes
s2.unsafe_set_radius(s2.radius + 0.15)
return False
def main():
pygame.init()
screen = pygame.display.set_mode((600, 600))
clock = pygame.time.Clock()
running = True
### Physics stuff
pm.init_pymunk()
space = pm.Space()
space.gravity = Vec2d(0.0, -900.0)
#space.resize_static_hash()
#space.resize_active_hash()
## Balls
balls = []
### Mouse
mouse_body = pm.Body(pm.inf, pm.inf)
mouse_shape = pm.Circle(mouse_body, 3, Vec2d(0,0))
mouse_shape.collision_type = COLLTYPE_MOUSE
space.add(mouse_shape)
space.add_collision_handler(COLLTYPE_MOUSE, COLLTYPE_DEFAULT, None, mouse_coll_func, None, None)
### Static line
line_point1 = None
static_lines = []
run_physics = True
while running:
for event in pygame.event.get():
if event.type == QUIT:
pygame.quit()
running = False
elif event.type == KEYDOWN and event.key == K_ESCAPE:
pygame.quit()
running = False
elif event.type == MOUSEBUTTONDOWN and event.button == 3:
p = event.pos[X], flipy(event.pos[Y])
body = pm.Body(10, 100)
body.position = p
shape = pm.Circle(body, 10, (0,0))
shape.friction = 0.5
space.add(body, shape)
balls.append(shape)
elif event.type == MOUSEBUTTONDOWN and event.button == 1:
if line_point1 is None:
line_point1 = Vec2d(event.pos[X], flipy(event.pos[Y]))
elif event.type == MOUSEBUTTONUP and event.button == 1:
if line_point1 is not None:
line_point2 = Vec2d(event.pos[X], flipy(event.pos[Y]))
print line_point1, line_point2
body = pm.Body(pm.inf, pm.inf)
shape= pm.Segment(body, line_point1, line_point2, 0.0)
shape.friction = 0.99
space.add_static(shape)
static_lines.append(shape)
line_point1 = None
elif event.type == KEYDOWN and event.key == K_SPACE:
run_physics = not run_physics
if running == False :
break
p = pygame.mouse.get_pos()
mouse_pos = Vec2d(p[X],flipy(p[Y]))
mouse_body.position = mouse_pos
if pygame.key.get_mods() & KMOD_SHIFT and event.type == MOUSEBUTTONDOWN and event.button == 3:
body = pm.Body(10, 10)
body.position = mouse_pos
shape = pm.Circle(body, 10, (0,0))
space.add(body, shape)
balls.append(shape)
### Update physics
if run_physics:
dt = 1.0/60.0
for x in range(1):
space.step(dt)
### Draw stuff
screen.fill(THECOLORS["white"])
# Display some text
font = pygame.font.Font(None, 16)
text = """RMB: Create ball
RMB + Shift: Create many balls
LMB: Drag to create wall, release to finish
Space: Pause physics simulation"""
y = 5
for line in text.splitlines():
text = font.render(line, 1,THECOLORS["black"])
screen.blit(text, (5,y))
y += 10
for ball in balls:
r = ball.radius
v = ball.body.position
rot = ball.body.rotation_vector
p = int(v.x), int(flipy(v.y))
p2 = Vec2d(rot.x, -rot.y) * r * 0.9
screen.scroll(int(v.x),int(flipy(v.y)))
pygame.draw.circle(screen, THECOLORS["blue"], p, int(r), 2)
pygame.draw.line(screen, THECOLORS["red"], p, p+p2)
if line_point1 is not None:
p1 = line_point1.x, flipy(line_point1.y)
p2 = mouse_pos.x, flipy(mouse_pos.y)
pygame.draw.lines(screen, THECOLORS["black"], False, [p1,p2])
for line in static_lines:
body = line.body
pv1 = body.position + line.a.rotated(body.angle)
pv2 = body.position + line.b.rotated(body.angle)
p1 = pv1.x, flipy(pv1.y)
p2 = pv2.x, flipy(pv2.y)
pygame.draw.lines(screen, THECOLORS["lightgray"], False, [p1,p2])
### Flip screen
pygame.display.flip()
clock.tick(50)
pygame.display.set_caption("fps: " + str(clock.get_fps()))
if __name__ == '__main__':
doprof = 0
if not doprof:
main()
else:
import cProfile, pstats
prof = cProfile.run("main()", "profile.prof")
stats = pstats.Stats("profile.prof")
stats.strip_dirs()
stats.sort_stats('cumulative', 'time', 'calls')
stats.print_stats(30)