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 __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
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)
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 __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 __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 __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 __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
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)
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)
def __init__(self, x=0, y=0, width=1, height=1): super(Entity, self).__init__(x, y, width, height) self.sprite = Sprite(x, y, SpriteType.NONE) self.color = Color.WHITE self.layer = 0 self.remove = False self.ignore = False self.__bounds_that_actually_draw_correctly = Rectangle( self.x, self.y, self.width, self.height, self.color, 2)
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 __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 __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
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)
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)
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 __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
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)
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)
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)
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)
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)
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
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)
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)
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)
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)
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
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)