Example #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)
Example #2
0
class Block(Entity):
    def __init__(self, x, y):
        super(Block, self).__init__(x, y, 52, 16)
        self.sprite = Sprite(self.x - 6, self.y - 13, SpriteType.BLOCK)

    def update(self, delta_time, scene_data):
        pass

    def draw(self, surface):
        if globals.debugging:
            draw_rectangle(surface, self.bounds, CameraType.DYNAMIC,
                           self.color)
        else:
            self.sprite.draw(surface, CameraType.DYNAMIC)
Example #3
0
class Tree(Entity):
    def __init__(self, x, y):
        super(Tree, self).__init__(x, y, 20, 20)
        self.sprite = Sprite(self.x - 11 - 16, self.y - 21,
                             SpriteType.TREE_CLUSTER)
        # self.shadow = Sprite(self.x - 11 - 8, self.y - 21,
        #                     SpriteType.TREE_THING_SHADOW)

    def update(self, delta_time, entities):
        pass

    def draw(self, surface):
        if pygine.globals.debug:
            self._draw_bounds(surface, CameraType.DYNAMIC)
        else:
            # self.shadow.draw(surface, CameraType.DYNAMIC)
            self.sprite.draw(surface, CameraType.DYNAMIC)
Example #4
0
class Bullet(Kinetic):
    def __init__(self, x, y, speed=50):
        super(Bullet, self).__init__(x, y, 11, 12, speed)
        self.sprite = Sprite(x, y - 2, SpriteType.INK_BULLET)
        self.shadow = Sprite(x, y - 2 + 16, SpriteType.INK_BULLET_SHADOW)
        self.dead = False

    def set_location(self, x, y):
        super(Bullet, self).set_location(x, y)
        self.sprite.set_location(self.x, self.y - 2)
        self.shadow.set_location(self.x, self.y - 2 + 16)

    def update(self, delta_time, entities):
        self._calculate_scaled_speed(delta_time)
        self.set_location(self.x - self.move_speed, self.y)

    def draw(self, surface):
        if pygine.globals.debug:
            self._draw_bounds(surface, CameraType.DYNAMIC)
        else:
            self.shadow.draw(surface, CameraType.DYNAMIC)
            self.sprite.draw(surface, CameraType.DYNAMIC)
Example #5
0
class SpeechBubble(Entity):
    def __init__(self, x, y, source, sprite_type=SpriteType.NONE):
        super(SpeechBubble, self).__init__(x, y, 1, 1)
        self.sprite = Sprite(x, y, SpriteType.SPEECH_BUBBLE)
        self.__content = Sprite(x + 8, y + 8, sprite_type)
        self.source = source

    def set_location(self, x, y):
        super(SpeechBubble, self).set_location(x, y)
        self.sprite.set_location(x, y)
        self.__content.set_location(x + 8, y + 8)

    def set_content(self, sprite_type):
        self.__content.set_sprite(sprite_type)
        self.__content.set_location(self.x + 8, self.y + 8)

    def update(self, delta_time, entities):
        pass

    def draw(self, surface):
        self.sprite.draw(surface, CameraType.DYNAMIC)
        self.__content.draw(surface, CameraType.DYNAMIC)
Example #6
0
class OceanWall(Entity):
    def __init__(self, y, left, layer, total_layers):
        super(OceanWall, self).__init__(
            0 + layer * 20 if left else Camera.BOUNDS.width - 32 - layer * 20,
            y, 32, 64)
        self.layer = layer
        self.sprite = Sprite(
            self.x, self.y,
            SpriteType.ROCK_WALL_L if left else SpriteType.ROCK_WALL_R)

        self.direction = 1
        self.parallax_layers = total_layers
        self.parallax_variance = 10
        self.parallax_speed = 0
        self.calculate_parallax_speed()

    def set_location(self, x, y):
        super(OceanWall, self).set_location(x, y)
        self.sprite.set_location(self.x, self.y)

    def set_direction(self, direction):
        self.direction = direction
        self.calculate_parallax_speed()

    def calculate_parallax_speed(self):
        assert (self.parallax_variance > 0), \
            "Parallax Variance must be greater than zero!"
        self.parallax_speed = self.parallax_variance * \
            (self.parallax_layers - (self.layer + 1))**2 * self.direction * -1

    def update_parallax(self, delta_time):
        self.set_location(self.x, self.y + self.parallax_speed * delta_time)

    def update(self, delta_time, entities):
        self.update_parallax(delta_time)

    def draw(self, surface):
        self.sprite.draw(surface, CameraType.DYNAMIC)
Example #7
0
class Rock(Kinetic):
    def __init__(self, x, y, speed=75):
        super(Rock, self).__init__(x, y, 34, 14, speed)
        self.sprite = Sprite(x - 7, y - 16, SpriteType.ROCK)
        self.shadow = Sprite(self.x - 7 - 8, self.y - 16,
                             SpriteType.ROCK_SHADOW)
        self.dead = False

    def set_location(self, x, y):
        super(Rock, self).set_location(x, y)
        self.sprite.set_location(self.x - 7, self.y - 16)
        self.shadow.set_location(self.x - 7 - 8, self.y - 16)

    def update(self, delta_time, entities):
        self._calculate_scaled_speed(delta_time)
        self.set_location(self.x - self.move_speed, self.y)

    def draw(self, surface):
        if pygine.globals.debug:
            self._draw_bounds(surface, CameraType.DYNAMIC)
        else:
            self.shadow.draw(surface, CameraType.DYNAMIC)
            self.sprite.draw(surface, CameraType.DYNAMIC)
Example #8
0
class Octopus(Kinetic):
    def __init__(self, x, y):
        super(Octopus, self).__init__(x, y, 16, 16, randint(10, 30))
        self.timer = Timer(randint(1, 5) * 1000, True)
        self.sprite = Sprite(x - 16, y - 16, SpriteType.OCTOPUS)
        self.shadow = Sprite(x - 16 - 8, y - 16 + 16,
                             SpriteType.OCTOPUS_SHADOW)
        self.i = 0

    def set_location(self, x, y):
        super(Octopus, self).set_location(x, y)
        self.sprite.set_location(self.x - 16, self.y - 16)
        self.shadow.set_location(self.x - 16 - 8, self.y - 16 + 16)

    def __shoot(self, entities):
        entities.append(Bullet(self.x, self.y + self.height / 2, 200))

    def __move(self, delta_time):
        self.i += 1 * delta_time
        self.set_location(self.x - self.move_speed, self.y + math.sin(self.i))

    def update(self, delta_time, entities):
        self._calculate_scaled_speed(delta_time)
        self.__move(delta_time)
        self.timer.update(delta_time)
        if self.timer.done:
            if randint(1, 10) <= 7:
                self.__shoot(entities)
            self.timer.reset()
            self.timer.start()

    def draw(self, surface):
        if pygine.globals.debug:
            self._draw_bounds(surface, CameraType.DYNAMIC)
        else:
            self.shadow.draw(surface, CameraType.DYNAMIC)
            self.sprite.draw(surface, CameraType.DYNAMIC)
Example #9
0
class SandWall(Entity):
    def __init__(self, x, y, layer, total_layers):
        super(SandWall, self).__init__(x, y - layer * 10, 64, 32)
        self.layer = layer
        self.sprite = Sprite(self.x, self.y, SpriteType.SAND_WALL)

        self.direction = 1
        self.parallax_layers = total_layers
        self.parallax_variance = 10
        self.parallax_speed = 0
        self.calculate_parallax_speed()

    def set_location(self, x, y):
        super(SandWall, self).set_location(x, y)
        self.sprite.set_location(self.x, self.y)

    def set_direction(self, direction):
        self.direction = direction
        self.calculate_parallax_speed()

    def calculate_parallax_speed(self):
        assert (self.parallax_variance > 0), \
            "Parallax Variance must be greater than zero!"
        self.parallax_speed = self.parallax_variance * \
            (self.parallax_layers - (self.layer + 1))**2 * self.direction * -1
        if self.parallax_speed == 0:
            self.parallax_speed = self.parallax_variance / 2 * self.direction * -1

    def update_parallax(self, delta_time):
        self.set_location(self.x + self.parallax_speed * delta_time, self.y)

    def update(self, delta_time, entities):
        self.update_parallax(delta_time)

    def draw(self, surface):
        self.sprite.draw(surface, CameraType.DYNAMIC)
Example #10
0
class Player(Actor):
    def __init__(self, x, y):
        super(Player, self).__init__(x, y, 14, 8, 50)
        self.sprite = Sprite(self.x - 9, self.y - 24, SpriteType.PLAYER)
        self.query_result = None

    def set_location(self, x, y):
        super(Player, self).set_location(x, y)
        self.sprite.set_location(self.x - 9, self.y - 24)

    def _apply_force(self, delta_time):
        self.set_location(self.x + self.velocity.x, self.y + self.velocity.y)

    def _update_input(self):
        if pressing(InputType.UP) and not pressing(InputType.DOWN):
            self.velocity.y = -1 * self.move_speed

        if pressing(InputType.DOWN) and not pressing(InputType.UP):
            self.velocity.y = 1 * self.move_speed

        if not pressing(InputType.UP) and not pressing(InputType.DOWN):
            self.velocity.y = 0

        if pressing(InputType.LEFT) and not pressing(InputType.RIGHT):
            self.velocity.x = -1 * self.move_speed

        if pressing(InputType.RIGHT) and not pressing(InputType.LEFT):
            self.velocity.x = 1 * self.move_speed

        if not pressing(InputType.LEFT) and not pressing(InputType.RIGHT):
            self.velocity.x = 0

    def __rectanlge_collision_logic(self, entity):
        # Bottom
        if self.collision_rectangles[0].colliderect(
                entity.bounds) and self.velocity.y < 0:
            self.set_location(self.x, entity.bounds.bottom)
        # Top
        if self.collision_rectangles[1].colliderect(
                entity.bounds) and self.velocity.y > 0:
            self.set_location(self.x, entity.bounds.top - self.bounds.height)
        # Right
        if self.collision_rectangles[2].colliderect(
                entity.bounds) and self.velocity.x < 0:
            self.set_location(entity.bounds.right, self.y)
        # Left
        if self.collision_rectangles[3].colliderect(
                entity.bounds) and self.velocity.x > 0:
            self.set_location(entity.bounds.left - self.bounds.width, self.y)

    def _collision(self, scene_data):
        if (globals.debugging):
            for e in scene_data.entities:
                e.set_color(Color.WHITE)

        self.area = Rect(self.x - 52, self.y - 16, self.width + 52 * 2,
                         self.height + 16 * 2)

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

            if (globals.debugging):
                e.set_color(Color.RED)

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

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

    def draw(self, surface):
        if globals.debugging:
            self._draw_collision_rectangles(surface)
            draw_rectangle(surface, self.bounds, CameraType.DYNAMIC,
                           self.color)
            draw_rectangle(surface, self.area, CameraType.DYNAMIC, Color.BLACK,
                           1)
        else:
            self.sprite.draw(surface, CameraType.DYNAMIC)
Example #11
0
class Boulder(Kinetic):
    def __init__(self, x, y):
        super(Boulder, self).__init__(x, y, 0, 0, 0)
        if randint(1, 10) % 2 == 0:
            self.sprite = Sprite(self.x, self.y, SpriteType.FALLING_ROCK_BIG)
            self.radius = 16
            self.set_width(32)
            self.set_height(32)
        else:
            self.sprite = Sprite(self.x, self.y, SpriteType.FALLING_ROCK_SMALL)
            self.radius = 8
            self.set_width(16)
            self.set_height(16)

        self.center = Vector2(self.x + self.radius, self.y + self.radius)
        self.default_gravity = 16 * randint(3, 6)
        self.gravity = 0

        self.circle = Circle(self.center.x, self.center.y, self.radius,
                             Color.GREEN, 2)

    def set_location(self, x, y):
        super(Boulder, self).set_location(x, y)
        self.sprite.set_location(self.x, self.y)
        self.center = Vector2(self.x + self.radius, self.y + self.radius)
        self.circle.set_location(self.center.x, self.center.y)

    def _calculate_scaled_speed(self, delta_time):
        super(Boulder, self)._calculate_scaled_speed(delta_time)

        time = 1 / delta_time

        self.gravity = 2 * self.default_gravity / time**2

    def _apply_force(self, delta_time):
        self.velocity.y += self.gravity
        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 _collision(self, scene_data):
        if self.y + self.height > scene_data.scene_bounds.height + 64:
            self.remove = True

        if Vector2.distance_between(
                Vector2(scene_data.actor.x + scene_data.actor.width,
                        scene_data.actor.y + scene_data.actor.height),
                self.center) < self.radius:
            scene_data.actor.get_yeeted()

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

    def draw(self, surface):
        if globals.debugging:
            draw_rectangle(surface, self.bounds, CameraType.DYNAMIC,
                           self.color, 4)
            self.circle.draw(surface, CameraType.DYNAMIC)
        else:
            self.sprite.draw(surface, CameraType.DYNAMIC)
Example #12
0
class Claw(Kinetic):
    def __init__(self, boss, is_left):
        super(Claw, self).__init__(96, 128, 56, 74, 200)
        self.boss = boss
        self.is_left = is_left

        self.sprite = Sprite(self.x, self.y, SpriteType.CRAB_BOSS_ARM)

        if self.is_left:
            self.set_location(self.x - 16, self.y + 6)
        else:
            self.sprite.flip_horizontally(True)
            self.set_location(self.x + 5 * 16, self.y + 6)

        self.initial_y = self.sprite.y
        self.windup = False
        self.slamming = False
        self.cooldown = False
        self.needs_setup = True

    def set_location(self, x, y):
        super(Claw, self).set_location(x, y)
        self.sprite.set_location(self.x, self.y)

    def _apply_force(self, delta_time):
        pass

    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 _collision(self, scene_data):
        if (self.slamming and not scene_data.actor.attacked
                and scene_data.actor.bounds.colliderect(self.bounds)):
            scene_data.actor.get_yeeted()

    def __update_ai(self, delta_time, scene_data):
        if self.boss.injured:
            return

        if self.boss.crab_smash:
            if self.needs_setup:
                if self.y > self.initial_y - 40:
                    self.set_location(self.x, self.y - self.move_speed * 1.25)
                else:
                    self.needs_setup = False
                    self.boss.sync_smash += 1

            elif self.boss.sync_smash >= 2:
                if self.y + self.height < scene_data.scene_bounds.height - 8:
                    self.set_location(self.x, self.y + self.move_speed * 4)
                else:
                    self.needs_setup = True
                    self.cooldown = True
                    self.boss.special_attack = True

                    play_sound("stomp.wav", 0.5)

            return

        if (not self.boss.hurt and not self.slamming and not self.cooldown
                and scene_data.actor.y > self.initial_y
                and scene_data.actor.x >= self.x
                and scene_data.actor.x <= self.x + self.width):
            self.windup = True

        if self.windup:
            if self.y > self.initial_y - 40:
                if self.boss.state_index == 4:
                    self.set_location(self.x, self.y - self.move_speed * 0.6)
                else:
                    self.set_location(self.x, self.y - self.move_speed * 0.4)
            else:
                self.slamming = True
                self.windup = False

        if self.slamming:
            if self.y + self.height < scene_data.scene_bounds.height - 8:
                self.set_location(self.x, self.y + self.move_speed * 3)
            else:
                self.cooldown = True
                self.slamming = False

                play_sound("stomp.wav")
                self.boss.idle_timer.reset()
                self.boss.idle_timer.start()

        if self.cooldown:
            if self.y > self.initial_y:
                if self.boss.state_index == 4:
                    self.set_location(self.x, self.y - self.move_speed * 0.15)
                else:
                    self.set_location(self.x, self.y - self.move_speed * 0.07)
            else:
                self.cooldown = False

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

    def draw(self, surface):
        if globals.debugging:
            self._draw_collision_rectangles(surface)
            draw_rectangle(surface, self.bounds, CameraType.DYNAMIC,
                           self.color, 4)
        else:
            self.sprite.draw(surface, CameraType.STATIC)
Example #13
0
class BossCrab(Entity):
    def __init__(self):
        super(BossCrab, self).__init__(96, 128, 128, 8)
        self.body = Sprite(self.x - 64, self.y - 32, SpriteType.CRAB_BOSS_BODY)
        self.bandaid = Sprite(self.x + 2 * 16, self.y - 1 * 16,
                              SpriteType.CRAB_BOSS_BANDAID)
        self.face = Sprite(self.x + 2 * 16, self.y + 2 * 16,
                           SpriteType.CRAB_FACE_SLEEPING)
        self.emote = Sprite(self.x + 5 * 16, self.y - 2 * 16,
                            SpriteType.CRAB_BOSS_EMOTE_SLEEPY)

        self.state_index = 0
        self.total_flashes = 3
        self.flashes = 0
        self.flash_duration = 200
        self.invinsibility_flash_timer = Timer(self.flash_duration)
        self.hurt = False
        self.flashing = False
        self.injured = False

        self.crab_smash = False
        self.sync_smash = 0
        self.special_attack = False

        self.idle_timer = Timer(5000)

    def bop_on_head(self):
        if not self.hurt:
            self.state_index += 1
            self.hurt = True
            self.invinsibility_flash_timer.start()

            if self.state_index < 5:
                self.face.set_sprite(SpriteType.CRAB_FACE_HURT)
                self.emote.set_sprite(SpriteType.CRAB_BOSS_EMOTE_MAD)

    def __update_ai(self, delta_time, scene_data):
        if self.state_index > 1 and self.state_index < 5:
            self.idle_timer.start()
            self.idle_timer.update(delta_time)

        if self.idle_timer.done:
            self.crab_smash = True
            self.idle_timer.reset()

    def __update_health(self, delta_time):
        if self.hurt:
            self.idle_timer.reset()
            self.invinsibility_flash_timer.update(delta_time)

            if self.invinsibility_flash_timer.done:
                self.flashes += 1
                self.flashing = not self.flashing

                if self.flashes >= self.total_flashes * 2:
                    self.hurt = False
                    self.flashing = False
                    self.flashes = 0

                    if self.state_index == 1:
                        self.state_index += 1
                    if self.state_index < 5:
                        self.face.set_sprite(SpriteType.CRAB_FACE_HAPPY)
                        self.emote.set_sprite(SpriteType.NONE)

                    self.crab_smash = True

                self.invinsibility_flash_timer.reset()
                self.invinsibility_flash_timer.start()

    def __update_expression(self):
        if self.state_index >= 5:
            self.emote.set_sprite(SpriteType.CRAB_BOSS_EMOTE_THIRSTY)
            self.face.set_sprite(SpriteType.CRAB_FACE_INJURED)
            self.injured = True

    def update(self, delta_time, scene_data):
        self.__update_ai(delta_time, scene_data)
        self.__update_health(delta_time)
        self.__update_expression()

    def draw(self, surface):
        if globals.debugging:
            draw_rectangle(surface, self.bounds, CameraType.DYNAMIC,
                           self.color, 4)
        else:
            if not self.flashing:
                self.body.draw(surface, CameraType.STATIC)
                self.bandaid.draw(surface, CameraType.STATIC)
                self.face.draw(surface, CameraType.STATIC)
                self.emote.draw(surface, CameraType.STATIC)
Example #14
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)
Example #15
0
class Player(Actor):
    def __init__(self, x, y):
        super(Player, self).__init__(x, y, 12, 28, 100)
        self.sprite = Sprite(self.x - 10, self.y - 16, SpriteType.PLAYER)
        self.walk_animation = Animation(6, 6, 100)
        self.direction = Direction.NONE
        self.area = None
        self.query_result = None

        self.default_jump_height = 16 * 4
        self.jump_duration = 1
        self.default_run_acceleration = 10
        self.default_ground_friction = 7
        self.default_air_friction = 1

        self.jump_initial_velocity = 0
        self.gravity = 0
        self.lateral_acceleration = 0
        self.ground_friction = 0
        self.air_friction = 0

        self.grounded = False
        self.jumping = False
        self.attempt_block_shift = False
        self.attacked = False
        self.restart = False
        self.pause = False
        self.transitioning = False

        self.restart_delay = Timer(2600)
        self.queue_restart = False

    def revive(self):
        self.grounded = False
        self.jumping = False
        self.attempt_block_shift = False
        self.attacked = False
        self.restart = False
        self.queue_restart = False

        self.velocity = Vector2(0, 0)
        self.sprite.set_frame(0, 6)

    def get_yeeted(self):
        self.__finessed_by_enemy()

    def _calculate_scaled_speed(self, delta_time):
        super(Player, self)._calculate_scaled_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

        self.lateral_acceleration = self.default_run_acceleration * delta_time
        self.ground_friction = self.default_ground_friction * delta_time
        self.air_friction = self.default_air_friction * delta_time

    def set_location(self, x, y):
        super(Player, self).set_location(x, y)
        self.sprite.set_location(self.x - 10, self.y - 16)

    def _apply_force(self, delta_time):

        if self.transitioning:
            return

        if not self.pause:
            self.velocity.y += self.gravity
        else:
            self.velocity.y += self.gravity * 0.6

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

    def _update_input(self, delta_time):
        if self.attacked:
            return

        if not self.pause and pressing(
                InputType.LEFT) and not pressing(InputType.RIGHT):
            self.velocity.x -= self.lateral_acceleration
            if self.velocity.x < -self.move_speed:
                self.velocity.x = -self.move_speed

            if not self.jumping:
                self.sprite.set_frame(self.walk_animation.current_frame, 6)

            self.direction = Direction.LEFT

        elif not self.pause and pressing(
                InputType.RIGHT) and not pressing(InputType.LEFT):
            self.velocity.x += self.lateral_acceleration
            if self.velocity.x > self.move_speed:
                self.velocity.x = self.move_speed

            if not self.jumping:
                self.sprite.set_frame(self.walk_animation.current_frame, 6)

            self.direction = Direction.RIGHT

        elif ((not pressing(InputType.LEFT) and not pressing(InputType.RIGHT))
              or (pressing(InputType.LEFT) and pressing(InputType.RIGHT))):
            if self.grounded:
                self.velocity.lerp(Vector2(0, self.velocity.y),
                                   self.ground_friction)
            else:
                self.velocity.lerp(Vector2(0, self.velocity.y),
                                   self.air_friction)

            if self.velocity.x > -0.1 and self.velocity.x < 0.1:
                self.velocity.x = 0

            self.sprite.set_frame(0, 6)

        if not self.grounded:
            if self.velocity.y < 0:
                self.sprite.set_frame(6, 6)
            if self.velocity.y > 0:
                self.sprite.set_frame(7, 6)
        else:
            if self.velocity.x == 0:
                if pressing(InputType.UP):
                    self.sprite.set_frame(8, 6)
                if pressing(InputType.DOWN):
                    self.sprite.set_frame(9, 6)

        if self.direction == Direction.LEFT:
            self.sprite.flip_horizontally(True)
        elif self.direction == Direction.RIGHT:
            self.sprite.flip_horizontally(False)

        if pressed(InputType.A) and self.grounded and not self.jumping:
            self.__jump(delta_time)
            self.jumping = True

        if self.jumping and self.velocity.y < -self.jump_initial_velocity / 2 and not pressing(
                InputType.A):
            self.velocity.y = -self.jump_initial_velocity / 2
            self.jumping = False

        if pressed(InputType.X):
            self.attempt_block_shift = True

    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.grounded = True
            self.jumping = False
            self.velocity.y = 0

        # 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
        # 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

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

        if self.x < 3:
            self.set_location(3, self.y)

        if (globals.debugging):
            for e in scene_data.entities:
                e.set_color(Color.WHITE)

        self.area = Rect(self.x - 16, self.y - 32, self.width + 16 * 2,
                         self.height + 32 * 2)

        self.grounded = False
        self.query_result = scene_data.entity_quad_tree.query(self.area)

        if self.attempt_block_shift:
            self.__shift_blocks(scene_data)

        self.attempt_block_shift = False

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

            if (globals.debugging):
                e.set_color(Color.RED)

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

            if isinstance(e, QBlock):
                if e.active:
                    self.__rectanlge_collision_logic(e)
                    self._update_collision_rectangles()

            if isinstance(e, BossCrab):
                if (not e.hurt and not self.grounded and self.velocity.y > 0
                        and self.collision_rectangles[1].colliderect(
                            e.bounds)):
                    e.bop_on_head()
                    self.velocity.y = -self.jump_initial_velocity * 0.35
                    if not e.injured:
                        play_sound("pain.wav", 0.4)
                    else:
                        play_sound("pain.wav", 0.2)

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

            if (globals.debugging):
                e.set_color(Color.RED)

            if isinstance(e, Crab):
                if not e.dead:
                    if (not e.aggravated and not self.grounded
                            and self.velocity.y > 0
                            and self.collision_rectangles[1].colliderect(
                                e.bounds)):
                        e.squish()
                        self.velocity.y = -self.jump_initial_velocity * 0.35
                        play_sound("bop.wav")

                    elif e.aggravated and self.bounds.colliderect(e.bounds):
                        self.__finessed_by_enemy()

    def __jump(self, delta_time):
        self.velocity.y = -self.jump_initial_velocity
        play_sound("jump.wav")

    def __shift_blocks(self, scene_data):
        for e in self.query_result:
            if e is self:
                continue

            if isinstance(e, QBlock):
                if self.bounds.colliderect(e.bounds):
                    play_sound("shift_fail.wav")
                    return

        for e in scene_data.entities:
            if isinstance(e, QBlock):
                e.toggle()
            elif isinstance(e, Crab):
                e.toggle_aggravation()

        play_sound("shift.wav")

    def __finessed_by_enemy(self):
        self.attacked = True
        self.velocity.y = -self.jump_initial_velocity * 0.5
        self.sprite.set_frame(10, 6)

        self.__play_mocking_music()

    def __play_mocking_music(self):
        if not self.queue_restart:
            play_song("fin.wav")
            self.queue_restart = True
            self.restart_delay.reset()
            self.restart_delay.start()

    def __update_death(self, delta_time, scene_data):
        if self.y + self.height > scene_data.scene_bounds.height:
            self.attacked = True
            self.__play_mocking_music()
        #if self.y + self.height > scene_data.scene_bounds.height + 64 + 128 + 64:
        #    self.restart = True

        if self.queue_restart:
            self.restart_delay.update(delta_time)
            if self.restart_delay.done:
                self.restart = True
                self.queue_restart = False

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

    def update(self, delta_time, scene_data):
        self._calculate_scaled_speed(delta_time)
        self._update_input(delta_time)
        self._apply_force(delta_time)
        self._update_collision_rectangles()
        self._collision(scene_data)
        self.__update_death(delta_time, 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)
            if self.area != None:
                draw_rectangle(surface, self.area, CameraType.DYNAMIC,
                               Color.BLACK, 1)
        else:
            self.sprite.draw(surface, CameraType.DYNAMIC)
Example #16
0
class Hook(Actor):
    def __init__(self, ocean_depth):
        super(Hook, self).__init__(0, 0, 13, 13, 80)
        self.ocean_depth = ocean_depth
        self.sprite = Sprite(self.x, self.y - 7, SpriteType.HOOK)
        self.direction = 1
        self.total_hooked_fish = 0

    def set_location(self, x, y):
        super(Hook, self).set_location(x, y)
        self.sprite.set_location(self.x, self.y - 7)

    def __bounds_collision(self):
        if self.x < 0:
            self.x = 0
        elif self.x + self.width > Camera.BOUNDS.width:
            self.x = Camera.BOUNDS.width - self.width

    def _collision(self, entities):
        if self.y + Camera.BOUNDS.height / 2 > self.ocean_depth:
            self.direction = -1
            self.default_move_speed = 100

        self.__bounds_collision()

        for e in entities:
            if isinstance(e, OceanWall):
                if self.direction == -1:
                    e.set_direction(-1)
            elif isinstance(e, Fishy) and not e.captured:
                if self.bounds.colliderect(e.bounds):
                    e.hook_fish()
                    self.total_hooked_fish += 1
                    self.direction = -1

    def _move(self, direction=Direction.NONE):
        self.facing = direction
        if self.facing == Direction.LEFT:
            self.set_location(self.x - self.move_speed, self.y)
            self.velocity.x = -1
        if self.facing == Direction.RIGHT:
            self.set_location(self.x + self.move_speed, self.y)
            self.velocity.x = 1

    def _update_input(self, delta_time):
        self.input.update(delta_time)
        if self.input.pressing(InputType.LEFT):
            self._move(Direction.LEFT)
        if self.input.pressing(InputType.RIGHT):
            self._move(Direction.RIGHT)

    def update(self, delta_time, entities):
        self._calculate_scaled_speed(delta_time)
        self._update_input(delta_time)
        self._collision(entities)
        self.set_location(self.x, self.y + self.move_speed * self.direction)

    def draw(self, surface):
        draw_line(surface, Camera.BOUNDS.width / 2 - 8, -8, self.x + 7,
                  self.y - 6, CameraType.DYNAMIC, Color.BLACK, 3)
        draw_line(surface, Camera.BOUNDS.width / 2 - 8, -8, self.x + 7,
                  self.y - 6, CameraType.DYNAMIC, Color.WHITE, 1)
        self.sprite.draw(surface, CameraType.DYNAMIC)

        if pygine.globals.debug:
            self._draw_bounds(surface, CameraType.DYNAMIC)
Example #17
0
class Boat(Actor):
    def __init__(self, x, y, beans=50):
        super(Boat, self).__init__(x, y, 83, 16, 50)
        self.beans = beans
        self.playbounds = Rectangle(0, 16 * 3, Camera.BOUNDS.width,
                                    Camera.BOUNDS.height - 16 * 3)
        self.sprite = Sprite(x - 16, y - 48, SpriteType.BOAT)
        self.shadow = Sprite(x - 16 - 16, y - 16, SpriteType.BOAT_SHADOW)
        self.blinks = 5
        self.invis_duration = 1600
        self.invis_timer = Timer(self.invis_duration)
        self.blink_timer = Timer(self.invis_duration / self.blinks / 2)
        self.damaged = False
        self.flashing = False
        self.dead = False

    def set_location(self, x, y):
        super(Boat, self).set_location(x, y)
        self.sprite.set_location(self.x - 16, self.y - 48)
        self.shadow.set_location(self.x - 16 - 16, self.y - 16)

    def _collision(self, entities):
        for e in entities:
            if not self.damaged:
                if isinstance(e, Bullet) or isinstance(e, Octopus):
                    if self.bounds.colliderect(e.bounds):
                        e.dead = True
                        self.__decrease_health(5)
                elif isinstance(e, Rock):
                    if self.bounds.colliderect(e.bounds):
                        self.__decrease_health(10)
        self.__bounds_collision()

    def __decrease_health(self, amount):
        self.damaged = True
        self.beans -= amount
        self.invis_timer.start()
        self.blink_timer.start()
        self.sprite.set_sprite(SpriteType.BOAT_OWO)

    def _move(self, direction=Direction.NONE):
        self.facing = direction
        if self.facing == Direction.UP:
            self.set_location(self.x, self.y - self.move_speed)
            self.velocity.y = -1
        if self.facing == Direction.DOWN:
            self.set_location(self.x, self.y + self.move_speed)
            self.velocity.y = 1
        if self.facing == Direction.LEFT:
            self.set_location(self.x - self.move_speed, self.y)
            self.velocity.x = -1
        if self.facing == Direction.RIGHT:
            self.set_location(self.x + self.move_speed, self.y)
            self.velocity.x = 1

    def _update_input(self, delta_time):
        self.input.update(delta_time)
        if self.input.pressing(InputType.UP):
            self._move(Direction.UP)
        if self.input.pressing(InputType.DOWN):
            self._move(Direction.DOWN)
        if self.input.pressing(InputType.LEFT):
            self._move(Direction.LEFT)
        if self.input.pressing(InputType.RIGHT):
            self._move(Direction.RIGHT)

    def __update_health(self, delta_time):
        if self.damaged:
            self.invis_timer.update(delta_time)
            self.blink_timer.update(delta_time)
            if self.blink_timer.done:
                self.flashing = not self.flashing
                self.blink_timer.reset()
                self.blink_timer.start()
            if self.invis_timer.done:
                self.damaged = False
                self.flashing = False
                self.invis_timer.reset()
                self.sprite.set_sprite(SpriteType.BOAT)

    def __bounds_collision(self):
        if self.x < self.playbounds.x:
            self.x = self.playbounds.x
        elif self.x + self.width > self.playbounds.x + self.playbounds.width:
            self.x = self.playbounds.x + self.playbounds.width - self.width

        if self.y < self.playbounds.y:
            self.y = self.playbounds.y
        elif self.y + self.height > self.playbounds.y + self.playbounds.height:
            self.y = self.playbounds.y + self.playbounds.height - self.height

    def __check_death(self):
        if self.beans <= 0:
            # TODO: death logic here, maybe display transition and change scene?
            self.dead = True

    def update(self, delta_time, entities):
        self._calculate_scaled_speed(delta_time)

        if self.dead:
            self.flashing = False
            self.set_location(self.x - self.move_speed / 2 + randint(-2, 0),
                              self.y + self.move_speed)
            return

        self._update_input(delta_time)
        self._collision(entities)
        self.__update_health(delta_time)
        self.__check_death()

    def draw(self, surface):
        if pygine.globals.debug:
            self._draw_bounds(surface, CameraType.DYNAMIC)
        else:
            if not self.flashing:
                self.shadow.draw(surface, CameraType.DYNAMIC)
                self.sprite.draw(surface, CameraType.DYNAMIC)
Example #18
0
class Fishy(Kinetic):
    def __init__(self, y, left):
        super(Fishy, self).__init__(-32 if left else Camera.BOUNDS.width + 16,
                                    y, 16, 16,
                                    randint(1, 10) * 10)
        self.type = randint(0, 1)
        self.velocity.x = -1 if left else 1
        if self.velocity.x > 0:
            if self.type == 0:
                self.sprite = Sprite(
                    self.x, self.y, SpriteType.FISH_SMALL_L
                    if left else SpriteType.FISH_SMALL_R)
            elif self.type == 1:
                self.sprite = Sprite(
                    self.x, self.y, SpriteType.FISH_LARGE_L
                    if left else SpriteType.FISH_LARGE_R)
        else:
            if self.type == 0:
                self.sprite = Sprite(
                    self.x, self.y, SpriteType.FISH_SMALL_L
                    if left else SpriteType.FISH_SMALL_L)
            elif self.type == 1:
                self.sprite = Sprite(
                    self.x, self.y, SpriteType.FISH_LARGE_L
                    if left else SpriteType.FISH_LARGE_L)

        self.captured = False

    def set_location(self, x, y):
        super(Fishy, self).set_location(x, y)
        self.sprite.set_location(self.x, self.y)

    def hook_fish(self):
        self.captured = True

    def _update_ai(self):
        self.set_location(self.x + self.move_speed * self.velocity.x, self.y)

    def flip_velocity(self):
        self.velocity.x *= -1
        if self.velocity.x > 0:
            if self.type == 0:
                self.sprite.set_sprite(SpriteType.FISH_SMALL_R)
            elif self.type == 1:
                self.sprite.set_sprite(SpriteType.FISH_LARGE_R)
        else:
            if self.type == 0:
                self.sprite.set_sprite(SpriteType.FISH_SMALL_L)
            elif self.type == 1:
                self.sprite.set_sprite(SpriteType.FISH_LARGE_L)

    def _collision(self, entities):
        if self.captured:
            for e in entities:
                if isinstance(e, Hook):
                    if self.velocity.x > 0:
                        self.set_location(e.x - 6 + randint(-3, 3),
                                          e.y + 4 + randint(-3, 3))
                    else:
                        self.set_location(e.x + 2 + randint(-3, 3),
                                          e.y + 4 + randint(-3, 3))

                    if randint(1, 10) <= 1:
                        self.flip_velocity()
                    return

        if (self.bounds.left < -32 and self.velocity.x < 0) or (
                self.bounds.right > Camera.BOUNDS.width + 32
                and self.velocity.x > 0):
            self.flip_velocity()

    def update(self, delta_time, entities):
        self._calculate_scaled_speed(delta_time)
        # self._update_collision_rectangles()
        self._update_ai()
        self._collision(entities)

    def draw(self, surface):
        if pygine.globals.debug:
            self._draw_bounds(surface, CameraType.DYNAMIC)
            self._draw_collision_rectangles(surface)
        else:
            self.sprite.draw(surface, CameraType.DYNAMIC)
Example #19
0
class NPC(Kinetic):
    def __init__(self,
                 x,
                 y,
                 type,
                 can_move=True,
                 horizontal=True,
                 start_direction=1,
                 walk_duration=5000):
        super(NPC, self).__init__(x, y, 10, 10, 25)
        self.type = type
        self.sprite = Sprite(self.x - 3, self.y - 22, SpriteType.NONE)
        self.shadow = Sprite(self.x - 3, self.y - 21, SpriteType.PLAYER_SHADOW)
        self.speech_bubble = SpeechBubble(self.x - 11, self.y - 32 - 11, self)
        self.radius = 32
        self.show_prompt = False
        self.set_color(Color.RED)
        self.walk_direction = 1 if start_direction >= 0 else -1
        self.horizontal = horizontal
        self.can_move = can_move
        self._walk_timer = Timer(walk_duration, True)
        self.animation_walk = Animation(6, 6, 100)
        self.walking = True
        self._set_walking_sprite()
        self._set_random_emotion()

    def set_location(self, x, y):
        super(NPC, self).set_location(x, y)
        self.sprite.set_location(self.x - 3, self.y - 22)
        self.shadow.set_location(self.x - 3, self.y - 21)
        self.speech_bubble.set_location(self.x - 11, self.y - 32 - 11)

    def _set_random_emotion(self):
        rand = randint(1, 4)
        if rand == 1:
            self.speech_bubble.set_content(SpriteType.FACE_HAPPY)
        elif rand == 2:
            self.speech_bubble.set_content(SpriteType.FACE_SAD)
        elif rand == 3:
            self.speech_bubble.set_content(SpriteType.FACE_MAD)
        elif rand == 4:
            self.speech_bubble.set_content(SpriteType.FACE_SURPRISED)

    def _stop_walking(self):
        if not self.horizontal:
            if self.type == NPCType.MALE:
                self.sprite.set_sprite(SpriteType.NPC_M_F)
            else:
                self.sprite.set_sprite(SpriteType.NPC_F_F)
        self._set_random_emotion()
        self.walking = not self.walking

    def _walk(self, delta_time):
        self._walk_timer.update(delta_time)
        if self._walk_timer.done:
            if random() < 0.25:
                self._stop_walking()
            if self.walking:
                self.walk_direction = -self.walk_direction
                self._set_walking_sprite()
            self._walk_timer.reset()
            self._walk_timer.start()
        if self.walking:
            if self.horizontal:
                self.set_location(
                    self.x + self.move_speed * self.walk_direction, self.y)
            else:
                self.set_location(
                    self.x, self.y + self.move_speed * self.walk_direction)

    def _set_walking_sprite(self):
        if self.can_move:
            if self.horizontal:
                if self.walk_direction > 0:
                    if self.type == NPCType.MALE:
                        self.sprite.set_sprite(SpriteType.NPC_M_R)
                    else:
                        self.sprite.set_sprite(SpriteType.NPC_F_R)
                else:
                    if self.type == NPCType.MALE:
                        self.sprite.set_sprite(SpriteType.NPC_M_L)
                    else:
                        self.sprite.set_sprite(SpriteType.NPC_F_L)
            else:
                if self.walk_direction > 0:
                    if self.type == NPCType.MALE:
                        self.sprite.set_sprite(SpriteType.NPC_M_F)
                    else:
                        self.sprite.set_sprite(SpriteType.NPC_F_F)
                else:
                    if self.type == NPCType.MALE:
                        self.sprite.set_sprite(SpriteType.NPC_M_B)
                    else:
                        self.sprite.set_sprite(SpriteType.NPC_F_B)
        else:
            if self.type == NPCType.MALE:
                self.sprite.set_sprite(SpriteType.NPC_M_F)
            else:
                self.sprite.set_sprite(SpriteType.NPC_F_F)

    def _within_radius(self, e):
        if distance_between(self.center, e.center) <= self.radius:
            self.show_prompt = True
        else:
            self.show_prompt = False

    def _update_conversation(self, entities):
        for e in entities:
            if isinstance(e, Player):
                last = self.show_prompt
                self._within_radius(e)
                if last != self.show_prompt:
                    if self.show_prompt:
                        entities.append(self.speech_bubble)
                    else:
                        entities.remove(self.speech_bubble)

    def _update_animation(self, delta_time):
        if self.walking:
            self.animation_walk.update(delta_time)
            self.sprite.set_frame(self.animation_walk.current_frame,
                                  self.animation_walk.columns)
        else:
            self.sprite.set_frame(0, self.animation_walk.columns)

    def _rectangle_collision_logic(self, entity):
        # Bottom
        if self.collision_rectangles[0].colliderect(
                entity.bounds) and self.velocity.y < 0:
            self.set_location(self.x, entity.bounds.bottom)
        # Top
        elif self.collision_rectangles[1].colliderect(
                entity.bounds) and self.velocity.y > 0:
            self.set_location(self.x, entity.bounds.top - self.bounds.height)
        # Right
        elif self.collision_rectangles[2].colliderect(
                entity.bounds) and self.velocity.x < 0:
            self.set_location(entity.bounds.right, self.y)
        # Left
        elif self.collision_rectangles[3].colliderect(
                entity.bounds) and self.velocity.x > 0:
            self.set_location(entity.bounds.left - self.bounds.width, self.y)

    def _collision(self, entities):
        for e in entities:
            if (isinstance(e, Building) or isinstance(e, Tree)):
                self._rectangle_collision_logic(e)

    def update(self, delta_time, entities):
        self._update_conversation(entities)
        self._calculate_scaled_speed(delta_time)
        if self.can_move:
            self._walk(delta_time)

        # self._update_collision_rectangles()
        # self._collision(entities)

        if self.can_move:
            self._update_animation(delta_time)

    def draw(self, surface):
        if pygine.globals.debug:
            self._draw_bounds(surface, CameraType.DYNAMIC)
        else:
            self.shadow.draw(surface, CameraType.DYNAMIC)
            self.sprite.draw(surface, CameraType.DYNAMIC)
Example #20
0
class Player(Actor):
    def __init__(self, x, y, width=10, height=10, speed=50):
        super(Player, self).__init__(x, y, width, height, speed)
        self.sprite = Sprite(self.x - 3, self.y - 22, SpriteType.PLAYER_F)
        self.arms = Sprite(self.x - 3, self.y - 22,
                           SpriteType.PLAYER_ARM_SIDE_F)
        self.shadow = Sprite(self.x - 3, self.y - 21, SpriteType.PLAYER_SHADOW)
        self.set_color(Color.RED)
        self.item_carrying = None
        self.animation_walk = Animation(6, 6, 100)
        self.walking = False

    def set_location(self, x, y):
        super(Player, self).set_location(x, y)
        self.sprite.set_location(self.x - 3, self.y - 22)
        self.arms.set_location(self.x - 3, self.y - 22)
        self.shadow.set_location(self.x - 3, self.y - 21)

        if self.item_carrying != None:
            self.item_carrying.set_location(self.x - 3, self.sprite.y - 8)

    def _move(self, direction=Direction.NONE):
        self.facing = direction
        self.walking = True
        if self.facing == Direction.UP:
            self.sprite.set_sprite(SpriteType.PLAYER_B)
            self.arms.set_sprite(SpriteType.PLAYER_ARM_SIDE_B)
            self.set_location(self.x, self.y - self.move_speed)
            self.velocity.y = -1
        if self.facing == Direction.DOWN:
            self.sprite.set_sprite(SpriteType.PLAYER_F)
            self.arms.set_sprite(SpriteType.PLAYER_ARM_SIDE_F)
            self.set_location(self.x, self.y + self.move_speed)
            self.velocity.y = 1
        if self.facing == Direction.LEFT:
            self.sprite.set_sprite(SpriteType.PLAYER_L)
            self.arms.set_sprite(SpriteType.PLAYER_ARM_SIDE_L)
            self.set_location(self.x - self.move_speed, self.y)
            self.velocity.x = -1
        if self.facing == Direction.RIGHT:
            self.sprite.set_sprite(SpriteType.PLAYER_R)
            self.arms.set_sprite(SpriteType.PLAYER_ARM_SIDE_R)
            self.set_location(self.x + self.move_speed, self.y)
            self.velocity.x = 1

    def _update_input(self, delta_time):
        self.input.update(delta_time)
        self.walking = False
        if self.input.pressing(
                InputType.UP) and not self.input.pressing(InputType.DOWN):
            self._move(Direction.UP)
        if self.input.pressing(
                InputType.DOWN) and not self.input.pressing(InputType.UP):
            self._move(Direction.DOWN)
        if self.input.pressing(
                InputType.LEFT) and not self.input.pressing(InputType.RIGHT):
            self._move(Direction.LEFT)
        if self.input.pressing(
                InputType.RIGHT) and not self.input.pressing(InputType.LEFT):
            self._move(Direction.RIGHT)

    def _rectangle_collision_logic(self, entity):
        # Bottom
        if self.collision_rectangles[0].colliderect(
                entity.bounds) and self.velocity.y < 0:
            self.set_location(self.x, entity.bounds.bottom)
        # Top
        elif self.collision_rectangles[1].colliderect(
                entity.bounds) and self.velocity.y > 0:
            self.set_location(self.x, entity.bounds.top - self.bounds.height)
        # Right
        elif self.collision_rectangles[2].colliderect(
                entity.bounds) and self.velocity.x < 0:
            self.set_location(entity.bounds.right, self.y)
        # Left
        elif self.collision_rectangles[3].colliderect(
                entity.bounds) and self.velocity.x > 0:
            self.set_location(entity.bounds.left - self.bounds.width, self.y)

    def _collision(self, entities):
        for e in entities:
            if (not e.ignore
                    and (isinstance(e, Building) or isinstance(e, Furniture)
                         or isinstance(e, Wall) or isinstance(e, Tree))
                    # isinstance(e, NPC)
                ):
                self._rectangle_collision_logic(e)

    def _update_animation(self, delta_time):
        if self.walking:
            self.animation_walk.update(delta_time)
            self.sprite.set_frame(self.animation_walk.current_frame,
                                  self.animation_walk.columns)
            self.arms.set_frame(self.animation_walk.current_frame,
                                self.animation_walk.columns)
        else:
            self.sprite.set_frame(0, self.animation_walk.columns)
            self.arms.set_frame(0, self.animation_walk.columns)

    def _update_item(self):
        if self.item_carrying != None:
            self.arms.increment_sprite_x(16 * 6)

    def update(self, delta_time, entities):
        self._calculate_scaled_speed(delta_time)
        self._update_input(delta_time)
        self._update_collision_rectangles()
        self._collision(entities)
        self._update_animation(delta_time)
        self._update_item()

    def draw(self, surface):
        if pygine.globals.debug:
            self._draw_bounds(surface, CameraType.DYNAMIC)
            self._draw_collision_rectangles(surface)
        else:
            self.shadow.draw(surface, CameraType.DYNAMIC)
            self.sprite.draw(surface, CameraType.DYNAMIC)
            self.arms.draw(surface, CameraType.DYNAMIC)
            if (self.item_carrying != None):
                self.item_carrying.draw(surface)