Пример #1
0
    def draw(self, screen, camera, image_handler):
        color = self.color_selected if self.selected else self.color
        camera.draw_text(screen,
                         self.text,
                         self.position + 0.63 * basis(1),
                         0.75,
                         color=color,
                         chromatic_aberration=self.selected)

        val_str = str(self.values[self.selection]).replace(', ',
                                                           'x').strip('()')
        camera.draw_text(screen,
                         val_str,
                         self.position,
                         0.75,
                         color=color,
                         chromatic_aberration=self.selected)

        if self.selected:
            if self.cyclic or self.selection > 0:
                camera.draw_triangle(screen,
                                     self.position - 1.5 * basis(0),
                                     0.75,
                                     chromatic_aberration=True)
            if self.cyclic or self.selection < len(self.values) - 1:
                camera.draw_triangle(screen,
                                     self.position + 1.5 * basis(0),
                                     0.75,
                                     np.pi,
                                     chromatic_aberration=True)
Пример #2
0
    def update_joints(self):
        w = normalized(self.body.collider.half_width) * self.direction
        h = normalized(self.body.collider.half_height)

        foot_offset = 0.3 * ((self.front_foot.relative_position[1]) +
                             (self.back_foot.relative_position[1])) * basis(1)

        self.body.set_position(self.position - 0.5 * self.crouched * basis(1) +
                               foot_offset)

        self.shoulder = self.body.position + 0.15 * (
            1 - self.crouched) * h - 0.2 * w

        self.back_hip = self.body.position - foot_offset + 0.1 * w - 0.45 * h
        self.front_hip = self.body.position - foot_offset - 0.1 * w - 0.45 * h

        if self.destroyed:
            angle_goal = self.body.angle
        else:
            angle_goal = np.arctan(self.hand_goal[1] /
                                   (self.hand_goal[0] + 1e-6))

        angle_goal = max(self.body.angle - 0.25,
                         min(self.body.angle + 0.25, angle_goal))
        self.head.angle += 0.1 * (angle_goal - self.head.angle)
        self.head.set_position(self.body.position -
                               (1 - self.crouched) * 0.35 *
                               (self.head.angle - self.body.angle) * w *
                               self.direction + 0.2 * self.crouched * w +
                               (1 - 0.5 * self.crouched) * h)
Пример #3
0
    def draw(self, screen, camera, image_handler):
        if not self.image_path:
            return

        if self.vertical:
            h = self.collider.half_height[1]
            ny = int(2 * h)

            for j, y in enumerate(np.linspace(-h, h, ny, False)):
                if j == 0:
                    l = 2
                elif j == ny - 1:
                    l = 0
                else:
                    l = 1

                pos = self.position + self.image_position + y * basis(1)
                image = image_handler.images[
                    f'{self.image_path}_vertical_0_{l}']
                camera.draw_image(screen, image, pos, 1, 1, 0.0)
        else:
            w = self.collider.half_width[0]
            nx = int(2 * w)

            for i, x in enumerate(np.linspace(-w, w, nx, False)):
                if i == 0:
                    k = 0
                elif i == nx - 1:
                    k = 2
                else:
                    k = 1

                pos = self.position + self.image_position + x * basis(0)
                image = image_handler.images[f'{self.image_path}_{k}_{0}']
                camera.draw_image(screen, image, pos, 1, 1, 0.0)
Пример #4
0
 def __init__(self, position, resolution):
     self.position = np.array(position, dtype=float)
     self.max_zoom = resolution[1] / 720 * 50.0
     self.zoom = self.max_zoom
     self.half_width = 0.5 * resolution[0] * basis(0)
     self.half_height = 0.5 * resolution[1] * basis(1)
     self.shake = np.zeros(2)
     self.velocity = np.zeros(2)
Пример #5
0
    def __init__(self, position, width, height):
        super().__init__(position, image_path='wall')
        self.add_collider(Rectangle([0, 0], width, height, Group.WALLS))
        self.size = 1.0
        self.vertical = False

        self.image_position = 0.5 * basis(0) + 0.04 * basis(1)
        if width == 1:
            self.vertical = True
            self.image_position = np.array([0.0, 0.52])
Пример #6
0
    def __init__(self, option_handler):
        self.option_handler = option_handler
        self.state = State.MENU

        self.level = Level()
        self.players = dict()
        self.colliders = []

        self.time_scale = 1.0

        self.camera = Camera([0, 0], self.option_handler.resolution)

        self.respawn_time = 50.0

        self.menu = MainMenu()
        self.player_menus = [
            PlayerMenu((6 * i - 9) * basis(0)) for i in range(4)
        ]
        self.options_menu = OptionsMenu()
        self.options_menu.set_values(self.option_handler)

        self.network = None
        self.network_id = -1
        self.obj_id = -1

        self.controller_id = 0
Пример #7
0
    def update_occupied_squares(self, colliders):
        self.clear_occupied_squares(colliders)

        pos = self.position
        w = axis_half_width(self.half_width, self.half_height, basis(0))
        h = axis_half_width(self.half_width, self.half_height, basis(1))

        for i in range(int((pos[0] - w) / GRID_SIZE),
                       min(int((pos[0] + w) / GRID_SIZE) + 1, len(colliders))):
            for j in range(
                    int((pos[1] - h) / GRID_SIZE),
                    min(int((pos[1] + h) / GRID_SIZE) + 1, len(colliders[i]))):
                self.occupied_squares.append((i, j))

        for i, j in self.occupied_squares:
            colliders[i][j].append(self)
Пример #8
0
    def draw_triangle(self,
                      screen,
                      position,
                      size,
                      angle=0,
                      color=(255, 255, 255),
                      chromatic_aberration=False):
        a = size * rotate(np.array([0, 0.5]), angle)
        b = size * rotate(np.array([0, -0.5]), angle)
        c = size * rotate(np.array([np.sqrt(3) / 2, 0]), angle)

        if chromatic_aberration:
            offset = 0.05 * size * basis(0)

            points = [
                self.world_to_screen(-self.zoom / 100 * p + position - offset)
                for p in [a, b, c]
            ]
            pygame.draw.polygon(screen, (255, 0, 0), points)

            points = [
                self.world_to_screen(-self.zoom / 100 * p + position + offset)
                for p in [a, b, c]
            ]
            pygame.draw.polygon(screen, (0, 255, 255), points)

        points = [
            self.world_to_screen(-self.zoom / 100 * p + position)
            for p in [a, b, c]
        ]
        pygame.draw.polygon(screen, color, points)
Пример #9
0
    def destroy(self, colliders):
        if self.destroyed:
            return

        self.hand.gravity_scale = 1.0
        self.back_foot.gravity_scale = 1.0
        self.front_foot.gravity_scale = 1.0

        self.velocity += 0.5 * basis(1)
        self.bounce = 0.5
        self.angular_velocity = -0.125 * np.sign(self.velocity[0])
        self.destroyed = True
        if self.object:
            self.throw_object(0)
        self.hand.image_path = 'hand'
        self.hand.image_position[:] = np.zeros(2)
        self.timer = 0.0

        self.collider.group = Group.DEBRIS

        if not self.head.destroyed:
            self.head.collision_enabled = False

        self.body.collision_enabled = False
        self.collider.half_height[1] = 0.75
Пример #10
0
    def draw(self, screen, camera, image_handler):
        self.back_foot.image_path = f'foot_{self.body_type}'
        self.back_foot.draw(screen, camera, image_handler)
        self.draw_limb(self.back_hip, self.back_foot.position, self.leg_length,
                       screen, camera, image_handler, 'leg', 'knee', -1)

        if not self.destroyed and self.back_hand.image_path:
            self.draw_limb(self.shoulder + 0.25 * self.direction * basis(0),
                           self.back_hand.position, 1.0, screen, camera,
                           image_handler, 'arm', 'elbow')

        self.body.draw(screen, camera, image_handler)

        self.front_foot.image_path = f'foot_{self.body_type}'
        self.front_foot.draw(screen, camera, image_handler)
        self.draw_limb(self.front_hip, self.front_foot.position,
                       self.leg_length, screen, camera, image_handler, 'leg',
                       'knee', -1)

        self.head.draw(screen, camera, image_handler)

        if self.object and self.object.collider:
            if self.object.collider.group is Group.SHIELDS:
                self.draw_limb(self.shoulder, self.hand.position,
                               self.arm_length, screen, camera, image_handler,
                               'arm', 'elbow')
                self.object.draw(screen, camera, image_handler)
            elif self.back_hand.image_path:
                pos = self.object.get_hand_position()
                self.draw_limb(self.shoulder, pos, self.arm_length, screen,
                               camera, image_handler, 'arm', 'elbow')

                if type(self.object) is Bow and self.attack_charge:
                    self.object.arrow.draw(screen, camera, image_handler)

                self.object.draw(screen, camera, image_handler)

                self.back_hand.angle = self.object.angle
                self.back_hand.draw(screen, camera, image_handler)

                self.hand.draw(screen, camera, image_handler)
            else:
                self.object.draw(screen, camera, image_handler)
                self.draw_limb(self.shoulder, self.hand.position,
                               self.arm_length, screen, camera, image_handler,
                               'arm', 'elbow')
                self.hand.draw(screen, camera, image_handler)
        else:
            self.draw_limb(self.shoulder, self.hand.position, self.arm_length,
                           screen, camera, image_handler, 'arm', 'elbow')
            self.hand.draw(screen, camera, image_handler)

        for b in self.particle_clouds:
            b.draw(screen, camera, image_handler)
Пример #11
0
    def overlap(self, other):
        overlap = np.zeros(2)

        if type(other) is Circle:
            dist = norm2(self.position - other.position)
            if dist > (self.radius + other.radius)**2:
                return overlap

            if dist == 0.0:
                overlap = (self.radius + other.radius) * basis(1)
            else:
                dist = np.sqrt(dist)
                unit = (self.position - other.position) / dist
                overlap = (self.radius + other.radius - dist) * unit
        elif type(other) is Rectangle:
            overlap = -other.overlap(self)

        return overlap
Пример #12
0
    def __init__(self, position):
        super().__init__(position, image_path='', size=0.8)
        self.image_position = 0.15 * basis(0)

        self.add_collider(Circle([0, 0], 0.1, Group.DEBRIS))
        self.gravity_scale = 0.0

        self.add_animation(0.3 * np.ones(1), np.zeros(1), np.zeros(1), 'idle')

        xs = 0.3 * np.ones(4)
        ys = np.array([0, 0.25, 0.3, 0.32])
        angles = np.array([0, -0.25, -0.25, -0.25])
        self.add_animation(xs, ys, angles, 'jump')

        xs = 0.25 * np.array([3, 2, 1, 0, 0.5, 1, 2, 2.5, 3])
        ys = 0.25 * np.array([0, 0, 0, 0, 0.5, 1, 1, 0.5, 0])
        angles = 0.25 * np.array([0, 0, 0, 0, -1, -1, -1, 0, 0])
        self.add_animation(xs, ys, angles, 'walk')

        self.loop_animation('idle')
Пример #13
0
    def draw(self, screen, image_handler):
        if self.state in [State.PLAY, State.LAN]:
            screen.fill((0, 0, 0))
            screen.blit(
                self.level.background,
                self.camera.world_to_screen(np.array([0, self.level.height])))

            if self.option_handler.shadows:
                self.level.draw_shadow(screen, self.camera, image_handler)
                for p in self.players.values():
                    p.draw_shadow(screen, self.camera, image_handler,
                                  self.level.light)

            self.level.draw(screen, self.camera, image_handler)

            for player in self.players.values():
                player.draw(screen, self.camera, image_handler)

            if self.option_handler.debug_draw:
                self.debug_draw(screen, image_handler)
        elif self.state is State.MENU:
            screen.fill((50, 50, 50))
            self.menu.draw(screen, self.camera, image_handler)
        elif self.state is State.PLAYER_SELECT:
            screen.fill((50, 50, 50))
            for pm in self.player_menus:
                pm.draw(screen, self.camera, image_handler)
                if pm.controller_id is not None:
                    self.players[pm.controller_id].set_position(pm.position +
                                                                3 * basis(1))
                    self.players[pm.controller_id].on_ground = True
                    self.players[pm.controller_id].animate(0.0)
                    self.players[pm.controller_id].draw(
                        screen, self.camera, image_handler)
        elif self.state is State.OPTIONS:
            screen.fill((50, 50, 50))
            self.options_menu.draw(screen, self.camera, image_handler)
Пример #14
0
    def damage(self, amount, colliders):
        self.parent.damage(amount, colliders)
        self.blood.append(((np.random.random() - 0.5) * basis(1),
                           2 * np.pi * np.random.random()))

        return BloodSplatter
Пример #15
0
    def update(self, gravity, time_step, colliders):
        if self.health <= 0:
            self.destroy(colliders)

        if norm(self.camera_shake) < time_step:
            self.camera_shake = np.zeros(2)
        else:
            self.camera_shake *= -0.5

        for b in self.particle_clouds:
            b.update(gravity, time_step)
            if not b.active:
                self.particle_clouds.remove(b)

        if self.destroyed:
            self.update_ragdoll(gravity, time_step, colliders)
            self.update_joints()
            return

        self.grab_timer = max(0, self.grab_timer - time_step)

        if self.velocity[1] != 0:
            self.on_ground = False

        delta_pos = self.velocity * time_step  # + 0.5 * self.acceleration * time_step**2
        self.position += delta_pos

        self.collider.position += delta_pos

        self.collider.update_occupied_squares(colliders)
        self.head.collider.update_occupied_squares(colliders)
        self.body.collider.update_occupied_squares(colliders)

        self.collider.update_collisions(colliders)

        if not self.collision_enabled:
            return

        for collision in self.collider.collisions:
            obj = collision.collider.parent
            if not obj.collision_enabled:
                continue

            if obj.collider.group is Group.PLATFORMS:
                if self.position[1] - self.collider.half_height[1] - delta_pos[1] \
                        < obj.position[1] + obj.collider.half_height[1] + 0.5 * gravity[1] * time_step**2:
                    continue

            if collision.overlap[1] > 0:
                if self.velocity[1] < -0.1:
                    self.goal_crouched = -0.5 * self.velocity[1] / time_step
                    self.sounds.add('bump')
                    self.sounds.add('walk')
                self.on_ground = True
                self.velocity[1] = 0.0
            elif collision.overlap[1] < 0:
                if self.velocity[1] > 0.1:
                    self.sounds.add('bump')
                self.velocity[1] *= -1

            self.position += collision.overlap

            self.collider.position += collision.overlap

            if not collision.overlap[1]:
                self.velocity[0] = 0.0

        self.acceleration[:] = gravity

        if np.any(self.goal_velocity[0]):
            self.acceleration[0] = (self.goal_velocity[0] -
                                    self.velocity[0]) * self.walk_acceleration
        else:
            self.acceleration[0] = (self.goal_velocity[0] - self.velocity[0]
                                    ) * 2 * self.walk_acceleration

        self.velocity += self.acceleration * time_step

        self.speed = norm(self.velocity)
        if self.speed > 0:
            self.velocity *= min(self.speed, MAX_SPEED) / self.speed

        self.crouched += (self.goal_crouched -
                          self.crouched) * self.crouch_speed * time_step

        self.body.rotate(-0.5 * self.velocity[0] -
                         0.5 * self.direction * self.crouched -
                         self.body.angle)

        self.update_joints()

        self.collider.position[1] = self.position[1] - 0.5 * self.crouched
        self.collider.half_height[1] = 1.5 - 0.5 * self.crouched

        d = self.hand_goal[0]
        if abs(d) > 0.1 and np.sign(d) != self.direction:
            self.flip_horizontally()

        r = self.hand.position - self.shoulder

        if abs(r[0]) > 0.1:
            self.hand.angular_velocity = 0.5 * (np.arctan(r[1] / r[0]) -
                                                self.hand.angle)
        else:
            self.hand.angular_velocity = 0.0

        self.animate(time_step)

        # purkka
        if self.back_hand.image_path:
            self.back_hand.set_position(self.object.get_grip_position())

        if self.object:
            self.object.set_position(self.object.position +
                                     time_step * self.velocity)
            if self.object.collider:
                self.object.collider.update_occupied_squares(colliders)
            hand_pos = self.shoulder + (
                1 - 0.5 * self.throw_charge) * self.hand_goal
            self.object.velocity = 0.5 * (
                hand_pos - self.object.position) - 0.125 * gravity * basis(1)

            if not self.object.collider:
                self.throw_object()
                return

            if self.object.collider.group in {
                    Group.GUNS, Group.SHIELDS, Group.SWORDS
            }:
                if abs(d) > 0.1 and np.sign(d) != self.object.direction:
                    self.object.flip_horizontally()
                self.hand.set_position(hand_pos)
                self.hand.velocity[:] = np.zeros(2)

                if type(self.object) not in {Bow, Shield, Grenade
                                             } and self.object.timer > 0:
                    if self.object.hit:
                        self.hand.play_animation('idle')
                    self.hand.animate(time_step)
                    self.object.set_position(self.hand.position)

                    # experimental
                    PhysicsObject.update(self.object, gravity, time_step,
                                         colliders)
                    self.hand.set_position(self.object.position)
                    self.hand.velocity[:] = np.zeros(2)

                self.object.rotate(self.hand.angle - self.object.angle)

            if norm(self.shoulder -
                    self.object.position) > 1.6 * self.arm_length:
                if isinstance(self.object, Weapon):
                    self.object.set_position(self.position)
                    self.object.collider.update_occupied_squares(colliders)
                    self.hand.set_position(self.object.position)
                    self.hand.velocity[:] = np.zeros(2)
                else:
                    self.throw_object(0.0)
            else:
                self.hand.set_position(self.object.position)
                self.hand.velocity[:] = np.zeros(2)
                self.hand.update(gravity, time_step, colliders)
        else:
            self.hand.set_position(self.hand.position +
                                   time_step * self.velocity)
            self.hand.velocity = self.shoulder + self.hand_goal - self.hand.position - 0.185 * gravity * basis(
                1)
            self.hand.update(gravity, time_step, colliders)
            self.hand.collider.update_occupied_squares(colliders)
            self.hand.collider.update_collisions(
                colliders,
                {Group.PROPS, Group.GUNS, Group.SHIELDS, Group.SWORDS})
Пример #16
0
    def __init__(self, position=(0, 0), controller_id=0, network_id=0):
        super().__init__(position)
        self.goal_crouched = 0.0
        self.goal_velocity = np.zeros(2)
        self.walk_acceleration = 0.25
        self.bounce = 0.0

        self.add_collider(Rectangle([0, 0], 0.8, 3, Group.PLAYERS))

        self.body_type = 'speedo'
        self.head_type = 'bald'

        self.body = Body(self.position, self)
        self.head = Head(self.position + basis(1), self)

        self.back_hip = self.position + np.array([0.1, -0.5])
        self.front_hip = self.position + np.array([-0.1, -0.5])
        self.back_foot = Foot(self.position - np.array([0.35, 1.4]))
        self.front_foot = Foot(self.position - np.array([0.55, 1.4]))
        self.leg_length = 0.95

        self.max_speed = 0.5

        self.shoulder = self.position + 0.25 * 2 / 3 * self.collider.half_height \
            - 0.1 * self.direction * self.collider.half_width
        self.hand_goal = basis(0)
        self.arm_length = 1.0
        self.elbow = np.zeros(2)

        self.hand = Hand(self.position)
        self.back_hand = AnimatedObject(self.position, '', 1.2)

        self.object = None

        self.crouched = 0
        self.crouch_speed = 1.0

        self.lt_pressed = False
        self.rt_pressed = False

        self.attack_charge = 0.0

        self.throw_speed = 1.0
        self.throw_charge = 0.0
        self.charge_speed = 0.05

        self.controller_id = controller_id
        self.network_id = network_id
        self.timer = 0.0

        self.walking = False

        #self.channel = pygame.mixer.Channel(self.controller_id + 1)
        self.camera_shake = np.zeros(2)

        self.rest_angle = 0.5 * np.pi

        self.grab_delay = 1.0
        self.grab_timer = 0.0

        self.jump_speed = 0.65
Пример #17
0
 def __init__(self, position, radius, group=Group.NONE):
     super().__init__(position, group)
     self.radius = radius
     self.half_height = radius * basis(1)
     self.half_width = radius * basis(0)
Пример #18
0
 def set_resolution(self, resolution):
     self.max_zoom = resolution[1] / 720 * 50.0
     self.zoom = self.max_zoom
     self.half_width = 0.5 * resolution[0] * basis(0)
     self.half_height = 0.5 * resolution[1] * basis(1)
Пример #19
0
 def update_buttons(self):
     for i, b in enumerate(self.buttons):
         b.set_position(self.position - 1.5 * i * basis(1))
Пример #20
0
    def update(self, gravity, time_step, colliders):
        for p in self.particle_clouds:
            p.update(gravity, time_step)
            if not p.active:
                self.particle_clouds.remove(p)

        if not self.active:
            return

        if self.velocity[1] != 0:
            self.on_ground = False

        self.speed = norm(self.velocity)
        if self.speed != 0:
            self.velocity *= min(self.speed, MAX_SPEED) / self.speed

        delta_pos = self.velocity * time_step + 0.5 * self.acceleration * time_step**2
        self.set_position(self.position + delta_pos)
        acc_old = self.acceleration.copy()
        self.acceleration = self.get_acceleration(gravity)

        if self.rest_angle is None:
            self.angular_velocity = -self.gravity_scale * self.velocity[0]

        delta_angle = self.angular_velocity * time_step + 0.5 * self.angular_acceleration * time_step**2
        if delta_angle:
            self.rotate(delta_angle)
        ang_acc_old = float(self.angular_acceleration)
        self.angular_acceleration = 0.0

        if self.collider is None or not self.collision_enabled:
            return

        if any(np.abs(delta_pos) > 0.01) or abs(delta_angle) > 1e-3:
            self.collider.update_occupied_squares(colliders)

        self.collider.update_collisions(colliders)

        for collision in self.collider.collisions:
            collider = collision.collider
            if not collider.parent.collision_enabled:
                continue

            if collider.group is Group.PLATFORMS:
                if self.parent and self.collider.group in {Group.GUNS, Group.SWORDS, Group.SHIELDS}:
                    self.collider.collisions.remove(collision)
                    continue

                if collider.half_height[1] > 0:
                    if self.collider.position[1] - delta_pos[1] - self.collider.axis_half_width(basis(1)) \
                            < collider.position[1] + collider.half_height[1]:
                        self.collider.collisions.remove(collision)
                        continue
                elif self.collider.position[1] - delta_pos[1] + self.collider.axis_half_width(basis(1)) \
                        > collider.position[1] + collider.half_height[1]:
                    self.collider.collisions.remove(collision)
                    continue

            if self.collider.group is Group.THROWN:
                if collider.parent is self.parent:
                    self.collider.collisions.remove(collision)
                    continue

                try:
                    collider.parent.parent.throw_object()
                except AttributeError:
                    pass

            if collision.overlap[1] > 0:
                self.on_ground = True
                if not self.parent:
                    if self.rest_angle is not None:
                        self.rotate(-self.angle + self.direction * self.rest_angle)
                    self.angular_velocity = 0.0
            elif collision.overlap[0] != 0:
                self.angular_velocity *= -1

            n = min(int(self.speed * 5), 10)
            if n > 1:
                self.particle_clouds.append(Dust(self.position, self.speed * normalized(collision.overlap), n))

            self.set_position(self.position + collision.overlap)

            n = collision.overlap
            self.velocity -= 2 * self.velocity.dot(n) * n / norm2(n)
            self.velocity *= self.bounce

            if not self.parent and isinstance(collider.parent, PhysicsObject):
                collider.parent.velocity[:] = -self.velocity

        if self.collider.group is Group.THROWN and self.collider.collisions:
            self.parent = None
            self.collider.group = self.group

        self.velocity += 0.5 * (acc_old + self.acceleration) * time_step
        self.angular_velocity += 0.5 * (ang_acc_old + self.angular_acceleration) * time_step

        if abs(self.velocity[0]) < 0.05:
            self.velocity[0] = 0.0

        if self.parent is None and self.collider.collisions and self.speed > 0.1:
            self.sounds.add(self.bump_sound)