Exemplo n.º 1
0
class QBlock(Entity):
    def __init__(self, x, y, type):
        super(QBlock, self).__init__(x, y, 16, 16)
        self.active = False
        if type == 0:
            self.sprite = Sprite(self.x, self.y, SpriteType.Q_BLOCK_0)
        else:
            self.sprite = Sprite(self.x, self.y, SpriteType.Q_BLOCK_1)
            self.sprite.increment_sprite_y(16)
            self.active = True

    def toggle(self):
        self.active = not self.active
        if self.active:
            self.sprite.increment_sprite_y(16)
        else:
            self.sprite.increment_sprite_y(-16)

    def update(self, delta_time, scene_data):
        pass

    def draw(self, surface):
        if globals.debugging:
            self.sprite.draw(surface, CameraType.DYNAMIC)
            draw_rectangle(surface, self.bounds, CameraType.DYNAMIC,
                           self.color, 2)
        else:
            self.sprite.draw(surface, CameraType.DYNAMIC)
Exemplo n.º 2
0
class Crab(Kinetic):
    def __init__(self, x, y):
        super(Crab, self).__init__(x, y, 11, 9, 25)
        self.sprite = Sprite(self.x - 18, self.y - 19, SpriteType.CRAB)
        self.walk_animation = Animation(4, 4, 150)
        self.direction = Direction.RIGHT
        self.area = None
        self.query_result = None

        self.default_jump_height = 16 * 1.5
        self.jump_duration = 0.5

        self.jump_initial_velocity = 0
        self.gravity = 0
        self.lateral_acceleration = 0

        self.aggravated_move_speed = 100

        self.internal_bounds = Rect(self.x + 5, self.y + 5, 1, 1)

        self.grounded = False
        self.aggravated = False
        self.dead = False

    def set_location(self, x, y):
        super(Crab, self).set_location(x, y)
        self.sprite.set_location(self.x - 18, self.y - 19)
        self.internal_bounds = Rect(self.x + 5, self.y + 5, 1, 1)

    def toggle_aggravation(self):
        if self.dead:
            return

        self.aggravated = not self.aggravated

    def squish(self):
        self.dead = True
        self.velocity.y = -self.jump_initial_velocity * 0.75
        self.velocity.x = - \
            self.move_speed if randint(1, 10) % 2 == 0 else self.move_speed

    def _calculate_scaled_speed(self, delta_time):
        if self.aggravated:
            self.move_speed = self.aggravated_move_speed * delta_time
        else:
            self.move_speed = self.default_move_speed * delta_time

        time = 1 / delta_time * self.jump_duration

        self.jump_initial_velocity = 4 * self.default_jump_height / time
        self.gravity = 8 * self.default_jump_height / time**2

    def _apply_force(self, delta_time):
        self.velocity.y += self.gravity

        if self.direction == Direction.RIGHT:
            self.velocity.x = self.move_speed

        if self.direction == Direction.LEFT:
            self.velocity.x = -self.move_speed

        self.set_location(self.x + self.velocity.x, self.y + self.velocity.y)

    def _update_collision_rectangles(self):
        self.collision_width = 3
        self.collision_rectangles = [
            Rect(self.x + 2, self.y - self.collision_width * 2, self.width - 4,
                 self.collision_width * 2),
            Rect(self.x + 2, self.y + self.height, self.width - 4,
                 self.collision_width * 2),
            Rect(self.x - self.collision_width, self.y + self.collision_width,
                 self.collision_width, self.height - self.collision_width * 2),
            Rect(self.x + self.width, self.y + self.collision_width,
                 self.collision_width, self.height - self.collision_width * 2)
        ]

    def __rectanlge_collision_logic(self, entity):
        # Bottom
        if self.velocity.y < 0 and self.collision_rectangles[0].colliderect(
                entity.bounds):
            self.set_location(self.x, entity.bounds.bottom)
            self.velocity.y = 0

        # Top
        if self.velocity.y > 0 and self.collision_rectangles[1].colliderect(
                entity.bounds):
            self.set_location(self.x, entity.bounds.top - self.bounds.height)
            self.velocity.y = 0
            self.grounded = True

        # Right
        if self.velocity.x < 0 and self.collision_rectangles[2].colliderect(
                entity.bounds):
            self.set_location(entity.bounds.right, self.y)
            self.velocity.x = 0
            self.direction = Direction.RIGHT
        # Left
        if self.velocity.x > 0 and self.collision_rectangles[3].colliderect(
                entity.bounds):
            self.set_location(entity.bounds.left - self.bounds.width, self.y)
            self.velocity.x = 0
            self.direction = Direction.LEFT

    def _collision(self, scene_data):
        if self.dead:
            return

        if self.x < 3:
            self.set_location(3, self.y)
            self.velocity.x = 0
            self.direction = Direction.RIGHT

        if self.x + self.width > scene_data.scene_bounds.width:
            self.set_location(scene_data.scene_bounds.width - self.width,
                              self.y)
            self.velocity.x = 0
            self.direction = Direction.LEFT

        if self.y > scene_data.scene_bounds.height + 64:
            self.squish()

        self.area = Rect(self.x - 16, self.y - 16, self.width + 16 * 2,
                         self.height + 16 * 2)
        self.query_result = scene_data.entity_quad_tree.query(self.area)

        self.grounded = False

        for e in self.query_result:
            if e is self:
                continue

            if isinstance(e, Block):
                self.__rectanlge_collision_logic(e)
                self._update_collision_rectangles()

            elif isinstance(e, QBlock):
                if e.active:

                    if not self.dead and self.internal_bounds.colliderect(
                            e.bounds):
                        self.squish()

                    self.__rectanlge_collision_logic(e)
                    self._update_collision_rectangles()

        self.query_result = scene_data.kinetic_quad_tree.query(self.area)
        for e in self.query_result:
            if e is self:
                continue

            if isinstance(e, Crab):
                self.__rectanlge_collision_logic(e)
                self._update_collision_rectangles()

    def __update_ai(self, scene_data):
        if self.dead:
            if self.y > scene_data.scene_bounds.height + 64:
                self.remove = True

        if self.aggravated:
            if self.grounded:
                self.velocity.y = -self.jump_initial_velocity

    def __update_animation(self, delta_time):
        self.walk_animation.update(delta_time)

        self.sprite.set_frame(self.walk_animation.current_frame,
                              self.walk_animation.columns)

        if self.aggravated:
            self.sprite.increment_sprite_y(32)

        if self.dead:
            self.sprite.flip_vertically(True)

    def update(self, delta_time, scene_data):
        self._calculate_scaled_speed(delta_time)
        self.__update_ai(scene_data)
        self._apply_force(delta_time)
        self._update_collision_rectangles()
        self._collision(scene_data)
        self.__update_animation(delta_time)

    def draw(self, surface):
        if globals.debugging:
            self._draw_collision_rectangles(surface)
            draw_rectangle(surface, self.bounds, CameraType.DYNAMIC,
                           self.color)
        else:
            self.sprite.draw(surface, CameraType.DYNAMIC)