class MixerTest(unittest.TestCase): def setUp(self): # pygame.display.init() self.mixer = Mixer(glob.glob("assets/sound/play_menu/*")) def tearDown(self): del self.mixer def test_volume(self): self.mixer.set_volume(0.34) self.assertEqual(self.mixer.get_volume(), 0.34) self.assertAlmostEqual(self.mixer.volume, pygame.mixer.music.get_volume(), 2) def test_stop(self): self.mixer.play_random() self.assertTrue(pygame.mixer.music.get_busy()) self.mixer.stop() self.assertFalse(pygame.mixer.music.get_busy()) def test_end_event(self): self.mixer.play_random() self.mixer.stop() self.assertTrue(pygame.event.get(SOUND_END))
class PlayMenu(SpriteGroup): """Menu where the players are allowed to freely control their character(toon). The background image is chosen randomly as well as the currently playing music. """ def __init__(self, characters): """Initialize all attributes and music. utils -- SpriteGroup, contains background and timer players -- SpriteGroup, contains two characters skills -- SkillManager, contains the skills of both characters """ SpriteGroup.__init__(self) self.background = Background(random.choice(glob. glob("assets/fields/*"))) self.mana_time = 0 self.timer = Timer() self.timer.position = Vec2D(DEFAULT_SCREEN_SIZE[0] / 2, 30) self.mixer = Mixer(glob.glob("assets/sound/play_menu/*")) self.mixer.play_random() self.player1 = Character(1, characters[0], (0, 0)) self.player2 = Character(2, characters[1], DEFAULT_SCREEN_SIZE) self.skills = SkillManager(self.player1.skills, self.player2.skills) self.players = SpriteGroup(self.player1, self.player2) self.utils = SpriteGroup(self.background, self.timer) self.add(self.utils, self.players, self.skills) def update(self, time, input_list): """Consecutively update player1, player2, skill projectiles and check for collision after each update. Update enemy_position and direction attributes of each character, the background and the timer. Increase both players' mana points by a fixed rate(50 per second). PlayMenu.update(time, input_list): return None clock -- should be a pygame.time.Clock object """ self.player1.update(input_list) collide(self.player1, self.player2) collide(self.player1, self.player2.skills) self.player2.update(input_list) collide(self.player2, self.player1) collide(self.player2, self.player1.skills) self._update_enemy_positions() self.skills = SkillManager(self.player1.skills, self.player2.skills) self.skills.update(pygame.time.get_ticks()) collide(self.player2.skills, self.player1) collide(self.player1.skills, self.player2) self._boost_mana() self.utils.update(time) def _update_enemy_positions(self): """Update enemy_position and direction attributes of both characters according to their reciprocal positions. PlayMenu._update_enemy_positions(): return None Should not be used manually. """ self.player1.enemy_position = self.player2.rect self.player2.enemy_position = self.player1.rect if self.player1.position.x < self.player2.position.x: self.player1.direction = "Right" self.player2.direction = "Left" else: self.player1.direction = "Left" self.player2.direction = "Right" def _boost_mana(self): if self.timer.seconds - self.mana_time >= 1: self.player1.hud.mana.value += 50 if self.player1.hud.mana.value > self.player1.hud.mana.capacity: self.player1.hud.mana.value = self.player1.hud.mana.capacity self.player2.hud.mana.value += 50 if self.player2.hud.mana.value > self.player2.hud.mana.capacity: self.player2.hud.mana.value = self.player2.hud.mana.capacity self.mana_time = self.timer.seconds def draw(self, screen): """Draw all member sprites onto SCREEN surface. Scale SCREEN to the size of screen and draw SCREEN on screen. PlayMenu.draw(screen): return None """ super(PlayMenu, self).draw(SCREEN) screen.blit(pygame.transform.smoothscale(SCREEN, SCREEN_SIZE), (0, 0)) def stop_sound(self): """Stops any sound playback comming from both character members and the mixer. PlayMenu.stop_sound(): return None """ self.mixer.stop() self.player1.sound_effects.stop() self.player2.sound_effects.stop() def main(self, screen): """Run the play menu: process user input, update and draw all sprites onto the display. The fps is set to FPS. If the sound playback of the mixer ends a random sounds is played. PlayMenu.main(screen): return: EXIT if the display has been closed CHARACTER_MENU if the round has ended (a player died or the timer reached ROUND_TIME) """ clock = pygame.time.Clock() while True: clock.tick(FPS) pressed_keys = pygame.key.get_pressed() for event in pygame.event.get(): if event.type == pygame.QUIT: self.stop_sound() return EXIT elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: self.stop_sound() return CHARACTER_MENU elif event.type == SOUND_END: self.mixer.play_random() self.update(clock.get_time(), pressed_keys) self.draw(screen) pygame.display.flip() if (self.timer.time >= ROUND_TIME or self.player1.hud.get_health() == 0 or self.player2.hud.get_health() == 0): self.stop_sound() return CHARACTER_MENU