Пример #1
0
    def _cb_remove_brick(self, arbiter: pymunk.Arbiter, space: pymunk.Space,
                         data):
        """
        callback function

        :param arbiter:
        :param space:
        :param data:
        :return:
        """
        brick_shape = arbiter.shapes[0]
        space.remove(brick_shape, brick_shape.body)
Пример #2
0
 def remove(self, space: pymunk.Space):
     for pivot in self.pivots:
         space.remove(pivot)
     for muscle in self.muscles:
         space.remove(muscle)
     Creature.__remove(self, space)
Пример #3
0
 def __remove(part, space: pymunk.Space):
     space.remove(part.body)
     space.remove(part.shape)
     for limb in part.limbs:
         Creature.__remove(limb, space)
Пример #4
0
class WorldState:
    """
    Contains the objects, the robots and the surrounding space of the 'world'
    """
    def __init__(self, config):
        self.sprite_list = _arcade.SpriteList()
        self.obstacles = []
        self.static_obstacles = []
        self.falling_obstacles = []
        self.color_obstacles = []

        self.robots = []
        self.space = Space()
        self.space.damping = 0.1

        self.board_width = config['board_width']
        self.board_height = config['board_height']
        board_color = tuple(config['board_color'])

        board = Board(self.board_width / 2, self.board_height / 2,
                      self.board_width, self.board_height, board_color)
        self.static_obstacles.append(board)

        for robot_conf in config['robots']:
            self.robots.append(RobotState(robot_conf))

        edge = Edge(self.board_width, self.board_height)
        self.static_obstacles.append(edge)
        self.falling_obstacles.append(edge)

        for obstacle in config['obstacles']:
            if obstacle['type'] == 'lake':
                lake = Lake.from_config(obstacle)
                self.static_obstacles.append(lake)
                if lake.hole is not None:
                    self.falling_obstacles.append(lake.hole)
                self.color_obstacles.append(lake)
            elif obstacle['type'] == 'rock':
                rock = Rock.from_config(obstacle)
                self.obstacles.append(rock)
            elif obstacle['type'] == 'border':
                border = Border.from_config(self.board_width,
                                            self.board_height, obstacle)
                self.static_obstacles.append(border)
                self.color_obstacles.append(border)
            elif obstacle['type'] == 'bottle':
                bottle = Bottle.from_config(obstacle)
                self.obstacles.append(bottle)
            else:
                print("unknown obstacle type")

        self.falling_obstacles.append(board)
        self.color_obstacles.append(board)

        self.selected_object = None

    def reset(self):
        """
        Reset all obstacles in the world (except robots) to their original position.
        """
        for obstacle in self.obstacles:
            obstacle.reset()

    def setup_pymunk_shapes(self, scale):
        """
        Setup the shapes that are added to the pymunk space.
        The robot get a shape filter so it does not interact with itself.
        """
        for idx, robot in enumerate(self.robots):
            robot_shapes = robot.setup_pymunk_shapes(scale)
            for shape in robot_shapes:
                shape.filter = pymunk.ShapeFilter(group=idx + 5)
                self.space.add(shape)
            self.space.add(robot.body)

        for obstacle in self.obstacles:
            obstacle.create_shape(scale)
            self.space.add(obstacle.body)
            self.space.add(obstacle.shape)

    def rescale(self, new_scale):
        """
        On screen rescale, rescale all sprites.
        """
        for robot in self.robots:
            robot.shapes = []
        for obstacle in self.obstacles:
            obstacle.shape = None
        self.space.remove(self.space.shapes)
        self.space.remove(self.space.bodies)

        for robot in self.robots:
            robot.sprite_list = _arcade.SpriteList()
        self.sprite_list = _arcade.SpriteList()
        self.setup_pymunk_shapes(new_scale)
        self.setup_visuals(new_scale)

    def setup_visuals(self, scale):
        """
        Setup all sprites.
        """
        for obstacle in self.static_obstacles:
            obstacle.create_shape(scale)

        for obstacle in self.obstacles:
            obstacle.create_sprite(scale)
            self.sprite_list.append(obstacle.sprite)

        for robot in self.robots:
            robot.setup_visuals(scale)
            robot.set_color_obstacles(self.color_obstacles)
            robot.set_falling_obstacles(self.falling_obstacles)

    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 move_selected_object(self, delta_x, delta_y):
        """
        Move the selected object with the given offset.
        """
        if self.selected_object:
            self.selected_object.position += (delta_x, delta_y)

    def rotate_selected_object(self, delta_angle):
        """
        Rotate the selected object with the given angle.
        """
        if self.selected_object is not None:
            self.selected_object.angle += radians(delta_angle)

    def unselect_object(self):
        """
        Deselect the previously selected object.
        """
        self.selected_object = None

    def get_robots(self) -> [RobotState]:
        """
        Gets the objects that are on the playing field.
        """
        return self.robots
Пример #5
0
class World(PyxelWorld):
    def __init__(self):
        super().__init__()
        self.space = Space(threaded=True)
        self.space.collision_slop = 0.7
        self.iter = 0
        self.time = 0.0
        self.on_reset = []
        self.P, self.I, self.D = 4.25347222, 0.0001041666, -4.67881944
        self.I = 0.0

        y = 0
        L = 500
        self.ground = self.line(-L,
                                y,
                                L,
                                y,
                                static=True,
                                friction=0.75,
                                radius=5)
        handler = self.space.add_wildcard_collision_handler(1)
        handler.begin = self.on_collision

    def update(self):
        dt = 1 / 30
        with LOCK:
            self.space.step(dt)
            self.time += dt

    def on_collision(self, arbiter, space, data):
        for fn in self.on_reset:
            fn(self)
        return True

    def reset(self):
        global segway

        self.time = 0.0
        self.iter += 1
        self.clear()
        ctrl.object = segway = self.segway()

    def clear(self):
        for shape in self.space.shapes:
            if shape not in self.ground.shapes:
                self.space.remove(shape)

        for cons in self.space.constraints:
            self.space.remove(cons)

        for body in self.space.bodies:
            if body is not self.ground:
                self.space.remove(body)

    def segway(self):
        R = 12
        L = 60
        segway = self.circ(0, R, R, mass=1, moment=1, friction=2.0)
        arm = self.line(0, R, 0, R + L, mass=2, moment=50)
        head = self.circ(0,
                         R + L,
                         R,
                         mass=8,
                         moment=8,
                         velocity=(-1, 0),
                         friction=0.1)
        self.pin([head, arm], collide=False)

        next(iter(head.shapes)).collision_type = 1

        self.pin([segway, arm], anchor=(0, -L / 2), collide=False)

        segway.update = iter(self.pid(segway, arm)).__next__
        segway.radius = R
        segway.arm = arm
        segway.head = head
        return segway

    def pid(self, wheel, arm):
        P, I, D = self.P, self.I, self.D
        cte = 100
        R = wheel.radius
        err_ = 0.0
        err_i = 0.0
        gamma = 0.02

        while True:
            err = arm.angle
            err_i = err + 0.9 * err_i
            err_d = err - err_

            w = cte * (P * err - I * err_i - D * err_d)
            if w == 0:
                F = 0
            else:
                F = 100 * (1 if w > wheel.angular_velocity else -1)
            F -= gamma * abs(F) * wheel.angular_velocity

            wheel.apply_force_at_local_point((0, +F), (+R, 0))
            wheel.apply_force_at_local_point((0, -F), (-R, 0))
            err_ = err
            yield
Пример #6
0
class PlatformerScene(Scene):
    def __init__(self, game):
        super().__init__(game)
        self.player = None
        self.active = True

        self.geometry = list()
        self.space = Space()
        self.space.gravity = (0, 1000)
        self.sprites = LayeredUpdates()
        self.event_handler = event_handling.EventQueueHandler()
        self.background = resources.gfx("background.png", convert=True)
        self.load()
        pygame.mixer.music.load(resources.music_path("zirkus.ogg"))
        pygame.mixer.music.play(-1)

    def add_static(self, vertices, rect):
        body = pymunk.Body(body_type=pymunk.Body.STATIC)
        body.position = rect.x, rect.y
        shape = pymunk.Poly(body, vertices)
        shape.friction = 1.0
        shape.elasticity = 1.0
        self.space.add(body, shape)

    def load(self):
        def box_vertices(x, y, w, h):
            lt = x, y
            rt = x + w, y
            rb = x + w, y + h
            lb = x, y + h
            return lt, rt, rb, lb

        filename = path_join("data", "maps", "untitled.tmx")
        tmxdata = pytmx.util_pygame.load_pygame(filename)
        for obj in tmxdata.objects:
            if obj.type == map_fixed:
                rect = Rect(obj.x, obj.y, obj.width, obj.height)
                vertices = box_vertices(0, 0, obj.width, obj.height)
                self.add_static(vertices, rect)

            elif obj.type == map_yarn_spawn:
                ball = sprite.Ball(Rect((obj.x, obj.y), (32, 32)))
                model = BasicModel()
                model.sprites = [ball]
                model.pymunk_objects = ball.pymunk_shapes
                self.add_model(model)
                self.player = model

            elif obj.type == map_player_spawn:
                self.player = unicyclecat.build(self.space, self.sprites)
                self.player.position = obj.x, obj.y

        self.fsm = SimpleFSM(control, "idle")

    def add_model(self, model):
        self.sprites.add(*model.sprites)
        self.space.add(model.pymunk_objects)

    def remove_model(self, model):
        self.sprites.remove(*model.sprites)
        self.space.remove(model.pymunk_objects)

    def render(self):
        surface = self._game.screen
        surface.blit(self.background, (0, 0))
        self.sprites.draw(surface)
        return [surface.get_rect()]

    def tick(self, dt):
        step_amount = (1 / 30.) / 30
        for i in range(30):
            self.space.step(step_amount)
        self.sprites.update(dt)

    def event(self, pg_event):
        events = self.event_handler.process_event(pg_event)
        position = self.player.position

        for event in events:
            try:
                cmd, arg = self.fsm((event.button, event.held))
            except ValueError as e:
                continue

            if cmd == "move":
                resources.sfx("cat_wheel.ogg", False, True)
                resources.sfx("cat_wheel.ogg", True)
                self.player.accelerate(arg)

            if cmd == "idle":
                self.player.brake()

            elif cmd == "jump":
                resources.sfx("cat_jump.ogg", True)
                self.player.main_body.apply_impulse_at_world_point((0, -600),
                                                                   position)
Пример #7
0
 def pre_solve(arb: p.Arbiter, space: p.Space, data: Any) -> bool:
     space.remove(*arb.shapes)
     return True
Пример #8
0
 def pre_solve_remove(arb: p.Arbiter, space: p.Space, data: Any) -> bool:
     space.remove(b, c)
     space.remove(c, b)
     self.assertTrue(b in s.bodies)
     self.assertTrue(c in s.shapes)
     return True