Exemple #1
0
    def update(self, delta_time):
        super().update(delta_time)

        # Update the transition screen shake
        if self.transition:
            self.transition_delay = approach(self.transition_delay, 0,
                                             0.06 * delta_time)

            # Check if the next scene should be loaded
            if self.transition_delay == 0:
                self.transition_delay = 50
                self.transition = False

                # Checks if it is the last scene
                if Cutscene.current_cutscene == 19:
                    self.director.change_scene(scenes.Menu(True))
                    Config.level = 1
                    Cutscene.current_cutscene = 1
                    ScreenNarrator.current_narrator = 0
                    ScreenDialog.current_dialog = 0

                # Checks wheter next scene is a combat or another cutscene
                elif Cutscene.current_cutscene in (2, 5, 6, 9, 12, 15, 18):
                    Cutscene.current_cutscene += 1
                    self.director.change_scene(scenes.Stage())
                else:
                    Cutscene.current_cutscene += 1
                    self.director.change_scene(scenes.Cutscene())
        else:
            # Update the current screen
            self.current_screen.update(delta_time, self)
Exemple #2
0
    def update(self, delta_time, scene):
        super().update(delta_time)

        # Find the nearest ball
        nearest_ball = None
        for ball in scene.balls:
            if nearest_ball is None:
                nearest_ball = ball
            elif ball.y < nearest_ball.y:
                nearest_ball = ball

        # Check if a ball was found
        if nearest_ball is not None:
            # Calculate distance to the ball
            distance_x = nearest_ball.x - self.x
            distance_y = nearest_ball.y - self.y
            angle = -math.degrees(math.atan2(
                distance_y, distance_x)) + self.angle_offset - 13.5

            # Calculate target angle
            speed = 0.025 * delta_time
            diff = cycle(angle - self.arc_angle, -180, 180)
            target_angle = diff if abs(
                diff) < speed else diff / abs(diff) * speed

            # Move the shooter
            self.arc_angle = clamp(self.arc_angle + target_angle,
                                   self.min_angle, self.max_angle)

            # Move the gear
            if self.min_angle < self.arc_angle < self.max_angle:
                self.polygon_smooth += target_angle * 0.1 * delta_time

        # Reduce shoot delay
        self.shoot_delay = approach(self.shoot_delay, 0, 0.06 * delta_time)

        # Shoot
        if self.shoot_delay == 0 and not scene.score and self.cooldown == 0:
            # Reset cooldown
            self.cooldown = self.max_cooldown

            # Calculate new shoot delay
            self.shoot_delay = random.randint(self.min_shoot_delay,
                                              self.max_shoot_delay)

            # Calculate new angle offset
            self.angle_offset = random.randint(-5, 5)

            # Instantiate the projectile
            scene.projectiles.add(
                Projectile(self.x, self.y, self.color,
                           -(self.arc_angle + 13.5), 20))

            # Play a shooting sound
            random.choice(self.snd_shoot).play()
Exemple #3
0
    def update(self, delta_time):
        # Increase the radius of the explosion
        self.radius = ease_in_out_circle(self.frame, self.start, self.target,
                                         self.duration)

        # Calculate the next frame
        self.frame = approach(self.frame, self.duration, 0.06 * delta_time)

        # Destroy explosion particle
        if self.frame == self.duration:
            self.destroy()
Exemple #4
0
    def update(self, delta_time):
        # Calculate the new position
        self.x, self.y = polygon_coordinate(self.x, self.y, self.angle,
                                            0.24 * delta_time)

        # Reduce time left
        self.duration = approach(self.duration, 0, 0.2 * delta_time)

        # Destroy slash particle
        if self.duration == 0:
            self.destroy()
Exemple #5
0
    def update(self, delta_time, scene):
        # Check for sleep
        if self.sleep_ticks > 0:
            self.sleep_ticks = approach(self.sleep_ticks, 0, 0.06 * delta_time)
        else:            
            # Check if a character should be added
            if self.ticks == self.interval and self.input_string != '':
                self.ticks = 0
                
                new_char = self.input_string[0]

                # Sleep on space or punctuation mark
                if new_char == ' ':
                    self.sleep_ticks = round(self.interval / 3)
                elif new_char in [',', '.', ':', '?', '!']:
                    self.sleep_ticks = self.interval * 8
                
                # Add new character
                self.process_line()
                self.snd_blit.play()
            
            self.ticks = approach(self.ticks, self.interval, 0.06 * delta_time)

        # Finish text scroll or proceed to next line
        if self.key_interact:
            if self.input_string != '':
                while self.input_string != '':
                    self.process_line()
                
                self.ticks = 0
                self.sleep_ticks = 0
            elif self.current_index + 1 < len(self.line_list):
                # Reset line
                self.current_index += 1
                self.current_string = ''
                self.current_line = ''
                self.input_string = self.line_list[self.current_index]
                
            # Stop the dialog
            else:
                scene.stop()
Exemple #6
0
    def update(self, delta_time):
        # Calculate the new position
        self.x += self.hspeed * 0.06 * delta_time
        self.y += self.vspeed * 0.06 * delta_time

        # Calculate the current sub-image
        self.image_index = approach(self.image_index, len(self.sprite_sheet),
                                    self.image_speed * delta_time)

        # Destroy dust particle
        if self.image_index == len(self.sprite_sheet):
            self.destroy()
Exemple #7
0
    def update(self, delta_time, scene):
        # Update the transition
        if self.transition:
            if self.transition_delay == 0:
                scene.start()
            else:
                self.transition_delay = approach(self.transition_delay, 0,
                                                 0.06 * delta_time)

        # Update the instructions
        self.instructions.update(delta_time, self)

        # Update the top particles
        self.top_particles.update(delta_time)
Exemple #8
0
    def update(self, delta_time):
        # Calculate the current sub-image
        self.image_index = clamp(
            self.image_index + self.image_speed * delta_time, 0,
            len(self.sprite_sheet) - 1)

        # Keep the screen black
        if self.image_index == len(self.sprite_sheet) - 1:
            self.image_speed = 0
            self.timer = approach(self.timer, 25, 0.06 * delta_time)
            if self.timer == 25:
                self.image_speed = -0.015
                Fade.reverse = True

        # Destroy fade animation
        if self.image_speed < 0 and self.image_index == 0:
            self.destroy()
Exemple #9
0
    def update(self, delta_time):
        if not self.paused:
            # Change animation
            if self.frame == self.max_frames:
                self.frame = 0

                # From animation go down to animation go up
                if self.animation == 0:
                    self.animation = 1

                # From animation go up to animation go down
                elif self.animation == 1:
                    self.animation = 0
            else:
                # Calculate the next frame
                self.frame = approach(self.frame, self.max_frames,
                                      0.06 * delta_time)
Exemple #10
0
    def update(self, delta_time, scene):
        # Change animation
        if self.frame == self.max_frames[self.animation]:
            self.frame = 0

            # From animation go up to animation go down
            if self.animation == 1:
                self.animation = 2

                # Explosion particles
                for ball in scene.balls:
                    scene.top_particles.add(
                        Explosion(ball.x, ball.y, Colors.LIGHT_WHITE,
                                  ball.radius, 75))

            # From animation go down to animation go up
            elif self.animation == 2:
                self.animation = 1

                # Explosion particles
                for ball in scene.balls:
                    scene.top_particles.add(
                        Explosion(ball.x, ball.y, Colors.LIGHT_WHITE,
                                  ball.radius, 75))

            # From animation static to animation go up
            else:
                self.animation = 1

                # Explosion particles
                for ball in scene.balls:
                    scene.top_particles.add(
                        Explosion(ball.x, ball.y, Colors.LIGHT_WHITE,
                                  ball.radius, 75))
        else:
            # Calculate the next frame
            self.frame = approach(self.frame, self.max_frames[self.animation],
                                  0.06 * delta_time)
Exemple #11
0
    def update(self, delta_time, scene):
        # Update the entities
        self.entities.update(delta_time, self)

        # Update the projectiles
        self.projectiles.update(delta_time, self)

        # Update the balls
        self.balls.update(delta_time, self)

        # Update the top particles
        self.top_particles.update(delta_time)

        # Update the bottom particles
        self.bottom_particles.update(delta_time)

        # Check if an entity has score
        if self.score:
            # Wait until all the balls have been removed to reset the scene
            if len(self.top_particles) == 0 and len(self.balls) == 0:
                # Check if the stage has ended
                self.check_score(scene)

                # Reset score
                self.score = False

                # Reset the time for the next ball
                self.ball_time = self.ball_delay

                # Add the balls with which the stage began
                for x, y, radius in self.stage_balls:
                    self.balls.add(Ball(x, y, radius))
        
        else:
            # Check if the screen have to shake
            if self.shake:
                # Stop screen shake
                if self.shake_time == 0:
                    self.shake = False
                    self.shake_time = self.shake_duration
                
                # Reduce time left
                else:
                    self.shake_time = approach(self.shake_time, 0, 0.06 * delta_time)

            # Check if a new ball should appear
            if len(self.balls) < self.max_balls and self.ball_time == 0:
                # Check if the new ball would collide
                if collide(self.balls):
                    # If the new ball collides, its appearance is delayed
                    self.ball_time = 60
                
                # Spawn a new ball
                else:
                    # Reset the time for the next ball
                    self.ball_time = self.ball_delay * len(self.balls)

                    # Add a new ball to the stage
                    self.balls.add(Ball(125, 175, 10))

                    # Play a sound when a new ball appears
                    random.choice(self.snd_ball).play()
            
            # Reduce time left
            else:
                self.ball_time = approach(self.ball_time, 0, 0.06 * delta_time)
Exemple #12
0
 def update(self, delta_time):
     # Gear movement
     self.polygon_angle = angle_rotate(self.polygon_angle, self.polygon_smooth, 0.15 * delta_time)
     
     # Reduce cooldown
     self.cooldown = approach(self.cooldown, 0, 0.06 * delta_time)
Exemple #13
0
    def update(self, delta_time, scene):
        # Destroy projectile by radius
        if self.radius == 0:
            self.destroy()
            return

        # Calculate the new position
        percentage = self.radius / self.max_radius
        speed = 0.47 * percentage * delta_time
        self.x = clamp(self.x + speed * math.cos(math.radians(self.angle)),
                       self.radius, 250 - self.radius)
        self.y = clamp(self.y + speed * math.sin(math.radians(self.angle)), 0,
                       350)

        # Reverse projectile direction when the projectile collides with the sides
        if self.x == self.radius or self.x == 250 - self.radius:
            self.angle = cycle(180 - self.angle, -180, 180)

        # Create the trail particles
        x = self.x + random.randint(0, round(self.radius)) - self.radius / 2
        y = self.y + random.randint(0, round(self.radius)) - self.radius / 27
        image_speed = random.uniform(0.005, 0.01)

        scene.bottom_particles.add(
            Dust(x, y, Colors.LIGHT_GREY, 0, 0, image_speed))

        # Detect collisions between projectiles
        for projectile in scene.projectiles:
            # If is a projectile of the same entity continue
            if self.color == projectile.color:
                continue

            # Calculate distance to the projectile
            distance_x = projectile.x - self.x
            distance_y = projectile.y - self.y
            distance = math.hypot(distance_x, distance_y)

            # Detect if the projectile is close enough to another projectile
            if distance <= projectile.radius + self.radius:
                # The projectile with smaller radius is destroyed
                if self.radius < projectile.radius:
                    self.collide = True
                elif projectile.radius < self.radius:
                    projectile.collide = True
                else:
                    self.collide = True
                    projectile.collide = True

        # Detect collisions with balls
        for ball in scene.balls:
            # Calculate distance to the ball
            distance_x = ball.x - self.x
            distance_y = ball.y - self.y
            distance = math.hypot(distance_x, distance_y)

            # Detect if the projectile is close enough to a ball
            if distance <= ball.radius + self.radius:
                # How the projectile collided has to be destroyed
                self.collide = True

                # Calculate the direction after collide
                collision_angle = math.atan2(distance_y, distance_x)
                ball.hspeed = (ball.hspeed / 3
                               ) + 1.5 * percentage * math.cos(collision_angle)
                ball.vspeed = (ball.vspeed / 3
                               ) + 1.5 * percentage * math.sin(collision_angle)

                # Slash particles up
                x, y = polygon_coordinate(self.x, self.y,
                                          math.degrees(collision_angle),
                                          self.radius)
                for _ in range(random.randint(2, 4)):
                    angle = math.degrees(collision_angle) + random.randint(
                        -60, 60)
                    duration = percentage * random.randint(50, 100)

                    scene.top_particles.add(
                        Slash(x, y, Colors.LIGHT_WHITE, angle, duration))

                # Slash particles down
                for _ in range(random.randint(1, 2)):
                    angle = math.degrees(-collision_angle) + random.randint(
                        -60, 60)
                    duration = percentage * random.randint(30, 60)

                    scene.top_particles.add(
                        Slash(x, y, Colors.LIGHT_WHITE, angle, duration))

                # Play the collision sound
                random.choice(self.snd_collide).play()

        # Check if the projectile has collided
        if self.collide:
            # Make the sceen shake
            scene.shake = True

            # Dush particles
            radius = round(self.radius / 2)
            for _ in range(radius):
                x = self.x + random.randint(-radius, radius)
                y = self.y + random.randint(-radius, radius)
                hspeed = 1.5 * math.cos(math.radians(
                    self.angle)) + random.randint(-2, 2)
                vspeed = 1.5 * math.sin(math.radians(
                    self.angle)) + random.randint(-2, 2)
                image_speed = random.uniform(0.005, 0.01)

                scene.top_particles.add(
                    Dust(x, y, self.color, hspeed, vspeed, image_speed))

            # Destroy projectile by collision
            self.destroy()
            return

        # Reduce projectile radius
        self.radius = approach(self.radius, 0, 0.015 * delta_time)
Exemple #14
0
    def update(self, delta_time, scene):
        # Check if the ball has to be destroyed
        if scene.score:
            # Dust particles
            radius = round(self.radius)
            for _ in range(20):
                x = self.x + random.randint(-radius, radius)
                y = self.y + random.randint(-radius, radius)
                hspeed = random.randint(-3, 3)
                vspeed = random.randint(-3, 3)
                image_speed = random.uniform(0.005, 0.01)
                scene.top_particles.add(Dust(x, y, Colors.LIGHT_WHITE, hspeed, vspeed, image_speed))
            
            # Explosion particles
            scene.top_particles.add(Explosion(self.x, self.y, Colors.LIGHT_WHITE, self.radius, 100))
            
            # Destroy the ball
            self.destroy()
            return
        
        # Reverse ball direction when the projectile collides with the sides
        if self.x == self.min_x or self.x == self.max_x:
            self.hspeed = -self.hspeed
        
        # Reduce speed
        self.hspeed = approach(self.hspeed, 0, 0.00001 * delta_time)
        self.vspeed = approach(self.vspeed, 0, 0.00001 * delta_time)

        # Calculate the new position
        self.x = clamp(self.x + self.hspeed * 0.06 * delta_time, self.min_x, self.max_x)
        self.y = clamp(self.y + self.vspeed * 0.06 * delta_time, self.min_y, self.max_y)

        # Check if the ball is inside the enemy goal
        if self.y == self.min_y:
            # Make the sceen shake
            scene.shake = True
            
            # Update the scene
            scene.score = True

            # Add the score to the player
            scene.player_score += 1

            # Explosion particles
            scene.top_particles.add(Explosion(self.x, self.min_y, Colors.LIGHT_WHITE, self.radius, 225))
            
            # Play the score sound
            random.choice(self.snd_score).play()

            # Play the explosion sound
            self.snd_explosion.play()

            # Destroy ball
            self.destroy()
            return
        
        # Check if the ball is inside the player goal
        elif self.y == self.max_y:
            # Make the sceen shake
            scene.shake = True
            
            # Update the scene
            scene.score = True

            # Add the score to the enemy
            scene.enemy_score += 1

            # Explosion particles
            scene.top_particles.add(Explosion(self.x, self.max_y, Colors.LIGHT_WHITE, self.radius, 225))
            
            # Play the score sound
            random.choice(self.snd_score).play()

            # Play the explosion sound
            self.snd_explosion.play()

            # Destroy ball
            self.destroy()
            return
        
        # Detect collisions between balls
        speed = 0.7 * math.hypot(self.hspeed, self.vspeed)
        for ball in scene.balls:
            # If is the same ball continue
            if ball == self:
                continue
            
            # Calculate distance to the ball
            distance_x = ball.x - self.x
            distance_y = ball.y - self.y
            distance = math.hypot(distance_x, distance_y)

            # Detect if the ball is close enough to another ball
            if distance <= ball.radius + self.radius:
                # Make the sceen shake
                scene.shake = True
                
                # Calculate the direction after collide
                collision_angle = math.atan2(distance_y, distance_x)
                hspeed = -speed * math.cos(collision_angle)
                vspeed = -speed * math.sin(collision_angle)
                
                if hspeed != 0 or vspeed != 0:
                    self.hspeed = hspeed
                    self.vspeed = vspeed
                    ball.hspeed = -hspeed
                    ball.vspeed = -vspeed
                
                # Plan B if the ball is inside another
                else:
                    self.hspeed = 0.5 * (1 + random.random())
                    self.vspeed = 0.5 * (1 + random.random())
                    ball.hspeed = -(0.5 * (1 + random.random()))
                    ball.vspeed = -(0.5 * (1 + random.random()))
                
                # Slash particles
                x, y = polygon_coordinate(self.x, self.y, math.degrees(collision_angle), self.radius)
                for _ in range(random.randint(1, 2)):
                    angle = math.degrees(collision_angle+90) + random.randint(-60, 60)
                    duration = speed * random.randint(30, 60)

                    scene.top_particles.add(Slash(x, y, Colors.LIGHT_WHITE, angle, duration))
                
                for _ in range(random.randint(1, 2)):
                    angle = math.degrees(collision_angle-90) + random.randint(-60, 60)
                    duration = speed * random.randint(30, 60)

                    scene.top_particles.add(Slash(x, y, Colors.LIGHT_WHITE, angle, duration))

                # Play the collision sound
                random.choice(self.snd_collide).play()
Exemple #15
0
    def update(self, delta_time, scene):
        # Check for sleep
        if self.sleep_ticks > 0:
            self.sleep_ticks = approach(self.sleep_ticks, 0, 0.06 * delta_time)
        else:
            # Calculate the current sub-image
            if self.input_string == '':
                self.box_pause_index = approach(self.box_pause_index,
                                                len(self.spr_box_pause),
                                                0.005 * delta_time)
                if self.box_pause_index == len(self.spr_box_pause):
                    self.box_pause_index = 0

            # Check if a character should be added
            elif self.ticks == self.interval:
                self.ticks = 0

                new_char = self.input_string[0]

                # Sleep on space or punctuation mark
                if new_char == ' ':
                    self.sleep_ticks = round(self.interval / 3)
                elif new_char in [',', '.', ':', '?', '!']:
                    self.sleep_ticks = self.interval * 8

                # Add new character
                self.process_line()
                self.snd_blit.play()

            self.ticks = approach(self.ticks, self.interval, 0.06 * delta_time)

        # Finish text scroll or proceed to next line
        if self.key_interact:
            self.box_pause_index = 0

            if self.input_string != '':
                while self.input_string != '':
                    self.process_line()

                self.ticks = 0
                self.sleep_ticks = 0

            # Load next line
            elif self.current_index + 1 < len(self.line_list):
                # Reset line
                self.current_index += 1
                self.current_string = ''
                self.current_line = ''
                self.input_string = self.line_list[self.current_index]

                # Check if the portrait should be changed
                last_sprite = self.sprite_list[self.current_index - 1]
                new_sprite = self.sprite_list[self.current_index]
                if last_sprite != new_sprite:
                    self.portrait_left.pause()
                    self.portrait_right.pause()
                    if self.speaker == 0:
                        self.speaker = 1
                        self.sprite_left = self.portrait[last_sprite][
                            'shade_flip']
                        self.sprite_right = self.portrait[new_sprite][
                            'original']
                    elif self.speaker == 1:
                        self.speaker = 0
                        self.sprite_left = self.portrait[new_sprite][
                            'original_flip']
                        self.sprite_right = self.portrait[last_sprite]['shade']

            # Stop the dialog
            else:
                scene.stop()

        # Update the portraits
        self.portrait_left.update(delta_time)
        self.portrait_right.update(delta_time)