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)
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()
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()
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()
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()
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()
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)
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()
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)
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)
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)
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)
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)
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()
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)