0

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)
2
Contributors
1
Reply
2
Views
6 Years
Discussion Span
Last Post by vegaseat
This topic has been dead for over six months. Start a new discussion instead.
Have something to contribute to this discussion? Please be thoughtful, detailed and courteous, and be sure to adhere to our posting rules.