def add_circle(self, x, y, radius): # create a falling circle body = cy.Body(100, 1e9) body.position = x, y circle = cy.Circle(body, radius) circle.elasticity = 0.6 #circle.friction = 1.0 self.space.add(body, circle) with self.canvas.before: self._hue = (self._hue + 0.01) % 1 color = Color(self._hue, 1, 1, mode='hsv') rect = Rectangle(texture=self.texture, pos=(self.x - radius, self.y - radius), size=(radius * 2, radius * 2)) self.cmap[body] = (radius, color, rect) # remove the oldest one self.blist.append((body, circle)) if len(self.blist) > 200: body, circle = self.blist.pop(0) self.space.remove(body) self.space.remove(circle) radius, color, rect = self.cmap.pop(body) self.canvas.before.remove(color) self.canvas.before.remove(rect)
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()))
for s in ss: s.friction = .5 s.layers = s.layers ^ 0b100 space.add(ss) ### WEB web_group = 1 web_collision_type = 1 web_layers = 0b101 bs = [] dist = .3 cb = pymunk.Body(1, 1) cb.position = c s = pymunk.Circle(cb, 15) # to have something to grab s.group = web_group s.layers = web_layers s.collision_type = web_collision_type #s.ignore_draw = True space.add(cb, s) #generate each crossing in the net for x in range(0, 101): b = pymunk.Body(1, 1) v = Vec2d.unit() v.angle_degrees = x * 18 scale = window.height / 2. / 6. * .5 dist += 1 / 18. dist = dist**1.005
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()))