Exemplo n.º 1
0
    def move(self, collider, new_pixel_position, tf_dispatch_events=False):
        """Teleports the collider to new position, and returns any resulting collisions"""
        collider.position = copy_vector(new_pixel_position)
        collider.rect.x, collider.rect.y = collider.position.x, collider.position.y
        collisions = []

        if collider.mask == 0:
            return collisions  # optimization: no sense in wasting loops on something that never collides

        # check for collisions against world grid, if applicable
        if (collider.mask & constants.Block) != 0:
            collisions.extend(self.get_world_collisions(collider))

        for other_collider in (c for c in self._colliders
                               if c is not collider):
            if (collider.mask & other_collider.layer) == 0:
                continue

            if collider.rect.colliderect(
                    other_collider.rect) and other_collider not in collisions:
                collisions.append(
                    Collision(collider, other_collider,
                              copy_vector(collider.position)))

        if tf_dispatch_events:
            ColliderManager.dispatch_events(collider, collisions)

        return collisions
Exemplo n.º 2
0
    def get_world_collisions(self, collider):
        tw, th = self.tile_map.tile_width, self.tile_map.tile_height
        tmw, tmh = self.tile_map.width, self.tile_map.height

        # determine which grid square(s) the collider is in
        left, right = int(collider.rect.left / tw), int(collider.rect.right /
                                                        tw)
        top, bottom = int(collider.rect.top / th), int(collider.rect.bottom /
                                                       th)
        r = Rect(left * tw, top * th, tw, th)

        collisions = []

        # each of these tiles is potentially intersecting the collider
        for x in range(left, right + 1):
            if x < 0 or x >= tmw:
                continue

            for y in range(top, bottom + 1):
                if y < 0 or y >= tmh:
                    continue

                if not self.tile_map.get_passable((x, y)):
                    # a non-passable tile might be within range: now use a pixel-perfect collision test
                    r.x = x * tw
                    r.y = y * th

                    if collider.rect.colliderect(r):
                        collisions.append(
                            Collision(moved_collider=collider,
                                      hit_thing=(x, y),
                                      moved_collider_position=copy_vector(
                                          collider.position)))

        return collisions
Exemplo n.º 3
0
    def _handle_vertical_movement(self, dt):
        self.update_airborne()

        current_velocity = copy_vector(self.velocity)

        if not self._airborne:
            current_velocity.y = 0
        else:
            current_velocity.y += (self.parameters.gravity * dt)

            # limit downward velocity
            if current_velocity.y > self.parameters.max_vertical_velocity:
                current_velocity.y = self.parameters.max_vertical_velocity

        vel = make_vector(0, current_velocity.y)
        target_pos = self.entity.position + vel * dt
        self.airborne_collider.position = self.entity.position
        self.velocity = current_velocity

        # very important to be accurate with vertical movement because of the single pixel downward we use
        # for airborne detection.
        if any(self.airborne_collider.try_move(target_pos, True)):
            self.airborne_collider.approach(target_pos)
            self._airborne = False

            if self.on_hit:
                self.on_hit()

        self.entity.position = self.airborne_collider.position
Exemplo n.º 4
0
    def __init__(self, assets, level, scoring_labels: Labels, mario_stats):
        super().__init__()

        self.assets = assets
        self.scoring_labels = scoring_labels
        self.mario_stats = mario_stats
        self.level = level

        def make_centered(surface):
            return make_vector(*sr.center) - make_vector(surface.get_width() // 2, surface.get_height() // 2)

        sr = config.screen_rect
        tc = pygame.Color('white')

        self.elapsed = 0
        self.world_title = Labels.font_large.render(level.title, True, tc).convert_alpha()
        self.world_title_pos = make_centered(self.world_title) - make_vector(0, 100)

        self.x = Labels.font_large.render("x", True, tc)
        self.x_pos = make_centered(self.x) + make_vector(0, 40)

        little_mario = assets.character_atlas.load_static("mario_stand_right").image

        # scale it up
        self.mario_icon = pygame.transform.scale2x(little_mario).convert()
        self.mario_pos = copy_vector(self.x_pos) - \
            make_vector(self.mario_icon.get_width() * 2, self.mario_icon.get_height() // 4)

        self.lives = Labels.font_large.render(str(mario_stats.lives), True, tc).convert_alpha()
        self.lives_pos = self.x_pos + make_vector(self.mario_icon.get_width(), 0)
Exemplo n.º 5
0
    def __init__(self, position, initial_rect=None, anchor=Anchor.CENTER):
        # note to self: some elements won't have an initial rect (their content needs to be created), so
        # a None value is permissible here and will be changed when a layout event occurs

        super().__init__(initial_rect
                         or pygame.Rect(position[0], position[1], 0, 0))

        self.anchor = anchor
        self.parent = None
        self.children = []
        self.relative_position = copy_vector(position)
        self.position = self.relative_position
        self.enabled = True
Exemplo n.º 6
0
    def __init__(self,
                 entity,
                 manager,
                 mask,
                 position,
                 rect,
                 layer,
                 on_collision_callback=None):
        assert entity is not None
        assert manager is not None
        assert isinstance(mask, int)

        self.entity = entity
        self.manager = manager
        self.mask = mask or 0
        self._position = copy_vector(position)
        self.rect = rect.copy()
        self.layer = layer
        self.on_collision = on_collision_callback
Exemplo n.º 7
0
    def __init__(self,
                 window_position,
                 size,
                 background,
                 anchor=Anchor.TOP_LEFT,
                 draggable=True,
                 background_mouseover=None):
        super().__init__(window_position, size, anchor)

        assert background is not None
        assert isinstance(background, pygame.Surface) or isinstance(background, pygame.Color) \
            or isinstance(background, tuple) or isinstance(background, SlicedImage) or isinstance(background, Animation)

        self.element_position = copy_vector(window_position)
        self.background = background
        self.background_mouseover = background_mouseover or background
        self.draggable = draggable
        self.hidden_rect = None

        # event-related state
        self._is_dragging = False
        self._start_drag = pygame.Vector2()
        self._mouseover = False
Exemplo n.º 8
0
 def offset(self):
     return copy_vector(self._offset)
Exemplo n.º 9
0
 def position(self):
     return copy_vector(self._scroll_position)
Exemplo n.º 10
0
 def velocity(self, val):
     self.entity.velocity = copy_vector(val)
Exemplo n.º 11
0
 def get_velocity(self):
     return copy_vector(self._velocity)
Exemplo n.º 12
0
 def position(self):
     return copy_vector(self.mario_entity.position)
Exemplo n.º 13
0
 def get_scroll(self):
     return copy_vector(self.scroll_pos)
Exemplo n.º 14
0
 def position(self, pos):
     self._position = copy_vector(pos)
     self._rect.x, self._rect.y = pos
Exemplo n.º 15
0
 def deserialize(self, values):
     super().deserialize(values)
     self.movement.center_position = copy_vector(self.position)
Exemplo n.º 16
0
    def __init__(self,
                 position,
                 size,
                 background,
                 font,
                 text,
                 selected_image,
                 unselected_image,
                 is_selected=True,
                 anchor=Anchor.TOP_LEFT,
                 text_color=config.default_text_color,
                 mouseover_image=None,
                 on_selected_callback=None,
                 on_deselected_callback=None):
        if background is not None:
            size = size or background.get_rect().size

        assert hasattr(selected_image, "get_rect")
        assert hasattr(unselected_image, "get_rect")

        super().__init__(position=position,
                         size=size,
                         background=background,
                         text="",
                         font=font,
                         anchor=anchor,
                         mouseover_image=mouseover_image)

        assert selected_image and unselected_image

        self.on_selected = on_selected_callback
        self.on_deselected = on_deselected_callback

        # create textures
        # position them on left side, in center
        relative = make_vector(0, size[1] // 2)

        self._texture_on = Texture(selected_image, relative)
        self._texture_off = Texture(unselected_image, relative)

        relative.y -= max(self._texture_off.height,
                          self._texture_on.height) // 2
        self._texture_on.relative_position = copy_vector(relative)
        self._texture_off.relative_position = copy_vector(relative)

        self.add_child(self._texture_on)
        self.add_child(self._texture_off)

        self.selected = is_selected

        # create text
        # position to right side of textures
        relative.x = max(self._texture_on.get_absolute_rect().right + 10,
                         self._texture_off.get_absolute_rect().right + 10)
        relative.y = size[1] // 2 - font.get_height() // 2

        self.text = Text(relative, text, font, text_color=text_color)

        self.add_child(self.text)

        self.layout()