Пример #1
0
class CapeGuy(Character):
    def __init__(self, game):
        super().__init__(game)
        self.sprite = Sprite(3, colorkey=c.BLACK)
        idle = SpriteSheet(c.image_path("evil_guy_placeholder.png"), (1, 1), 1)
        self.sprite.add_animation({"Idle": idle})
        self.sprite.start_animation("Idle")
        self.name = "Parity"

        self.x = c.WINDOW_WIDTH//2
        self.y = 125
        self.yoff = 0
        self.age = 0
        self.alpha = 0
        self.target_alpha = 255

    def update(self, dt, events):
        self.sprite.update(dt)
        self.age += dt
        self.yoff = math.sin(self.age * 1) * 12

        da = self.target_alpha - self.alpha
        if da >= 0:
            self.alpha = min(self.alpha + da * dt, self.target_alpha)
        else:
            self.alpha = max(self.alpha + da * dt, self.target_alpha)

    def draw(self, surface):
        if self.alpha <= 0:
            return
        size = self.sprite.size()
        x, y = self.game.xy_transform(self.x, self.y)
        self.sprite.set_position((x - size[0]//2, y + self.yoff - size[1]//2))
        self.sprite.draw(surface, self.alpha)
Пример #2
0
 def main(self):
     inst = SpriteSheet("images/controls.png", (2, 1), 2)
     sprite = Sprite(4)
     sprite.add_animation({"Idle": inst})
     sprite.start_animation("Idle")
     clock = pygame.time.Clock()
     age = 0
     shade = pygame.Surface(c.WINDOW_SIZE)
     shade.fill(c.BLACK)
     shade.set_alpha(255)
     while True:
         end = 4
         if age < 0.25:
             shade.set_alpha((0.25 - age) * 255 / 0.25)
         elif age > end - 0.25:
             shade.set_alpha((age - end + 0.25) * 255 / 0.25)
         else:
             shade.set_alpha(0)
         sprite.set_position((c.WINDOW_WIDTH // 2, c.WINDOW_HEIGHT // 2))
         dt = clock.tick(60) / 1000
         age += dt
         events = self.game.update_globals()
         sprite.update(dt)
         sprite.draw(self.game.screen)
         self.game.screen.blit(shade, (0, 0))
         pygame.display.flip()
         if age >= end:
             self.game.bus_ride.fadeout(500)
             break
Пример #3
0
class BulletHit(Particle):
    def __init__(self, game, position=(0, 0)):
        super().__init__(game, None, position=position)
        self.sprite = Sprite(16)
        anim = SpriteSheet(c.image_path("bullet_hit.png"), (8, 1), 8)
        self.sprite.add_animation({"Default": anim})
        self.sprite.start_animation("Default")
        self.game.top_particles.add(self)

        surface = pygame.Surface((100, 100))
        surface.fill((0, 0, 0))
        pygame.draw.circle(surface, (255, 255, 255), (50, 50), 50)
        self.boom = surface
        self.boom.set_colorkey((0, 0, 0))
        self.boom_alpha = 200
        self.boom_size = 40

    def update(self, dt, events):
        self.age += dt
        self.boom_alpha -= 1600 * dt
        self.boom_size += 600 * dt
        self.sprite.update(dt)
        if self.age > 0.4:
            self.destroy()

    def draw(self, surface, offset=(0, 0)):
        x = self.x + offset[0]
        y = self.y + offset[1]
        self.sprite.set_position((x, y))
        self.sprite.draw(surface)

        boom = pygame.transform.scale(
            self.boom, (int(self.boom_size), int(self.boom_size)))
        boom.set_alpha(self.boom_alpha)
        surface.blit(boom, (x - self.boom_size // 2, y - self.boom_size // 2))

    def destroy(self):
        super().destroy()
        self.game.top_particles.remove(self)
Пример #4
0
class Warden(Character):

    def __init__(self, game):
        super().__init__(game)
        self.sprite = Sprite(3, colorkey=c.BLACK)
        self.halberd = Sprite(3, colorkey=c.BLACK)
        idle = SpriteSheet(c.image_path("warden.png"), (1, 1), 1)
        self.sprite.add_animation({"Idle": idle})
        self.sprite.start_animation("Idle")

        idle = SpriteSheet(c.image_path("halberd.png"), (1, 1), 1)
        self.halberd.add_animation({"Idle": idle})
        self.halberd.start_animation("Idle")

        self.x = c.WINDOW_WIDTH // 2
        self.y = 125
        self.age = 0
        self.alpha = -200
        self.target_alpha = 255
        self.name = "Warden"
        self.slashing = False
        self.slash_timer = 0

        self.left = pygame.image.load(c.image_path("warden_left.png")).convert()
        self.left.set_colorkey(c.BLACK)
        self.left.set_alpha(255)
        self.right = pygame.image.load(c.image_path("warden_right.png")).convert()
        self.right.set_colorkey(c.BLACK)
        self.right.set_alpha(255)

    def draw(self, surface):
        if self.alpha <= -200:
            return

        size = self.sprite.size()
        x, y = self.game.xy_transform(self.x, self.y)
        self.sprite.set_position((x - size[0]//2, y - size[1]//2))
        yoff = math.sin(self.age * 1.6) * 5
        self.halberd.set_position((x - size[0]//2, y - size[1]//2 + yoff))
        if not self.slashing:
            self.sprite.draw(surface, self.alpha)
            self.halberd.draw(surface, self.alpha + 200)
        else:
            width = 4
            yoff = max(0, ((self.slash_timer - 2.0) * 40)) ** 2
            alpha = min(255, 255 - (self.slash_timer - 2.0) * 800)

            lx = x - width//2 - size[0]//2
            rx = lx + self.left.get_width() + width
            ly = y - size[1]//2 + yoff
            ry = y - size[1]//2 - yoff
            self.left.set_alpha(alpha)
            self.right.set_alpha(alpha)
            if alpha > 0:
                surface.blit(self.left, (lx, ly))
                surface.blit(self.right, (rx, ry))
            else:
                self.game.characters.remove(self)

    def update(self, dt, events):
        self.sprite.update(dt)
        if not self.slashing:
            self.age += dt
        else:
            self.slash_timer += dt

        da = self.target_alpha - self.alpha
        if da >= 0:
            self.alpha = min(self.alpha + da * dt, self.target_alpha)
        else:
            self.alpha = max(self.alpha + da * dt, self.target_alpha)

    def slash(self):
        self.game.slash_sound.play()
        self.game.shake(15)
        self.slashing = True
        self.game.set_flash(0.5)
Пример #5
0
class Character(OverWorldObject):
    name = None

    def __init__(self, scene, pos=(3, 3)):
        super().__init__(scene)
        self.priority = 3
        self.blocking = True
        self.interactive = True
        self.dialogue = None

        tag_dict = {"Player": "player", "Emilia": "captain", None: "player"}
        tag = tag_dict[self.name]

        down = SpriteSheet(scene.load_image(f"{tag}_walk_down"), (6, 1), 6)
        up = SpriteSheet(scene.load_image(f"{tag}_walk_up"), (6, 1), 6)
        down_idle = SpriteSheet(scene.load_image(f"{tag}_idle_down"), (4, 1),
                                4)
        up_idle = SpriteSheet(scene.load_image(f"{tag}_idle_up"), (4, 1), 4)
        right = SpriteSheet(scene.load_image(f"{tag}_walk_right"), (6, 1), 6)
        left = SpriteSheet(scene.load_image(f"{tag}_walk_right"), (6, 1), 6)
        left.reverse(1, 0)
        right_idle = SpriteSheet(scene.load_image(f"{tag}_idle_right"), (4, 1),
                                 4)
        left_idle = SpriteSheet(scene.load_image(f"{tag}_idle_right"), (4, 1),
                                4)
        left_idle.reverse(1, 0)
        self.sprite = Sprite(8)
        self.sprite.add_animation({
            "down": down,
            "up": up,
            "down_idle": down_idle,
            "up_idle": up_idle,
            "right": right,
            "left": left,
            "right_idle": right_idle,
            "left_idle": left_idle
        })
        self.sprite.start_animation("down_idle")
        self.idles = {
            c.DOWN: "down_idle",
            c.UP: "up_idle",
            c.RIGHT: "right_idle",
            c.LEFT: "left_idle"
        }
        self.idle_playing = True

        self.x = pos[0]
        self.y = pos[1]
        self.scene.map.add_to_cell(self, self.x, self.y)
        self.draw_x = self.x
        self.draw_y = self.y
        self.prev_x = self.x
        self.prev_y = self.y
        self.shadow = CharacterShadow(scene, self)
        self.scene.map.add_to_cell(self.shadow, self.x, self.y)

        self.since_move = 0
        self.move_speed = 3

        self.in_motion = False
        self.next_direction = c.NO_DIRECTION
        self.face_direction = c.DOWN
        self.last_face_direction = c.DOWN
        self.since_arrive = 999

        self.shadow_surf = pygame.Surface(c.TILE_SIZE)
        self.shadow_surf.fill(c.WHITE)
        width = int(c.TILE_WIDTH * 0.7)
        height = int(c.TILE_HEIGHT * 0.5)
        pygame.draw.ellipse(
            self.shadow_surf, c.BLACK,
            (c.TILE_WIDTH // 2 - width // 2,
             3.2 * c.TILE_HEIGHT // 5 - height // 2, width, height))
        self.shadow_surf.set_alpha(30)
        self.shadow_surf.set_colorkey(c.WHITE)

    def draw(self, surface):
        draw_x, draw_y = self.scene.camera.grid_to_screen(
            self.draw_x, self.draw_y)
        yoff = c.TILE_HEIGHT // 1.5
        self.sprite.set_position((draw_x, draw_y - yoff))
        surface.blit(self.shadow_surf, (draw_x, draw_y))
        self.sprite.draw(surface)

    def touch(self):
        pass

    def setDialogue(self, dialogueTag):
        self.dialogue = Dialogue(dialogueTag, self.name)

    def update(self, dt, events):
        self.check_events(events)
        self.since_move += dt
        self.since_arrive += dt
        self.draw_x = h.approach(self.draw_x, self.x, self.move_speed * dt)
        self.draw_y = h.approach(self.draw_y, self.y, self.move_speed * dt)
        if (self.draw_x,
                self.draw_y) == (self.x, self.y) and (self.x, self.y) != (
                    self.prev_x, self.prev_y) and self.in_motion:
            self.arrive()

        self.update_move(self.direction())

        self.sprite.update(dt)
        if self.since_arrive > 0.1 and not self.idle_playing and not self.in_motion:
            self.idle_playing = True
            if self.face_direction in self.idles:
                self.sprite.start_animation(self.idles[self.face_direction])

    def check_events(self, events):
        pass

    def direction(self):
        new_direction = self.next_direction
        self.next_direction = c.NO_DIRECTION
        return new_direction

    def arrive(self):
        """ Called when the player arrives at the target location each step. """
        self.in_motion = False
        self.scene.map.remove_from_cell(self.shadow, self.prev_x, self.prev_y)
        self.scene.map.add_to_cell(self.shadow, self.x, self.y)
        self.prev_x, self.prev_y = self.x, self.y
        self.since_arrive = 0

    def move(self, direction):
        """ Queues a movement in the direction for the character."""
        self.next_direction = direction

    def update_move(self, direction):
        """ Move the character one square in a direction. """
        self.scene.map.remove_from_cell(self, self.x, self.y)
        if not self.in_motion and direction is not c.NO_DIRECTION:
            new_x = self.x + direction[0]
            new_y = self.y + direction[1]
            self.face_direction = direction

            if not self.scene.map.cell_is_blocking(new_x, new_y):
                self.prev_x = self.x
                self.prev_y = self.y
                self.x += direction[0]
                self.y += direction[1]
                self.since_move = 0
                self.in_motion = True

            self.turn(direction)

        self.scene.map.add_to_cell(self, self.x, self.y)

    def turn(self, direction):
        if direction != self.last_face_direction or self.idle_playing:
            self.idle_playing = False
            if direction == c.UP:
                self.sprite.start_animation("up")
            elif direction == c.DOWN:
                self.sprite.start_animation("down")
            elif direction == c.LEFT:
                self.sprite.start_animation("left")
            elif direction == c.RIGHT:
                self.sprite.start_animation("right")
        self.last_face_direction = direction
Пример #6
0
class Player:
    def __init__(self, game):
        self.game = game

        self.width = 64
        self.height = 64

        self.x = c.WINDOW_WIDTH / 3
        self.y = c.WINDOW_HEIGHT // 2 + self.game.corridor.width // 2 - self.height // 2

        self.y_velocity = 0
        self.x_velocity = 0

        self.extra_jumps = 1

        self.bullets = set()
        self.bullet_cooldown = 0
        self.bullet_period = 0.10

        self.gunfire = pygame.mixer.Sound("sounds/gunfire.wav")
        self.hurt_noise = pygame.mixer.Sound("sounds/hurt.wav")
        self.death_noise = pygame.mixer.Sound("sounds/death.wav")
        self.hurt_noise.set_volume(0.5)
        self.jump_noise = pygame.mixer.Sound("sounds/jump.wav")

        self.sprite = Sprite(7)
        self.sprite.add_animation({
            "Running": player_running,
            "Dead": player_dead,
            "Hit": player_hit
        })
        self.sprite.start_animation("Running")
        self.gun = pygame.image.load("images/player_gun.png")
        self.gun = pygame.transform.scale(
            self.gun, (self.gun.get_width() * 2, self.gun.get_height() * 2))

        self.since_hit = 10
        self.invincibility_period = 1

        self.movement_enabled = True
        self.in_bus = False

        self.cash = 0
        self.cash_this_level = 0
        self.dead = False

        self.collision_radius = 24
        self.hit_circle_radius = 1000

        self.hp = 3

    def update(self, dt, events):
        if pygame.mouse.get_pressed()[0]:
            self.shoot()

        if self.hit_circle_radius < 1000:
            self.hit_circle_radius += 2500 * dt

        if self.movement_enabled:
            self.y_velocity += 2500 * dt
            self.y += self.y_velocity * dt
            self.x_velocity *= 0.0005**dt
            self.x += self.x_velocity * dt
        self.bullet_cooldown += dt
        self.since_hit += dt

        if self.since_hit >= 0.05 and not self.dead:
            self.sprite.start_animation("Running")

        self.collide_corridor(self.game.corridor)
        self.update_movement(dt, events)

        to_destroy = set()
        for bullet in self.bullets:
            bullet.update(dt, events)
            margin = 30
            if bullet.x > c.WINDOW_WIDTH + margin or bullet.y > c.WINDOW_HEIGHT + margin or \
                bullet.x < -margin or bullet.y < -margin:
                to_destroy.add(bullet)
        self.bullets -= to_destroy

        self.sprite.update(dt)

        mindist = 800
        for enemy in self.game.enemies:
            if enemy.dead or self.dead:
                continue
            dist = c.distance_between_points(self.x, self.y, enemy.x, enemy.y)
            dist -= enemy.radius + 32
            if dist < mindist:
                mindist = dist
        if mindist < 0:
            mindist = 0
        self.game.slowdown = min(0.4 + 0.6 * mindist / 130, 1)

    def die(self):
        self.game.scroll_speed = 0
        self.dead = True
        self.x_velocity = 500
        self.y_velocity = -1000
        self.sprite.start_animation("Dead")
        self.death_noise.play()

    def update_movement(self, dt, events):
        if not self.movement_enabled:
            return

        pressed = pygame.key.get_pressed()
        if self.on_floor():
            acceleration = 6000
        else:
            acceleration = 3000
        max_speed = 500

        if not self.dead:
            if pressed[pygame.K_a]:
                self.x_velocity -= dt * acceleration
            if pressed[pygame.K_d]:
                self.x_velocity += dt * acceleration
            if pressed[pygame.K_w]:
                if not self.on_floor():
                    self.y_velocity -= 1400 * dt

        for event in events:
            if event.type == pygame.KEYDOWN:
                if event.key == pygame.K_w:
                    if not self.dead:
                        self.jump()

        invisible_force = 40
        if not self.on_floor():
            invisible_force = 20
        if self.x > c.WINDOW_WIDTH * 0.5:
            diff = self.x - c.WINDOW_WIDTH * 0.4
            self.x_velocity -= invisible_force * diff * dt
        elif self.x < c.WINDOW_WIDTH * 0.25:
            diff = c.WINDOW_WIDTH * 0.25 - self.x
            self.x_velocity += invisible_force * diff * dt

        if self.x_velocity > max_speed:
            self.x_velocity = max_speed
        if self.x_velocity < -max_speed:
            self.x_velocity = -max_speed

    def jump(self):
        if self.on_floor() or self.extra_jumps > 0:
            self.jump_noise.play()
            self.y_velocity = -660
            if not self.on_floor():
                self.extra_jumps -= 1

    def draw(self, surface):
        sx, sy = self.game.get_shake_offset()
        x, y = int(self.x + sx), int(self.y + sy)
        self.sprite.set_position((x, y))
        self.sprite.draw(surface)

        mpos = pygame.mouse.get_pos()
        dx = mpos[0] - self.x
        dy = mpos[1] - self.y
        angle = -math.atan2(dy, dx) * 180 / math.pi
        if self.dead:
            angle = 0
        gun = pygame.transform.rotate(self.gun, angle)
        gx = x - gun.get_width() // 2
        gy = y - gun.get_height() // 2 - 14
        surface.blit(gun, (gx, gy))

        if self.hit_circle_radius < 1000:
            pass
            #pygame.draw.circle(surface, c.WHITE, (int(self.x), int(self.y)), int(self.hit_circle_radius+5), 5)

        for bullet in self.bullets:
            bullet.draw(surface)

    def shoot(self):
        if not self.bullet_cooldown > self.bullet_period:
            return
        if self.dead:
            return
        if not self.movement_enabled:
            return

        self.bullet_cooldown = 0

        self.game.particles.append(Shell(self.game, self.x, self.y))

        mpos = pygame.mouse.get_pos()
        dx = mpos[0] - self.x
        dy = mpos[1] - self.y
        mag = (dx**2 + dy**2)**0.5
        dir = (dx / mag, dy / mag)
        new_bullet = Bullet(self.game, self.x, self.y, dir)
        self.bullets.add(new_bullet)

        recoil = 80
        self.game.shake(3)
        self.x_velocity -= recoil * dir[0]
        if not self.on_floor():
            self.y_velocity -= recoil * dir[1]

        self.gunfire.play()

    def on_floor(self):
        off = self.height // 3
        if self.y >= c.WINDOW_HEIGHT // 2 + self.game.corridor.width // 2 - off:
            self.extra_jumps = 1
            return True
        return False

    def collide_corridor(self, corridor):
        off = self.height // 3
        if self.y + off > c.WINDOW_HEIGHT // 2 + corridor.width // 2:
            self.y = c.WINDOW_HEIGHT // 2 + corridor.width // 2 - off
            self.y_velocity = 0
        elif self.y - off < c.WINDOW_HEIGHT // 2 - corridor.width // 2:
            self.y = c.WINDOW_HEIGHT // 2 - corridor.width // 2 + off
            self.y_velocity = 0

    def get_hit_by(self, enemy):
        if self.in_bus == True:
            return
        if self.since_hit < self.invincibility_period:
            return
        self.game.shake(25)
        self.since_hit = 0
        self.hp -= 1
        self.game.flash_alpha = 100
        self.game.slowdown = 0.1
        if self.hp == 0:
            self.game.flash_alpha = 255
            self.die()
        else:
            self.hurt_noise.play()
            self.hit_circle_radius = 0
            pickups = self.game.pickups[:]
            for enemy in self.game.enemies:
                enemy.die()
            self.game.pickups = pickups
            dx = self.x - enemy.x
            dy = self.y - enemy.y
            dx, dy = dx / (abs(dx) + abs(dy)), dy / (abs(dx) + abs(dy))
            self.x_velocity += dx * 1000
            self.y_velocity += dy * 1000
            enemy.velocity[0] -= dx * 1000
            enemy.velocity[1] -= dy * 1000
            self.sprite.start_animation("Hit")
Пример #7
0
class Blocker(Enemy):
    def __init__(self, game):
        self.radius = 50
        self.game = game
        super().__init__(game, c.WINDOW_WIDTH + self.radius, self.game.corridor.floor_y() - self.radius, self.radius)
        self.hp = 4
        self.value = 6
        self.velocity = [-self.game.scroll_speed, 0]
        self.tink_sound = pygame.mixer.Sound("sounds/tink.wav")
        self.sprite = Sprite(10)
        self.sprite.add_animation({"Idle": blocker, "Hurt": blocker_hurt, "Dead": blocker_dead})
        self.sprite.start_animation("Idle")
        self.shield_surf = pygame.image.load("images/blocker_shield.png")
        self.shield_surf = pygame.transform.scale(self.shield_surf, (self.shield_surf.get_width()*2, self.shield_surf.get_height()*2))
        self.shield_offset = 0
        self.since_hit = 10
        self.playing_idle = True
        self.remove_on_death = False

    def update(self, dt, events):
        super().update(dt, events)
        self.sprite.update(dt)
        self.x += self.velocity[0] * dt
        self.y += self.velocity[1] * dt
        self.shield_offset *= 0.003**dt
        self.since_hit += dt
        if self.since_hit > 0.04 and self.playing_idle == False and not self.dead:
            self.playing_idle = True
            self.sprite.start_animation("Idle")
        if self.dead:
            self.sprite.start_animation("Dead")

        if self.dead:
            self.velocity[1] += 2500*dt
        if self.y >= self.game.corridor.floor_y() - self.radius and self.velocity[1] >= 0:
            self.y = self.game.corridor.floor_y() - self.radius
            self.velocity = [-self.game.scroll_speed, 0]


    def draw(self, surface):
        sx, sy = self.game.get_shake_offset()
        self.sprite.set_position((sx + self.x, sy + self.y))
        self.sprite.draw(surface)

        x = self.x - self.radius + sx - 20 + self.shield_offset
        y = self.y - self.radius + sy
        if not self.dead:
            surface.blit(self.shield_surf, (x, y))

    def get_hit_by(self, bullet):
        if self.dead:
            return
        if bullet.x > self.x - self.radius * 0.75 and bullet.dir[1]*2 > bullet.dir[0]:
            super().get_hit_by(bullet)
            self.sprite.start_animation("Hurt")
            self.playing_idle = False
            self.since_hit = 0
        else:
            self.tink_sound.play()
            self.shield_offset = 15
        pass

    def die(self):
        super().die()
        self.velocity = [random.random()*200 - 100 - self.game.scroll_speed, -300]
Пример #8
0
class Crawler(Enemy):
    CRAWLING = 0
    LAUNCHING = 1
    DEAD = 2

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.speed = -400
        self.velocity = [0, 0]
        self.launch_speed = 1000
        self.state = self.CRAWLING
        self.radius = 24
        self.y = c.WINDOW_HEIGHT//2 + self.game.corridor.width//2 - self.radius
        self.hp = 2
        self.remove_on_death = False

        self.sprite = Sprite(12)
        self.sprite.add_animation({"Running":crawler_running,
            "Jumping":crawler_jump,
            "Hurt":crawler_hurt,
            "Dead":crawler_dead})
        self.sprite.start_animation("Running")

        self.detect_range = 200
        self.since_hurt = 10
        self.hurt_playing = False
        self.since_land = 10

        self.value = 3

    def get_hit_by(self, bullet):
        super().get_hit_by(bullet)
        if not self.state == self.DEAD:
            self.since_hurt = 0
            self.hurt_playing = True
            self.sprite.start_animation("Hurt")
        if self.state == self.LAUNCHING:
            self.velocity[0] += bullet.dir[0] * 300
            self.velocity[1] += bullet.dir[1] * 300
        elif self.state == self.CRAWLING:
            self.x += 5

    def update(self, dt, events):
        super().update(dt, events)

        dx = self.x - self.game.player.x
        dy = self.y - self.game.player.y
        if dx < self.detect_range and dx > 0 and self.state == self.CRAWLING and self.since_land > 2:
            self.state = self.LAUNCHING
            self.velocity = self.launch_velocity()
            self.sprite.start_animation("Jumping")

        if self.state == self.CRAWLING:
            self.x += self.speed * dt
        elif self.state == self.LAUNCHING:
            self.velocity[1] += 2000*dt
            self.x += self.velocity[0] * dt
            self.y += self.velocity[1] * dt
            if self.y >= c.WINDOW_HEIGHT//2 + self.game.corridor.width//2 - self.radius and self.velocity[1] > 0:
                self.reset_as_floor_crawler()
                self.since_land = 0
                return
        elif self.state == self.DEAD:
            self.velocity[1] += 2000*dt
            self.x += self.velocity[0] * dt
            self.y += self.velocity[1] * dt
            if self.y > c.WINDOW_HEIGHT//2 + self.game.corridor.width//2 - self.radius:
                self.y = c.WINDOW_HEIGHT//2 + self.game.corridor.width//2 - self.radius
                self.velocity[0] = -self.game.scroll_speed


        if self.since_hurt > 0.05 and self.hurt_playing and not self.state == self.DEAD:
            if self.state == self.CRAWLING:
                self.sprite.start_animation("Running")
            elif self.state == self.LAUNCHING:
                self.sprite.start_animation("Jumping")

        if self.y <= c.WINDOW_HEIGHT//2 - self.game.corridor.width//2 + self.radius:
            self.y = c.WINDOW_HEIGHT//2 - self.game.corridor.width//2 + self.radius

        self.since_hurt += dt
        self.since_land += dt

        self.sprite.update(dt)

    def launch_velocity(self):
        angle = math.pi * 3/4
        angle += (random.random() * math.pi/6) - math.pi/12
        x = math.cos(angle) * self.launch_speed
        y = -math.sin(angle) * self.launch_speed
        return [x, y]

    def draw(self, surface):
        if not self.is_colliding_with_player(self.game.player):
            color = c.RED
        else:
            color = c.BLUE
        sx, sy = self.game.get_shake_offset()
        x, y = int(self.x + sx), int(self.y + sy)
        self.sprite.set_position((x, y))
        self.sprite.draw(surface)

    def die(self):
        super().die()
        self.state = self.DEAD
        self.sprite.start_animation("Dead")
        new_y = -300 if self.y < c.WINDOW_HEIGHT//2 - self.game.corridor.width//2 + 200 else -150
        self.velocity = [-random.random() * 200, new_y]

    def reset_as_floor_crawler(self):
        Crawler.__init__(self, self.game, self.x, self.y)
        self.y = c.WINDOW_HEIGHT//2 + self.game.corridor.width//2 - self.radius
Пример #9
0
class Dasher(Enemy):
    HOVERING = 0
    DASHING = 1

    def __init__(self, *args, **kwargs):
        super().__init__(*args, **kwargs)
        self.hover_x = c.WINDOW_WIDTH * 0.8

        self.hover_length = 2
        self.x_velocity = 0
        self.velocity = [-1, -1]
        self.hp = 7

        self.value = 6

        self.shiver_x = 0
        self.shiver_y = 0
        self.shiver_target = [1, 0]
        self.shiver_intensity = 0
        self.since_hit = 10
        self.since_particle = 0

        self.state = self.HOVERING

        self.sprite = Sprite(12)
        self.sprite.add_animation({"Hovering": dasher_hovering,
            "Dashing": dasher_dashing,
            "Damage": dasher_damage,
            "DashDamage": dasher_dashing_damage})
        self.sprite.start_animation("Hovering")

    def update(self, dt, events):
        super().update(dt, events)

        if abs(self.shiver_x - self.shiver_target[0]) < 10 and abs(self.shiver_y - self.shiver_target[1]) < 10:
            self.shiver_target[0] = random.random() * 2 * self.shiver_intensity - self.shiver_intensity
            self.shiver_target[1] = random.random() * 2 * self.shiver_intensity - self.shiver_intensity

        if self.age < self.hover_length:
            if self.x > self.hover_x:
                self.x -= (self.x - self.hover_x) * 7 * dt
            self.shiver_intensity = self.age * 10
        else:
            self.state = self.DASHING
            self.sprite.start_animation("Dashing")
            self.x_velocity = -1600
            self.x += self.x_velocity * dt
            self.shiver_target = [0, 0]

        self.shiver_x += (self.shiver_target[0] - self.shiver_x) * self.shiver_intensity * dt * 2.5
        self.shiver_y += (self.shiver_target[1] - self.shiver_y) * self.shiver_intensity * dt * 2.5

        self.check_player_bullets()
        if self.hp <= 0 and not self.dead:
            self.die()

        self.since_hit += dt
        self.since_particle += dt

        if self.since_hit > 0.04 and self.state == self.HOVERING:
            self.sprite.start_animation("Hovering")
        elif self.since_hit > 0.04 and self.state == self.DASHING:
            self.sprite.start_animation("Dashing")


        if self.since_particle >= 0.02:
            self.game.particles.insert(0, DasherSmokeRed(self.game, self.x, self.y))
            self.game.particles.append(DasherSmoke(self.game, self.x, self.y))
            self.since_particle = 0

        self.sprite.update(dt)

    def draw(self, surface):
        xoff = math.sin(self.age * 5) * 15
        yoff = math.sin(self.age * 7) * 15
        sx, sy = self.game.get_shake_offset()
        x, y = int(self.x + self.shiver_x + sx), int(self.y + self.shiver_y + sy)
        self.sprite.set_position((x + xoff, y + yoff))
        self.sprite.draw(surface)

    def get_hit_by(self, bullet):
        super().get_hit_by(bullet)
        if self.state == self.HOVERING:
            self.sprite.start_animation("Damage")
            self.since_hit = 0
        if self.state == self.DASHING:
            self.sprite.start_animation("DashDamage")
            self.since_hit = 0

    def die(self):
        super().die()
        self.game.shake(6)