def grab(self): """ Grab something """ # See if we have a physics object to our right check_point = (self.player.right + 10, self.player.center_y) shape_list = self.space.point_query(check_point, 1, pymunk.ShapeFilter()) # Create a joint for an item to our right for shape in shape_list: self.grab_joint = pymunk.PinJoint(self.player.shape.body, shape.shape.body) self.space.add(self.grab_joint)
def get_block(self, x, y): """(Block) Returns a block on the point ('x', 'y'), or None if there is no block there Note: It is technically possible for multiple blocks to overlap, in which case this method will return one of those. This should never happen, though. """ blocks = self._space.point_query((x, y), 0, pymunk.ShapeFilter(mask=self._thing_categories["block"])) if blocks: return blocks[0].shape.object
def set_object_at_position_as_selected(self, pos): """ Based on the position given, select the object that is closest (with a maximum of 15) and set as selected. """ max_distance = 15 queried_object = self.space.point_query_nearest(pos, max_distance, pymunk.ShapeFilter()) if queried_object is not None: poly = queried_object.shape if hasattr(poly, 'body'): self.selected_object = poly.body
def __init__(self, distance: float, total_scanned_angle: float, beam_radius: float, resolution: int): self.distance: float = distance self.total_scanned_angle: float = total_scanned_angle self.beam_radius: float = beam_radius self.resolution: int = resolution self.scan_step_angle = total_scanned_angle / ( resolution - 1) if total_scanned_angle > 0 else 0 self.shape_filter: pymunk.shape_filter.ShapeFilter = \ pymunk.ShapeFilter(categories=EntityCategory.sensor)
def on_mouse_press(self, x, y, button, modifiers): if button == arcade.MOUSE_BUTTON_LEFT: self.last_mouse_position = x, y # See if we clicked on anything shape_list = self.space.point_query((x, y), 1, pymunk.ShapeFilter()) # If we did, remember what we clicked on if len(shape_list) > 0: self.shape_being_dragged = shape_list[0]
def spawn_collider(self): self.collider = pymunk.Circle(self.app.physics.space.static_body, self.radius, self.pos.xyz[::2]) self.collider.damage_object = self self.collider.y = self.pos.y self.collider.height = self.height self.collider.collision_type = physics.STATIC self.collider.filter = pymunk.ShapeFilter(categories=physics.STATIC_FILTER) self.app.physics.space.add(self.collider)
def _setup_shape(self): friction = 0.5 self.shape = [] star_group = self.generate_group_id() for convex_part in self.cvx_parts: shape = pm.Poly(self.body, convex_part) shape.filter = pm.ShapeFilter(group=star_group) shape.friction = friction self.shape.append(shape) del shape
def __init__(self, pos, vertices): self.body = pymunk.Body(1, 100) self.body.position = pos shape = pymunk.Poly(self.body, vertices) shape.filter = pymunk.ShapeFilter(group=1) shape.density = 0.01 shape.elasticity = 0.5 shape.color = (255, 0, 0, 0) space.add(self.body, shape)
def add_robot(space, seat): #define robot upper body and upper leg ubt = Vec2d(3.5, 0) robot_u_points = [ Vec2d(-4, 31.64) + ubt, Vec2d(-4, 0) + ubt, Vec2d(4, 0) + ubt, Vec2d(4, 31.64) + ubt ] robot_body = pymunk.Body() robot_body.position = seat.position + (0, 3) robot_u = pymunk.Poly(robot_body, robot_u_points) robot_u.mass = 3.311 robot_u.color = THECOLORS["red"] robot_u.filter = pymunk.ShapeFilter(mask=pymunk.ShapeFilter.ALL_MASKS ^ 1) robot_u_leg = pymunk.Poly(seat, [(1, 3), (-10.5, 3), (-10.5, 8), (1, 8)]) robot_u_leg.color = THECOLORS["red"] robot_u_leg.mass = 0.603 #robot_u_leg_extra = pymunk.Circle(seat,2,(5,0)) #robot_u_leg_extra.mass = 2 #define robot lower leg robot_leg = pymunk.Body() robot_leg.position = seat.position robot_l_leg = pymunk.Poly(robot_leg, [(-10.5, 5), (-10.5, -11.8), (-4.0, -11.8), (-4.0, 5)]) robot_l_leg.mass = 1.214 robot_l_leg.color = THECOLORS["red"] space.add(robot_body, robot_u, robot_u_leg, robot_leg, robot_l_leg) #motor and pivot for hip #uses measured values of angles rather than given in program seat_motor = pymunk.SimpleMotor(seat, robot_body, 0) seat_motor.max_force = 1e6 seat_pivot = pymunk.PivotJoint(seat, robot_body, robot_body.position + ubt) seat_pivot._set_collide_bodies(False) seat_pivot_lim = pymunk.RotaryLimitJoint(robot_body, seat, 0, 0.575959) space.add(seat_motor, seat_pivot, seat_pivot_lim) #motor and pivot for knee max_knee_ang = 5 max_knee_ang = np.deg2rad(max_knee_ang) knee_motor = pymunk.SimpleMotor(seat, robot_leg, 0) knee_motor.max_force = 1e5 knee_pivot = pymunk.PivotJoint(seat, robot_leg, seat.position + (-8, 7)) knee_pivot._set_collide_bodies(False) knee_pivot_lim = pymunk.RotaryLimitJoint(seat, robot_leg, max_knee_ang - np.deg2rad(69), max_knee_ang) space.add(knee_motor, knee_pivot, knee_pivot_lim) return seat_motor, knee_motor, robot_body, robot_leg, robot_u_leg
def __init__( self, space: pymunk.Space, paddle_position: Vec2d, collision_type: CollisionType, aspect_ratio: AspectRatio, mass: float = 1, paddle: Paddle = None, ): """ :param space: :param paddle_position: :param collision_type: :param aspect_ratio: :param mass: :param paddle: """ super().__init__(mass=mass, moment=pymunk.inf) self.aspect_ratio = aspect_ratio self.radius = 16 paddle_height = 16 paddle_half_height = paddle_height ball_position = Vec2d( paddle_position.x, paddle_position.y + aspect_ratio.scale_s(paddle_half_height + self.radius)) self.position = ball_position shape = pymunk.Circle(self, radius=aspect_ratio.scale_s(self.radius)) shape.elasticity = 0.98 shape.collision_type = collision_type shape.filter = pymunk.ShapeFilter(categories=2 << collision_type) self.spc = space self.on_paddle = True self.velocity_func = self.constant_velocity self.joint = pymunk.GrooveJoint( space.static_body, self, Vec2d(paddle.groove_joint.groove_a.x, ball_position.y), Vec2d(paddle.groove_joint.groove_b.x, ball_position.y), Vec2d(0, 0), ) space.add(self, shape, self.joint) self.ball_speed = 500 self.segments_q = [] self.points_on_ball = []
def __init__(self, space: pymunk.Space, collision_type_for_ball, collision_type_for_bottom, cb_loose_ball, aspect_ratio): """ :param space: :param collision_type_for_ball: :param collision_type_for_bottom: :param cb_loose_ball: call back function to reset game """ left = pymunk.Segment(space.static_body, aspect_ratio.scale(50, 50), aspect_ratio.scale(50, 800), 2) top = pymunk.Segment(space.static_body, aspect_ratio.scale(50, 800), aspect_ratio.scale(1230, 800), 2) right = pymunk.Segment(space.static_body, aspect_ratio.scale(1230, 50), aspect_ratio.scale(1230, 800), 2) left.elasticity = 1.0 right.elasticity = 1.0 top.elasticity = 1.0 bottom = pymunk.Segment(space.static_body, aspect_ratio.scale(50, 50), aspect_ratio.scale(1230, 50), 2) bottom.sensor = True bottom.collision_type = collision_type_for_bottom left.filter = pymunk.ShapeFilter( categories=2 << collision_type_for_bottom) right.filter = pymunk.ShapeFilter( categories=2 << collision_type_for_bottom) top.filter = pymunk.ShapeFilter( categories=2 << collision_type_for_bottom) bottom.filter = pymunk.ShapeFilter( categories=2 << collision_type_for_bottom) # http://www.pymunk.org/en/latest/pymunk.html#pymunk.CollisionHandler handler = space.add_collision_handler(collision_type_for_ball, collision_type_for_bottom) handler.begin = self.reset_game self.cb_loose_ball = cb_loose_ball space.add(left, top, right, bottom)
def add_ground(space): body = pymunk.Body(0, 10000, body_type=pymunk.Body.STATIC) body.position = (0, 0) ground = pymunk.Segment(body, (-600, 0), (100000000.0, 0), 5.0) ground.filter = pymunk.ShapeFilter(group=0b0) ground.friction = 1 space.add(ground, body) return ground
def __init__(self, x, y, width, height) -> None: self.body = pymunk.Body(body_type=pymunk.Body.STATIC) self.body.position = x, y self.shape = pymunk.Poly.create_box(self.body, (width, height)) self.shape.collision_type = collision_types['wall'] self.shape.elasticity = 1 self.shape.friction = 1 self.isStatic = True self.shape.color = self.color() self.shape.filter = pymunk.ShapeFilter(categories=0b10, mask=0b01) space.add(self.body, self.shape)
def addToSpace(self, space): self.robot_body = pymunk.Body(self.mass, self.inertia) self.robot_shape = pymunk.Circle(self.robot_body, self.radius) self.robot_shape.color = (255,50,50) self.robot_shape.filter = pymunk.ShapeFilter(group=2) self.shoulders = pymunk.Segment(self.robot_body, self.arm_l_0, self.arm_r_0, self.arm_width) self.shoulders.filter = pymunk.ShapeFilter(group=2) self.arm_l = pymunk.Segment(self.robot_body, self.arm_l_0, self.arm_l_1, self.arm_width) self.arm_l.filter = pymunk.ShapeFilter(group=2) self.arm_r = pymunk.Segment(self.robot_body, self.arm_r_0, self.arm_r_1, self.arm_width) self.arm_r.filter = pymunk.ShapeFilter(group=2) self.shoulders.friction = 1. self.arm_l.friction = 1. self.arm_r.friction = 1. self.robot_shape.friction = 1. self.robot_body.position = self.position self.robot_body.angle = self.angle space.add(self.robot_body, self.robot_shape, self.shoulders, self.arm_l, self.arm_r)
def addAttrs(self, shape): self.shape.friction = self.friction self.shape.elasticity = self.elasticity self.shape.rgba = self.rgba self.shape.objectType = self.objectType if (self.objectType == self.START or self.objectType == self.NOBARRIER): self.shape.sensor = True elif (self.objectType == self.FINISH): self.shape.filter = pymunk.ShapeFilter(categories=10)
def __init__(self, pos, radius=20): self.body = pymunk.Body() self.body.position = pos shape = pymunk.Circle(self.body, radius) shape.density = 0.01 shape.friction = 0.5 shape.elasticity = 1 shape.filter = pymunk.ShapeFilter(categories=0b1, mask=pymunk.ShapeFilter.ALL_MASKS() ^ 0b1) space.add(self.body, shape)
def __init__(self, size, x, y, mass, moment, friction): Member.__init__(self, mass, moment, friction) self.body.position = (x, y - 40 * size) self.body_joint.position = self.body.position self.left_leg_shape = pymunk.Segment(self.body, (-10 * size, -20 * size), (0, 0), 2 * size) self.left_leg_shape.friction = friction self.left_leg_shape.filter = pymunk.ShapeFilter( categories=0x1, mask=pymunk.ShapeFilter.ALL_MASKS ^ 0x1)
def get_shape(self, x, y): # See if we clicked on anything shape_list = self.space.point_query((x, y), 1, pymunk.ShapeFilter()) # If we did, remember what we clicked on if len(shape_list) > 0: shape = shape_list[0] else: shape = None return shape
def on_mouse_press(x, y, button, modifiers): mouse_body.position = x,y hit = space.point_query_nearest((x,y), 10, pymunk.ShapeFilter()) if hit != None: global selected body = hit.shape.body rest_length = mouse_body.position.get_distance(body.position) stiffness = 1000 damping = 10 selected = pymunk.DampedSpring(mouse_body, body, (0,0), (0,0), rest_length, stiffness, damping) space.add(selected)
def create_pymunk_robot(self, mass): length, width = 20, 30 moment = pm.moment_for_box(mass, (length, width)) body = pm.Body(mass, moment) corners = [(-length, -width), (length, -width), (length, width), (-length, width)] shape = pm.Poly(body, corners) shape.filter = pm.ShapeFilter(categories=0b1) # shape.friction = .5 #seems to have no effect shape.color = WHITE #TODO make bounding box invisible somehow return body, shape
def create_wheel(self, wheel_side): if wheel_side not in ['rear', 'front']: raise Exception('Wheel position must be front or rear') wheel_objects = [] wheel_mass = getattr(self, wheel_side + '_wheel_mass') wheel_radius = getattr(self, wheel_side + '_wheel_radius') wheel_position = getattr(self, wheel_side + '_wheel_position') wheel_friction = getattr(self, wheel_side + '_wheel_friction') wheel_elasticity = getattr(self, wheel_side + '_wheel_elasticity') wheel_damp_position = getattr(self, wheel_side + '_wheel_damp_position') wheel_damp_length = getattr(self, wheel_side + '_wheel_damp_length') wheel_damp_stiffness = getattr(self, wheel_side + '_wheel_damp_stiffness') wheel_damp_damping = getattr(self, wheel_side + '_wheel_damp_damping') wheel_body = pymunk.Body( wheel_mass, pymunk.moment_for_circle(wheel_mass, 0, wheel_radius)) wheel_body.position = (wheel_position[0] * self.x_modification, wheel_position[1]) wheel_shape = pymunk.Circle(wheel_body, wheel_radius) wheel_shape.filter = pymunk.ShapeFilter(group=self.car_group) wheel_shape.color = 255, 34, 150 wheel_shape.friction = wheel_friction wheel_shape.elasticity = wheel_elasticity wheel_objects.append(wheel_shape) wheel_grove = pymunk.GrooveJoint( self.car_body, wheel_body, (wheel_damp_position[0] * self.x_modification, wheel_damp_position[1]), (wheel_damp_position[0] * self.x_modification, wheel_damp_position[1] - wheel_damp_length * 1.5), (0, 0)) wheel_objects.append(wheel_grove) wheel_damp = pymunk.DampedSpring( wheel_body, self.car_body, anchor_a=(0, 0), anchor_b=(wheel_damp_position[0] * self.x_modification, wheel_damp_position[1]), rest_length=wheel_damp_length, stiffness=wheel_damp_stiffness, damping=wheel_damp_damping) wheel_objects.append(wheel_damp) wheel_motor = None if (wheel_side == 'rear' and self.drive in [self.AWD, self.FR]) or ( wheel_side == 'front' and self.drive in [self.AWD, self.FF]): wheel_motor = pymunk.SimpleMotor(wheel_body, self.car_body, 0) return wheel_body, wheel_motor, wheel_objects
def generateBodyAndShape(self, physObj, body=None, rel_pos=(0, 0)): if body is None: moment = pymunk.moment_for_circle(physObj.mass, 0, self.radius) body = pymunk.Body(physObj.mass, moment, body_type=pymunk.Body.STATIC if physObj.static else pymunk.Body.DYNAMIC) shape = pymunk.Circle(body, self.radius, offset=rel_pos) shape.friction = physObj.friction_coefficient shape.elasticity = physObj.restitution_coefficient shape.collision_type = 1 from ev3sim.objects.base import STATIC_CATEGORY, DYNAMIC_CATEGORY shape.filter = pymunk.ShapeFilter(categories=STATIC_CATEGORY if physObj.static else DYNAMIC_CATEGORY) return body, shape
def punch(self): # --- Punch left # See if we have a physics object to our right self.check_point = (self.player.right + 10, self.player.center_y) shape_list = self.space.point_query(self.check_point, 1, pymunk.ShapeFilter()) # Apply force to any object to our right for shape in shape_list: shape.shape.body.apply_impulse_at_world_point((PLAYER_PUNCH_IMPULSE, PLAYER_PUNCH_IMPULSE), self.check_point) # --- Punch right # See if we have a physics object to our left self.check_point = (self.player.left - 10, self.player.center_y) shape_list = self.space.point_query(self.check_point, 1, pymunk.ShapeFilter()) # Apply force to any object to our right for shape in shape_list: shape.shape.body.apply_impulse_at_world_point((-PLAYER_PUNCH_IMPULSE, PLAYER_PUNCH_IMPULSE), self.check_point)
def handleEvent(self, event): if event.type == pygame.MOUSEBUTTONDOWN and event.button == 1: m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( m_pos, 0.0, pymunk.ShapeFilter(mask=pymunk.ShapeFilter.ALL_MASKS ^ STATIC_CATEGORY)) if len(shapes) > 0: self.obj = shapes[0].shape.obj self.obj.body.velocity = np.array([0.0, 0.0]) self.obj_grabbed = True self.obj_rel_pos = self.obj.position - m_pos self.obj_m_pos = m_pos if event.type == pygame.MOUSEBUTTONDOWN and event.button == 3: # If a robot is right clicked, copy it's ID for use in the attach script. m_pos = screenspace_to_worldspace(event.pos) shapes = World.instance.space.point_query( m_pos, 0.0, pymunk.ShapeFilter(mask=pymunk.ShapeFilter.ALL_MASKS ^ STATIC_CATEGORY)) if len(shapes) > 0: self.obj = shapes[0].shape.obj if hasattr(self.obj, "robot_class"): pyperclip.copy(self.obj.robot_class.ID) if event.type == pygame.MOUSEBUTTONUP and event.button == 1 and self.obj_grabbed: self.obj_grabbed = False # Give velocity based on previous mouse positions. if self.position_length != 0: differences = sum( (x + 1) / self.position_length * (self.positions[ (self.position_index + x + 1) % self.TOTAL_POSITIONS] - self.positions[ (self.position_index + x) % self.TOTAL_POSITIONS]) for x in range(self.position_length - 1)) # Sum will return 0 if position length is 0 - we need to handle this. if isinstance(differences, int): differences = np.array([0, 0]) self.obj.body.velocity = self.VELOCITY_MULT * differences if event.type == pygame.MOUSEMOTION and self.obj_grabbed: self.obj_m_pos = screenspace_to_worldspace(event.pos)
def testPointQueryNearest(self): s = p.Space() b1 = p.Body(1, 1) b1.position = 19, 0 s1 = p.Circle(b1, 10) s.add(s1) hit = s.point_query_nearest((23, 0), 0, p.ShapeFilter()) self.assertEqual(hit.shape, s1) self.assertEqual(hit.point, (29, 0)) self.assertEqual(hit.distance, -6) self.assertEqual(hit.gradient, (1, 0)) hit = s.point_query_nearest((30, 0), 0, p.ShapeFilter()) self.assertEqual(hit, None) hit = s.point_query_nearest((30, 0), 10, p.ShapeFilter()) self.assertEqual(hit.shape, s1) self.assertEqual(hit.point, (29, 0)) self.assertEqual(hit.distance, 1) self.assertEqual(hit.gradient, (1, 0))
def create_button_shape(self): if not self.car_body: raise Exception('Create car body before') button_shape = pymunk.Poly(self.car_body, list(map(lambda x: (x[0] * self.x_modification, x[1]), self.get_button_poly()))) button_shape.color = 23, 230, 230 button_shape.filter = pymunk.ShapeFilter(group=self.car_group) button_shape.sensor = True button_shape.collision_type = self.button_collision_type return button_shape
def ray_cast(start, end, callback): """ :param start: начальная точка отрезка :param end: конец отрезка :param callback: метод обратного вызова, если возвращает True, то продолжает луч, иначе обрывает его """ s = GameManager.instance().get_space().segment_query( start, end, 0, pymunk.ShapeFilter(mask=pymunk.ShapeFilter.ALL_MASKS)) for shape in s: if not callback(shape[0].body.data): return
def __init__(self, creature, sensor_range): self._shape = pymunk.Circle(creature.body, sensor_range, (0, 0)) self._shape.collision_type = Simulation.SOUND_SENSOR_COLLISION_TYPE self.shape.filter = pymunk.ShapeFilter( categories=(1 << (Simulation.SOUND_SENSOR_COLLISION_TYPE - 1))) self._shape.sensor = True self._shape.creature = creature creature.body.space.add(self._shape)
def buildDistanceMap(space, range_x, steps_x, range_y, steps_y): dist_map = np.zeros( (steps_y, steps_x) ) ix = 0 for x in np.linspace(range_x[0], range_x[1], steps_x, endpoint=True): iy = 0 for y in np.linspace(range_y[0], range_y[1], steps_y, endpoint=True): pq = space.point_query_nearest((x,y), pymunk.inf, pymunk.ShapeFilter(group=2)) if pq.distance > 0: dist_map[iy, ix] = pq.distance iy += 1 ix += 1 return dist_map
def __init__(self, p0, v, m=10, radius=2): self.body = pymunk.Body() self.body.position = p0 shape = pymunk.Segment(self.body, (0, 0), v, radius) shape.mass = m shape.density = 0.1 shape.elasticity = 0.5 shape.filter = pymunk.ShapeFilter(categories=0b1, mask=pymunk.ShapeFilter.ALL_MASKS() ^ 1) shape.color = (0, 255, 0, 0) space.add(self.body, shape)