def test_space_attributes(): space = cy.Space() assert (space is not None) assert (space.iterations == 10) space.iterations = 20 assert (space.iterations == 20) assert (len(space.bodies) == 0) assert (len(space.static_shapes) == 0) assert (len(space.bodies) == 0) assert (len(space.constraints) == 0) assert (space.static_body is not None) assert (isinstance(space.static_body, cy.Body)) assert (space.damping == 1.) assert (space.idle_speed_threshold == 0.) assert (space.sleep_time_threshold == float('inf')) assert (space.collision_slop < 0.2) assert (space.collision_bias < 0.01) assert (space.collision_persistence == 3L) assert (space.enable_contact_graph == 0) # tests readonly attributes with pytest.raises(AttributeError): space.static_body = None
def test_space_gravity(): space = cy.Space() assert (space.gravity.x == 0.) assert (space.gravity.y == 0.) space.gravity = (5, 10) assert (space.gravity.x == 5) assert (space.gravity.y == 10) space.gravity = cy.Vec2d(25, 50) assert (space.gravity.x == 25) assert (space.gravity.y == 50)
def init_physics(self): # create the space for physics simulation self.space = space = cy.Space() space.iterations = 30 space.gravity = (0, -700) space.sleep_time_threshold = 0.5 space.collision_slop = 0.5 # create 4 segments that will act as a bounds for x in range(4): seg = cy.Segment(space.static_body, cy.Vec2d(0, 0), cy.Vec2d(0, 0), 0) seg.elasticity = 0.6 #seg.friction = 1.0 self.cbounds.append(seg) space.add_static(seg) # update bounds with good positions self.update_bounds()
def __init__(self): self.running = True self.drawing = True self.w, self.h = 600, 600 self.screen = pygame.display.set_mode((self.w, self.h)) self.clock = pygame.time.Clock() ### Init pymunk and create space self.space = pymunk.Space() self.space.gravity = (0.0, -900.0) ### ground body = pymunk.Body() shape = pymunk.Segment(body, (50, 100), (550, 100), .0) shape.friction = 1.0 self.space.add(shape) ### pyramid x = Vec2d(-100, 7.5) + (300, 100) y = Vec2d(0, 0) deltaX = Vec2d(0.5625, 2.0) * 10 deltaY = Vec2d(1.125, 0.0) * 10 for i in range(25): y = Vec2d(x) for j in range(i, 25): size = 5 points = [(-size, -size), (-size, size), (size, size), (size, -size)] mass = 1.0 moment = pymunk.moment_for_poly(mass, points, (0, 0)) body = pymunk.Body(mass, moment) body.position = y shape = pymunk.Poly(body, points, (0, 0)) shape.friction = 1 self.space.add(body, shape) y += deltaY x += deltaX
def main(): pygame.init() screen = pygame.display.set_mode((600, 600)) clock = pygame.time.Clock() running = True ### Physics stuff space = pymunk.Space() space.gravity = Vec2d(0.0, -900.0) ## logo logo_img = pygame.image.load("pymunk_logo_googlecode.png") logos = [] ### Static line static_body = pymunk.Body() static_lines = [ pymunk.Segment(static_body, (11.0, 280.0), (407.0, 246.0), 0.0), pymunk.Segment(static_body, (407.0, 246.0), (407.0, 343.0), 0.0) ] for l in static_lines: l.friction = 0.5 space.add(static_lines) ticks_to_next_spawn = 10 while running: for event in pygame.event.get(): if event.type == QUIT: running = False elif event.type == KEYDOWN and event.key == K_ESCAPE: running = False elif event.type == KEYDOWN and event.key == K_p: pygame.image.save(screen, "using_sprites.png") ticks_to_next_spawn -= 1 if ticks_to_next_spawn <= 0: ticks_to_next_spawn = 100 x = random.randint(20, 400) y = 500 angle = random.random() * math.pi vs = [(-23, 26), (23, 26), (0, -26)] mass = 10 moment = pymunk.moment_for_poly(mass, vs) body = pymunk.Body(mass, moment) shape = pymunk.Poly(body, vs) shape.friction = 0.5 body.position = x, y body.angle = angle space.add(body, shape) logos.append(shape) ### Update physics dt = 1.0 / 60.0 for x in range(1): space.step(dt) ### Draw stuff screen.fill(THECOLORS["black"]) for logo_shape in logos: # image draw p = logo_shape.body.position p = Vec2d(p.x, flipy(p.y)) # we need to rotate 180 degrees because of the y coordinate flip angle_degrees = math.degrees(logo_shape.body.angle) + 180 rotated_logo_img = pygame.transform.rotate(logo_img, angle_degrees) offset = Vec2d(rotated_logo_img.get_size()) / 2. p = p - offset screen.blit(rotated_logo_img, (p.x, p.y)) # debug draw ps = logo_shape.get_vertices() ps = [(p.x, flipy(p.y)) for p in ps] ps += [ps[0]] pygame.draw.lines(screen, THECOLORS["red"], False, ps, 1) 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], 2) ### Flip screen pygame.display.flip() clock.tick(50) pygame.display.set_caption("fps: " + str(clock.get_fps()))
def main(): pygame.init() screen = pygame.display.set_mode((600, 600)) clock = pygame.time.Clock() running = True ### Physics stuff space = pm.Space() space.gravity = Vec2d(0.0, -900.0) ## Balls balls = [] ### walls static_lines = [pm.Segment(space.static_body, Vec2d(111.0, 280.0), Vec2d(407.0, 246.0), 1.0) ,pm.Segment(space.static_body, Vec2d(407.0, 246.0), Vec2d(407.0, 343.0), 1.0) ] space.add(static_lines) ticks_to_next_ball = 10 while running: for event in pygame.event.get(): if event.type == QUIT: running = False elif event.type == KEYDOWN and event.key == K_ESCAPE: running = False elif event.type == KEYDOWN and event.key == K_p: pygame.image.save(screen, "point_query.png") ticks_to_next_ball -= 1 if ticks_to_next_ball <= 0: ticks_to_next_ball = 100 mass = 10 radius = 25 inertia = pm.moment_for_circle(mass, 0, radius, Vec2d(0,0)) body = pm.Body(mass, inertia) x = random.randint(115,350) body.position = x, 400 shape = pm.Circle(body, radius, Vec2d(0,0)) #shape.color = THECOLORS["lightgrey"] space.add(body, shape) balls.append(shape) ### Clear screen screen.fill(THECOLORS["white"]) ### Draw stuff pygame_util.draw(screen, space) balls_to_remove = [] for ball in balls: if ball.body.position.y < 200: balls_to_remove.append(ball) for ball in balls_to_remove: space.remove(ball, ball.body) balls.remove(ball) mouse_pos = pygame_util.get_mouse_pos(screen) shape = space.point_query_first(Vec2d(mouse_pos)) if shape is not None: if hasattr(shape, "radius"): r = shape.radius + 4 else: r = 10 p = pygame_util.to_pygame(shape.body.position, screen) pygame.draw.circle(screen, THECOLORS["red"], p, int(r), 2) ### Update physics dt = 1.0/60.0 for x in range(1): space.step(dt) ### Flip screen pygame.display.flip() clock.tick(50) pygame.display.set_caption("fps: " + str(clock.get_fps()))
import cymunk as pymunk from cymunk import Vec2d window = pyglet.window.Window(width=600, height=600) fps_display = pyglet.clock.ClockDisplay() logo_img = pyglet.resource.image('pymunk_logo_googlecode.png') logo_img.anchor_x = logo_img.width / 2 logo_img.anchor_y = logo_img.height / 2 logos = [] batch = pyglet.graphics.Batch() ### Physics stuff space = pymunk.Space() space.gravity = Vec2d(0.0, -900.0) ### Static line static_body = pymunk.Body() static_lines = [ pymunk.Segment(static_body, (11.0, 280.0), (407.0, 246.0), 0.0), pymunk.Segment(static_body, (407.0, 246.0), (407.0, 343.0), 0.0) ] for l in static_lines: l.friction = 0.5 space.add(static_lines) @window.event def on_key_press(symbol, modifiers):
def main(): ### PyGame init pygame.init() screen = pygame.display.set_mode((width, height)) clock = pygame.time.Clock() running = True font = pygame.font.SysFont("Arial", 16) ### Physics stuff space = pymunk.Space() space.gravity = 0, -1000 # walls - the left-top-right walls static = [ pymunk.Segment(space.static_body, (50, 50), (50, 550), 5), pymunk.Segment(space.static_body, (50, 550), (650, 550), 5), pymunk.Segment(space.static_body, (650, 550), (650, 50), 5), pymunk.Segment(space.static_body, (50, 50), (650, 50), 5) ] b2 = pymunk.Body() static.append(pymunk.Circle(b2, 30)) b2.position = 300, 400 for s in static: s.friction = 1. s.group = 1 space.add(static) # "Cannon" that can fire arrows cannon_body = pymunk.Body() cannon_shape = pymunk.Circle(cannon_body, 25) cannon_shape.sensor = True cannon_body.position = 100, 100 space.add(cannon_shape) arrow_body, arrow_shape = create_arrow() space.add(arrow_shape) space.add_collision_handler(0, 1, post_solve=post_solve_arrow_hit) flying_arrows = [] while running: for event in pygame.event.get(): if event.type == QUIT or \ event.type == KEYDOWN and (event.key in [K_ESCAPE, K_q]): running = False elif event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: start_time = pygame.time.get_ticks() elif event.type == KEYDOWN and event.key == K_p: pygame.image.save(screen, "arrows.png") elif event.type == pygame.MOUSEBUTTONUP and event.button == 1: end_time = pygame.time.get_ticks() diff = end_time - start_time power = max(min(diff, 1000), 10) * 1.5 impulse = Vec2d(1, 0) * power arrow_body.apply_impulse(impulse.rotated(arrow_body.angle)) space.add(arrow_body) flying_arrows.append(arrow_body) arrow_body, arrow_shape = create_arrow() space.add(arrow_shape) keys = pygame.key.get_pressed() speed = 2.5 if (keys[K_UP]): cannon_body.position += Vec2d(0, 1) * speed if (keys[K_DOWN]): cannon_body.position += Vec2d(0, -1) * speed if (keys[K_LEFT]): cannon_body.position += Vec2d(-1, 0) * speed if (keys[K_RIGHT]): cannon_body.position += Vec2d(1, 0) * speed mouse_position = from_pygame(Vec2d(pygame.mouse.get_pos()), screen) cannon_body.angle = Vec2d(mouse_position - cannon_body.position).angle # move the unfired arrow together with the cannon arrow_body.position = cannon_body.position + Vec2d( cannon_shape.radius + 40, 0).rotated(cannon_body.angle) arrow_body.angle = cannon_body.angle for flying_arrow in flying_arrows: drag_constant = 0.0002 pointing_direction = Vec2d(1, 0).rotated(flying_arrow.angle) flight_direction = Vec2d(flying_arrow.velocity) flight_speed = flight_direction.normalize_return_length() dot = flight_direction.dot(pointing_direction) # (1-abs(dot)) can be replaced with (1-dot) to make arrows turn around even when fired straight up. # Might not be as accurate, but maybe look better. drag_force_magnitude = ( 1 - abs(dot)) * flight_speed**2 * drag_constant * flying_arrow.mass arrow_tail_position = Vec2d(-50, 0).rotated(flying_arrow.angle) flying_arrow.apply_impulse( -flight_direction * drag_force_magnitude, arrow_tail_position) flying_arrow.angular_velocity *= 0.9 for cb in callbacks: cbf = cb[0] params = cb[1:] cbf(*params) del callbacks[:] ### Clear screen screen.fill(pygame.color.THECOLORS["black"]) ### Draw stuff draw(screen, space) # Power meter if pygame.mouse.get_pressed()[0]: current_time = pygame.time.get_ticks() diff = current_time - start_time power = max(min(diff, 1000), 10) h = power / 2 pygame.draw.line(screen, pygame.color.THECOLORS["red"], (30, 550), (30, 550 - h), 10) # Info and flip screen screen.blit( font.render("fps: " + str(clock.get_fps()), 1, THECOLORS["white"]), (0, 0)) screen.blit( font.render("Aim with mouse, hold LMB to powerup, release to fire", 1, THECOLORS["darkgrey"]), (5, height - 35)) screen.blit( font.render("Press R to reset, ESC or Q to quit", 1, THECOLORS["darkgrey"]), (5, height - 20)) pygame.display.flip() ### Update physics fps = 60 dt = 1. / fps space.step(dt) clock.tick(fps)
def main(): pygame.init() screen = pygame.display.set_mode((600, 600)) clock = pygame.time.Clock() running = True ### Physics stuff space = pm.Space() space.gravity = Vec2d(0.0, -900.0) ## Balls balls = [] ### Mouse mouse_body = pm.Body() 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_BALL, 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: running = False elif event.type == KEYDOWN and event.key == K_ESCAPE: running = False elif event.type == KEYDOWN and event.key == K_p: pygame.image.save(screen, "balls_and_lines.png") elif event.type == MOUSEBUTTONDOWN and event.button == 1: 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 shape.collision_type = COLLTYPE_BALL space.add(body, shape) balls.append(shape) elif event.type == MOUSEBUTTONDOWN and event.button == 3: if line_point1 is None: line_point1 = Vec2d(event.pos[X], flipy(event.pos[Y])) elif event.type == MOUSEBUTTONUP and event.button == 3: if line_point1 is not None: line_point2 = Vec2d(event.pos[X], flipy(event.pos[Y])) print line_point1, line_point2 body = pm.Body() shape= pm.Segment(body, line_point1, line_point2, 0.0) shape.friction = 0.99 space.add(shape) static_lines.append(shape) line_point1 = None elif event.type == KEYDOWN and event.key == K_SPACE: run_physics = not run_physics 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 pygame.mouse.get_pressed()[0]: body = pm.Body(10, 10) body.position = mouse_pos shape = pm.Circle(body, 10, (0,0)) shape.collision_type = COLLTYPE_BALL 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 = """LMB: Create ball LMB + Shift: Create many balls RMB: 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 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()))