class Cutscene: def __init__(self, screen=None): self.cutscenes = [] for i in range(8): self.cutscenes.append(pygame.image.load(data.filepath("scene" + str(i + 1) + ".png"))) if screen is None: pygame.init() self.screen = pygame.display.set_mode((Constants.SCREEN_WIDTH, Constants.SCREEN_HEIGHT)) else: self.screen = screen self.clock = pygame.time.Clock() self.running = True self.font = pygame.font.Font(None, 24) self.music_player = MusicPlayer("palnap4.ogg") def display(self, number): self.music_player.play() done = False while not done: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: return elif event.type == pygame.QUIT: self.running = False return self.screen.blit(self.cutscenes[number], (0, 0)) pygame.display.flip() self.clock.tick(30) self.music_player.stop()
class StageFailure: """ Just a stage clear intermission screen. Nothing at all fancy here. """ def __init__(self, screen = None): if screen is None: self.screen = pygame.display.set_mode((600, 600)) else: self.screen = screen self.running = True self.explode_anims = [] for i in range(4): self.explode_anims.append(pygame.image.load(data.filepath("explode" + str(i + 1) + ".png"))) self.explode_anims *= 3 self.music_player = MusicPlayer("palnap4.ogg") def main(self): """ Display the screen. """ self.music_player.play() current_frame = 0 clock = pygame.time.Clock() font = pygame.font.Font(None, 24) try_again_text = font.render("[ press any key to try again ]", 1, (0, 255, 255)) failure_text = font.render("You failed!", 1, (0, 255, 255)) while True: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: return elif event.type == pygame.QUIT: self.running = False return False self.screen.fill((0, 0, 20)) if current_frame < 40: current_frame += 1 self.screen.blit(self.explode_anims[(current_frame / 5)], (self.screen.get_rect().centerx - 50, self.screen.get_rect().centery - 50)) else: current_frame = 0 self.screen.blit(failure_text, (self.screen.get_rect().centerx - 50, 100)) self.screen.blit(try_again_text, (self.screen.get_rect().centerx - 125, self.screen.get_rect().centery + 200)) pygame.display.flip() clock.tick(Constants.MAX_FPS)
class TitleScreen: """ Just a stage clear intermission screen. Nothing at all fancy here. """ def __init__(self, screen=None): if screen is None: self.screen = pygame.display.set_mode((600, 600)) else: self.screen = screen self.running = True self.music_player = MusicPlayer("palnap4.ogg") self.clock = pygame.time.Clock() self.choice = 0 def main(self): """ Display the screen and a little bit of text at the bottom of the screen. """ self.music_player.play() xasm_logo = pygame.image.load(data.filepath("xasm.png")) title_screen = pygame.image.load(data.filepath("title.png")) font = pygame.font.Font(None, 24) start_game = False alpha = 0 fade_in = True logo_alpha = 0 skip = False while logo_alpha < 255 and not skip: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: skip = True elif event.type == pygame.QUIT: self.running = False return self.screen.fill((0, 0, 0)) xasm_logo.set_alpha(logo_alpha) self.screen.blit(xasm_logo, (0, 0)) logo_alpha += 3 pygame.display.flip() self.clock.tick(30) while logo_alpha > 0 and not skip: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: skip = True elif event.type == pygame.QUIT: self.running = False return self.screen.fill((0, 0, 0)) xasm_logo.set_alpha(logo_alpha) self.screen.blit(xasm_logo, (0, 0)) logo_alpha -= 3 pygame.display.flip() self.clock.tick(30) skip = False counter = 50 while counter > 0 and not skip: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: skip = True elif event.type == pygame.QUIT: self.running = False return self.screen.fill((0, 0, 0)) text = font.render("Dedicated to the memory of Phoebe...", 1, (255, 255, 255)) text2 = font.render("We'll miss you...", 1, (255, 255, 255)) self.screen.blit(text, (150, 300)) self.screen.blit(text2, (225, 325)) pygame.display.flip() self.clock.tick(30) counter -= 1 choice = 0 while not start_game: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_UP: self.choice -= 1 elif event.key == pygame.K_DOWN: self.choice += 1 elif event.key == pygame.K_RETURN: start_game = True elif event.key == pygame.K_ESCAPE: self.running = False return elif event.type == pygame.QUIT: self.running = False return if self.choice < 0: self.choice = 1 elif self.choice > 1: self.choice = 0 new_game = "[ new game ]" continue_game = "[ continue game ]" if self.choice == 0: new_game = "> " + new_game elif self.choice == 1: continue_game = "> " + continue_game # There's some weird-ass PyGame font bug in 1.7, so the text is # ant-aliased. text = font.render(new_game, 1, (5, 231, 96)) text2 = font.render(continue_game, 1, (5, 231, 96)) self.screen.blit(title_screen, (0, 0)) self.screen.blit(text, (200, 525)) self.screen.blit(text2, (200, 550)) pygame.display.flip() self.clock.tick(30) self.music_player.stop()
class Alarm: def __init__(self): self.hour = None self.minute = None self.time_window_hours = ConfigManager.get_config()['hours_to_check'] self.time_window_minutes = ConfigManager.get_config( )['minutes_to_check'] self.music_player = MusicPlayer() self.camera = Camera() self.model = Model() # for storing images self.counter = 0 def set_alarm(self, hour, minute): self.hour = hour self.minute = minute self.stop_alarm() def verify_alarm(self): d = datetime.now() hour = int(d.hour) minute = int(d.minute) if self.in_time_window(hour, minute): is_present, image = self.verify_present() if is_present: self.launch_alarm() else: self.stop_alarm() self.store_image(image) def verify_present(self): image = Camera.capture_screenshot() predictable_image = prepare_for_prediction(image) prediction = self.model.predict(predictable_image) print("Predicted: {}".format(prediction)) return prediction < 0.5, image def in_time_window(self, curr_hour, curr_minute): if self.hour is None or self.minute is None: return False if curr_hour is None or curr_minute is None: d = datetime.now() curr_hour = int(d.hour) curr_minute = int(d.minute) # Compare hour after_alarm = self.hour < curr_hour # CCompare minute if needed if not after_alarm: after_alarm = self.hour == curr_hour and \ self.minute <= curr_minute target_hour = self.hour + self.time_window_hours target_minute = self.minute + self.time_window_minutes # Compare hour before_wind_end = curr_hour < target_hour # Compare minute if needed if not before_wind_end: before_wind_end = curr_hour == target_hour and \ curr_minute <= target_minute return after_alarm and before_wind_end def launch_alarm(self): self.music_player.play() def stop_alarm(self): self.music_player.stop() def store_image(self, image): # activates once every 3 iterations self.counter = self.counter + 1 if self.counter >= 2: self.counter = 0 Camera.save_image(image)
class TitleScreen: """ Just a stage clear intermission screen. Nothing at all fancy here. """ def __init__(self, screen = None): if screen is None: self.screen = pygame.display.set_mode((600, 600)) else: self.screen = screen self.running = True self.music_player = MusicPlayer("palnap4.ogg") self.clock = pygame.time.Clock() self.choice = 0 def main(self): """ Display the screen and a little bit of text at the bottom of the screen. """ self.music_player.play() xasm_logo = pygame.image.load(data.filepath("xasm.png")) title_screen = pygame.image.load(data.filepath("title.png")) font = pygame.font.Font(None, 24) start_game = False alpha = 0 fade_in = True logo_alpha = 0 skip = False while logo_alpha < 255 and not skip: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: skip = True elif event.type == pygame.QUIT: self.running = False return self.screen.fill((0, 0, 0)) xasm_logo.set_alpha(logo_alpha) self.screen.blit(xasm_logo, (0, 0)) logo_alpha += 3 pygame.display.flip() self.clock.tick(30) while logo_alpha > 0 and not skip: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: skip = True elif event.type == pygame.QUIT: self.running = False return self.screen.fill((0, 0, 0)) xasm_logo.set_alpha(logo_alpha) self.screen.blit(xasm_logo, (0, 0)) logo_alpha -= 3 pygame.display.flip() self.clock.tick(30) skip = False counter = 50 while counter > 0 and not skip: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: skip = True elif event.type == pygame.QUIT: self.running = False return self.screen.fill((0, 0, 0)) text = font.render("Dedicated to the memory of Phoebe...", 1, (255, 255, 255)) text2 = font.render("We'll miss you...", 1, (255, 255, 255)) self.screen.blit(text, (150, 300)) self.screen.blit(text2, (225, 325)) pygame.display.flip() self.clock.tick(30) counter -= 1 choice = 0 while not start_game: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_UP: self.choice -= 1 elif event.key == pygame.K_DOWN: self.choice += 1 elif event.key == pygame.K_RETURN: start_game = True elif event.key == pygame.K_ESCAPE: self.running = False return elif event.type == pygame.QUIT: self.running = False return if self.choice < 0: self.choice = 1 elif self.choice > 1: self.choice = 0 new_game = "[ new game ]" continue_game = "[ continue game ]" if self.choice == 0: new_game = "> " + new_game elif self.choice == 1: continue_game = "> " + continue_game # There's some weird-ass PyGame font bug in 1.7, so the text is # ant-aliased. text = font.render(new_game, 1, (5, 231, 96)) text2 = font.render(continue_game, 1, (5, 231, 96)) self.screen.blit(title_screen, (0, 0)) self.screen.blit(text, (200, 525)) self.screen.blit(text2, (200, 550)) pygame.display.flip() self.clock.tick(30) self.music_player.stop()
class EscortEngine: """ This is the main engine to be used in the game. This is the Lemmings-esque escort engine. Call set_stage(#) before calling main(). """ def __init__(self, screen=None): # See if we've been given a screen to use if screen is None: self.screen = pygame.display.set_mode((600, 600)) else: self.screen = screen self.running = True self.clock = pygame.time.Clock() # Gots to have us a background and a walkable mask self.background = None self.mask = None # If anyone takes screenshots, they can do so with this! self.screenshot_counter = 0 # Initialize our reusable robotic girl self.girl = Girl() # What is the current state of our game self.state = "Running" # Load our music player self.music_player = MusicPlayer() self.sound_player = SoundPlayer() self.girl.sound_player = self.sound_player def set_stage(self, stage_number): """ Set the current stage to the specified number and load the appropriate images. In addition, set the starting information for the player. Then, set the mask/image to the proper images and blit the background to the screen. """ if stage_number == 1: self.background = pygame.image.load(data.filepath("stage8.png")) self.original_mask = pygame.image.load( data.filepath("stage8_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 150) self.music_player.load("alma_mater.ogg") elif stage_number == 2: self.background = pygame.image.load(data.filepath("stage1.png")) self.original_mask = pygame.image.load( data.filepath("stage1_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 525) self.music_player.load("alma_mater.ogg") elif stage_number == 3: self.background = pygame.image.load(data.filepath("stage5.png")) self.original_mask = pygame.image.load( data.filepath("stage5_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 500) self.music_player.load("alma_mater.ogg") elif stage_number == 4: self.background = pygame.image.load(data.filepath("stage4.png")) self.original_mask = pygame.image.load( data.filepath("stage4_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 100) self.music_player.load("alma_mater.ogg") elif stage_number == 5: self.background = pygame.image.load(data.filepath("stage2.png")) self.original_mask = pygame.image.load( data.filepath("stage2_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (25, 100) self.music_player.load("alma_mater.ogg") elif stage_number == 6: self.background = pygame.image.load(data.filepath("stage10.png")) self.original_mask = pygame.image.load( data.filepath("stage10_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 75) self.music_player.load("jam_box_public.ogg") elif stage_number == 7: self.background = pygame.image.load(data.filepath("stage3.png")) self.original_mask = pygame.image.load( data.filepath("stage3_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 100) self.music_player.load("jam_box_public.ogg") elif stage_number == 8: self.background = pygame.image.load(data.filepath("stage13.png")) self.original_mask = pygame.image.load( data.filepath("stage13_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 135) self.music_player.load("jam_box_public.ogg") elif stage_number == 9: self.background = pygame.image.load(data.filepath("stage6.png")) self.original_mask = pygame.image.load( data.filepath("stage6_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 225) self.music_player.load("jam_box_public.ogg") elif stage_number == 10: self.background = pygame.image.load(data.filepath("stage7.png")) self.original_mask = pygame.image.load( data.filepath("stage7_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 300) self.girl.modifier = Constants.ANTIGRAVITY self.girl.image = pygame.transform.flip(self.girl.image, False, True) self.music_player.load("jam_box_public.ogg") elif stage_number == 11: self.background = pygame.image.load(data.filepath("stage14.png")) self.original_mask = pygame.image.load( data.filepath("stage14_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 135) self.girl.modifier = Constants.ANTIGRAVITY self.girl.image = pygame.transform.flip(self.girl.image, False, True) self.music_player.load("rejects.ogg") elif stage_number == 12: self.background = pygame.image.load(data.filepath("stage9.png")) self.original_mask = pygame.image.load( data.filepath("stage9_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 450) self.music_player.load("rejects.ogg") elif stage_number == 13: self.background = pygame.image.load(data.filepath("stage12.png")) self.original_mask = pygame.image.load( data.filepath("stage12_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 475) self.music_player.load("rejects.ogg") elif stage_number == 14: self.background = pygame.image.load(data.filepath("stage11.png")) self.original_mask = pygame.image.load( data.filepath("stage11_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 75) self.music_player.load("rejects.ogg") elif stage_number == 15: self.background = pygame.image.load(data.filepath("stage15.png")) self.original_mask = pygame.image.load( data.filepath("stage15_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (305, 311) self.music_player.load("rejects.ogg") elif stage_number == 16: self.background = pygame.image.load(data.filepath("stage16.png")) self.original_mask = pygame.image.load( data.filepath("stage16_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 475) self.music_player.load("manna_and_me.ogg") elif stage_number == 17: self.background = pygame.image.load(data.filepath("stage17.png")) self.original_mask = pygame.image.load( data.filepath("stage17_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 125) self.music_player.load("manna_and_me.ogg") elif stage_number == 18: self.background = pygame.image.load(data.filepath("stage18.png")) self.original_mask = pygame.image.load( data.filepath("stage18_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 140) self.girl.modifier = Constants.ANTIGRAVITY self.girl.image = pygame.transform.flip(self.girl.image, False, True) self.music_player.load("manna_and_me.ogg") elif stage_number == 19: self.background = pygame.image.load(data.filepath("stage19.png")) self.original_mask = pygame.image.load( data.filepath("stage19_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 410) self.music_player.load("manna_and_me.ogg") elif stage_number == 20: self.background = pygame.image.load(data.filepath("stage20.png")) self.original_mask = pygame.image.load( data.filepath("stage20_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (75, 110) self.music_player.load("manna_and_me.ogg") # All of that is done; now set up the initial environment to have the # player wander around in. self.mask = pygame.surface.Surface(self.original_mask.get_rect().size) self.mask.blit(self.original_mask, (0, 0)) self.screen.blit(self.background, (0, 0)) def grab_screenshot(self): """ Take a screenshot of the current screen. """ pygame.image.save(self.screen, "screenshot" + str(self.screenshot_counter) + ".bmp") self.screenshot_counter += 1 def main(self): """ The main game loop. Be sure to call set_stage(#) first! """ # Initialize our player sprite group player_group = pygame.sprite.RenderPlain(self.girl) # Initialize all of our "wrenches", or in-game draggable objects wrenches = [] wrench_group = GobjectGroup() for i in range(Constants.START_BLOCKS): wrenches.append(WrenchBlock()) wrench_group.add(wrenches[i]) self.music_player.play() # Game loop! while self.running: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_s: self.grab_screenshot() elif event.key == pygame.K_ESCAPE: self.state = "exit" self.running = False elif event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1: wrench_group.handle_click(True) elif event.type == pygame.MOUSEBUTTONUP: if event.button == 1: wrench_group.handle_click(False) elif event.type == pygame.QUIT: self.running = False # Clear all of the drawn sprites player_group.clear(self.screen, self.background) wrench_group.clear(self.screen, self.background) # This special little bit right here is for handling masks with the # draggable objects. wrench_group.clear(self.mask, self.original_mask) wrench_group.update() wrench_group.draw_to_mask(self.mask) # Update the player player_group.update(self.mask) # Draw the player and the wrenches to the screen player_group.draw(self.screen) wrench_group.draw(self.screen) pygame.display.flip() self.clock.tick(Constants.MAX_FPS) # If we've hit a condition to end the game, do so. if self.girl.done: self.girl.done = False self.state = "victory" self.running = False elif not self.girl.living: self.girl.living = True self.state = "failure" self.running = False self.music_player.stop()
class EscortEngine: """ This is the main engine to be used in the game. This is the Lemmings-esque escort engine. Call set_stage(#) before calling main(). """ def __init__(self, screen=None): # See if we've been given a screen to use if screen is None: self.screen = pygame.display.set_mode((600, 600)) else: self.screen = screen self.running = True self.clock = pygame.time.Clock() # Gots to have us a background and a walkable mask self.background = None self.mask = None # If anyone takes screenshots, they can do so with this! self.screenshot_counter = 0 # Initialize our reusable robotic girl self.girl = Girl() # What is the current state of our game self.state = "Running" # Load our music player self.music_player = MusicPlayer() self.sound_player = SoundPlayer() self.girl.sound_player = self.sound_player def set_stage(self, stage_number): """ Set the current stage to the specified number and load the appropriate images. In addition, set the starting information for the player. Then, set the mask/image to the proper images and blit the background to the screen. """ if stage_number == 1: self.background = pygame.image.load(data.filepath("stage8.png")) self.original_mask = pygame.image.load(data.filepath("stage8_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 150) self.music_player.load("alma_mater.ogg") elif stage_number == 2: self.background = pygame.image.load(data.filepath("stage1.png")) self.original_mask = pygame.image.load(data.filepath("stage1_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 525) self.music_player.load("alma_mater.ogg") elif stage_number == 3: self.background = pygame.image.load(data.filepath("stage5.png")) self.original_mask = pygame.image.load(data.filepath("stage5_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 500) self.music_player.load("alma_mater.ogg") elif stage_number == 4: self.background = pygame.image.load(data.filepath("stage4.png")) self.original_mask = pygame.image.load(data.filepath("stage4_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 100) self.music_player.load("alma_mater.ogg") elif stage_number == 5: self.background = pygame.image.load(data.filepath("stage2.png")) self.original_mask = pygame.image.load(data.filepath("stage2_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (25, 100) self.music_player.load("alma_mater.ogg") elif stage_number == 6: self.background = pygame.image.load(data.filepath("stage10.png")) self.original_mask = pygame.image.load(data.filepath("stage10_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 75) self.music_player.load("jam_box_public.ogg") elif stage_number == 7: self.background = pygame.image.load(data.filepath("stage3.png")) self.original_mask = pygame.image.load(data.filepath("stage3_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 100) self.music_player.load("jam_box_public.ogg") elif stage_number == 8: self.background = pygame.image.load(data.filepath("stage13.png")) self.original_mask = pygame.image.load(data.filepath("stage13_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 135) self.music_player.load("jam_box_public.ogg") elif stage_number == 9: self.background = pygame.image.load(data.filepath("stage6.png")) self.original_mask = pygame.image.load(data.filepath("stage6_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 225) self.music_player.load("jam_box_public.ogg") elif stage_number == 10: self.background = pygame.image.load(data.filepath("stage7.png")) self.original_mask = pygame.image.load(data.filepath("stage7_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 300) self.girl.modifier = Constants.ANTIGRAVITY self.girl.image = pygame.transform.flip(self.girl.image, False, True) self.music_player.load("jam_box_public.ogg") elif stage_number == 11: self.background = pygame.image.load(data.filepath("stage14.png")) self.original_mask = pygame.image.load(data.filepath("stage14_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 135) self.girl.modifier = Constants.ANTIGRAVITY self.girl.image = pygame.transform.flip(self.girl.image, False, True) self.music_player.load("rejects.ogg") elif stage_number == 12: self.background = pygame.image.load(data.filepath("stage9.png")) self.original_mask = pygame.image.load(data.filepath("stage9_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 450) self.music_player.load("rejects.ogg") elif stage_number == 13: self.background = pygame.image.load(data.filepath("stage12.png")) self.original_mask = pygame.image.load(data.filepath("stage12_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 475) self.music_player.load("rejects.ogg") elif stage_number == 14: self.background = pygame.image.load(data.filepath("stage11.png")) self.original_mask = pygame.image.load(data.filepath("stage11_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 75) self.music_player.load("rejects.ogg") elif stage_number == 15: self.background = pygame.image.load(data.filepath("stage15.png")) self.original_mask = pygame.image.load(data.filepath("stage15_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (305, 311) self.music_player.load("rejects.ogg") elif stage_number == 16: self.background = pygame.image.load(data.filepath("stage16.png")) self.original_mask = pygame.image.load(data.filepath("stage16_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 475) self.music_player.load("manna_and_me.ogg") elif stage_number == 17: self.background = pygame.image.load(data.filepath("stage17.png")) self.original_mask = pygame.image.load(data.filepath("stage17_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 125) self.music_player.load("manna_and_me.ogg") elif stage_number == 18: self.background = pygame.image.load(data.filepath("stage18.png")) self.original_mask = pygame.image.load(data.filepath("stage18_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 140) self.girl.modifier = Constants.ANTIGRAVITY self.girl.image = pygame.transform.flip(self.girl.image, False, True) self.music_player.load("manna_and_me.ogg") elif stage_number == 19: self.background = pygame.image.load(data.filepath("stage19.png")) self.original_mask = pygame.image.load(data.filepath("stage19_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (0, 410) self.music_player.load("manna_and_me.ogg") elif stage_number == 20: self.background = pygame.image.load(data.filepath("stage20.png")) self.original_mask = pygame.image.load(data.filepath("stage20_mask.png")) self.girl.direction = 0 self.girl.rect.topleft = (75, 110) self.music_player.load("manna_and_me.ogg") # All of that is done; now set up the initial environment to have the # player wander around in. self.mask = pygame.surface.Surface(self.original_mask.get_rect().size) self.mask.blit(self.original_mask, (0, 0)) self.screen.blit(self.background, (0, 0)) def grab_screenshot(self): """ Take a screenshot of the current screen. """ pygame.image.save(self.screen, "screenshot" + str(self.screenshot_counter) + ".bmp") self.screenshot_counter += 1 def main(self): """ The main game loop. Be sure to call set_stage(#) first! """ # Initialize our player sprite group player_group = pygame.sprite.RenderPlain(self.girl) # Initialize all of our "wrenches", or in-game draggable objects wrenches = [] wrench_group = GobjectGroup() for i in range(Constants.START_BLOCKS): wrenches.append(WrenchBlock()) wrench_group.add(wrenches[i]) self.music_player.play() # Game loop! while self.running: for event in pygame.event.get(): if event.type == pygame.KEYDOWN: if event.key == pygame.K_s: self.grab_screenshot() elif event.key == pygame.K_ESCAPE: self.state = "exit" self.running = False elif event.type == pygame.MOUSEBUTTONDOWN: if event.button == 1: wrench_group.handle_click(True) elif event.type == pygame.MOUSEBUTTONUP: if event.button == 1: wrench_group.handle_click(False) elif event.type == pygame.QUIT: self.running = False # Clear all of the drawn sprites player_group.clear(self.screen, self.background) wrench_group.clear(self.screen, self.background) # This special little bit right here is for handling masks with the # draggable objects. wrench_group.clear(self.mask, self.original_mask) wrench_group.update() wrench_group.draw_to_mask(self.mask) # Update the player player_group.update(self.mask) # Draw the player and the wrenches to the screen player_group.draw(self.screen) wrench_group.draw(self.screen) pygame.display.flip() self.clock.tick(Constants.MAX_FPS) # If we've hit a condition to end the game, do so. if self.girl.done: self.girl.done = False self.state = "victory" self.running = False elif not self.girl.living: self.girl.living = True self.state = "failure" self.running = False self.music_player.stop()
class AlarmWorker(Worker): def __init__(self, holder): super().__init__(holder) self._config = Config() self._player = MusicPlayer() self._load_alarms() self._time_pattern = re.compile('^([012]\d):(\d\d)$') self._old_time_str = '' self._alarm_is_playing = False def on_connect(self, client, userdata, flags): super().on_connect(client, userdata, flags) client.subscribe(ALARM_TOPIC_SUBSCRIBE) def on_message(self, client, userdata, msg): super().on_message(client, userdata, msg) payload = msg.payload.decode('UTF-8') if msg.topic.startswith(ALARM_TOPIC_ROOT): command = msg.topic.rsplit("/", 1)[-1] if command == 'add': alarm_time = payload if alarm_time != '': rst = self._time_pattern.match(alarm_time) if rst is not None: hour = int(rst.group(1)) minute = int(rst.group(2)) if hour < 24 and minute < 60: alarm = self._find_alarm(alarm_time) if alarm is None: self._alarms.append(Alarm(alarm_time)) else: alarm.enable() self._save_alarms() elif command == 'stop': self._stop_alarm() elif command == 'delete': alarm_time = payload alarm = self._find_alarm(alarm_time) if alarm is not None: self._alarms.remove(alarm) print('delete:', self._alarms) client.publish(msg.topic + '/reply', payload='ok', qos=1) self._save_alarms() else: client.publish(msg.topic + '/reply', payload='Alarm not exist!', qos=1) elif command == 'enable': alarm_time = payload alarm = self._find_alarm(alarm_time) if alarm is not None: alarm.enable() client.publish(msg.topic + '/reply', payload='ok', qos=1) self._save_alarms() else: client.publish(msg.topic + '/reply', payload='Alarm not exist!', qos=1) elif command == 'disable': alarm_time = payload alarm = self._find_alarm(alarm_time) if alarm is not None: alarm.disable() client.publish(msg.topic + '/reply', payload='ok', qos=1) self._save_alarms() else: client.publish(msg.topic + '/reply', payload='Alarm not exist!', qos=1) elif command == 'list_alarm': alarm_list = self._get_alarm_list() print('list:', '{}:{}'.format(payload, ','.join(alarm_list))) client.publish(msg.topic + '/reply', payload='{}:{}'.format(payload, ','.join(alarm_list)), qos=1, retain=True) elif command == 'alarm_at_once': self._play_alarm() def _play_alarm(self): #self._stop_alarm() self._holder.pause_music_players(self) mp3_list = self._get_alarm_mp3_list() mp3_file = random.choice(mp3_list) print('Playing: {}'.format(mp3_file)) self._player.play(mp3_file) # 好像这个音量被 music_worker 干扰了 # 设置不起作用,get_volume 返回 -1! #self._player.set_volume(100) #print('Alarm volume:', self._player.get_volume()) self._alarm_is_playing = True def _stop_alarm(self): self._player.stop() def _get_alarm_list(self): return sorted(['{}{}'.format(alarm.alarm_time, '' if alarm.enabled else ' 已停用') for alarm in self._alarms]) def _find_alarm(self, alarm_time): for alarm in self._alarms: if alarm.alarm_time == alarm_time: return alarm return None def _save_alarms(self): with open(ALARM_SAVE_FILE, 'wb') as f: pickle.dump(self._alarms, f) def _load_alarms(self): self._alarms = [] if os.path.isfile(ALARM_SAVE_FILE): try: with open(ALARM_SAVE_FILE, 'rb')as f: self._alarms = pickle.load(f) except: self._alarms = [] def update(self): super().update() current_time_str = datetime.now().strftime('%H:%M') for alarm in self._alarms: if alarm.enabled: if alarm.alarm_time != self._old_time_str and alarm.alarm_time == current_time_str: self._play_alarm() break self._old_time_str = current_time_str if self._alarm_is_playing: if not self._player.is_playing(): self._alarm_is_playing = False self._holder.resume_music_players(self) def _get_alarm_mp3_list(self): mp3_list = glob.glob('{}/*.mp3'.format(self._config.alarm_mp3_folder)) return mp3_list def pause(self): self._player.pause() def resume(self): self._player.resume()
class MusicWorker(Worker): def __init__(self, holder): super().__init__(holder) random.seed() self._config = Config() self._player = MusicPlayer() self._load_config() def on_connect(self, client, userdata, flags): super().on_connect(client, userdata, flags) client.subscribe(MUSIC_TOPIC_SUBSCRIBE) def on_message(self, client, userdata, msg): super().on_message(client, userdata, msg) payload = msg.payload.decode('UTF-8') if msg.topic.startswith(MUSIC_TOPIC_ROOT): command = msg.topic.rsplit("/", 1)[-1] if command == 'play': mp3_file = payload result = self._play_music(mp3_file) client.publish(msg.topic + '/reply', payload=result, qos=1) elif command == 'stop': self._stop_music() elif command == 'play_random_one': self._play_random_one() elif command == 'list_music': mp3_list = self._get_mp3_list() file_list = [mp3.rsplit('/', 1)[-1] for mp3 in mp3_list] client.publish(msg.topic + '/reply', payload='{}:{}'.format(payload, ','.join(file_list)), qos=1, retain=True) elif command == 'get_volume': volume = self._get_volume() client.publish(msg.topic + '/reply', payload='{}'.format(volume), qos=1, retain=True) elif command == 'set_volume': result = self._set_volume(payload) client.publish(msg.topic + '/reply', payload=result, qos=1) if result == 'ok': client.publish(MUSIC_TOPIC_ROOT + 'get_volume/reply', payload='{}'.format(payload), qos=1, retain=True) def _play_music(self, mp3_file=None, remote_command=True): self._stop_music() result = 'ok' if mp3_file is None or len(mp3_file) == 0: self._player.play(SAFE_MP3) result = 'ok' elif remote_command: if mp3_file.find('..') != -1 or mp3_file.find( '/') != -1 or mp3_file.find('\\') != -1: # bad guy self._player.play(SAFE_MP3) result = 'File not exist!' else: full_path = '{}/{}'.format(self._config.mp3_folder, mp3_file) if os.path.isfile(full_path): self._player.play(full_path) result = 'ok' else: self._player.play(SAFE_MP3) result = 'File not exist!' else: self._player.play(mp3_file) result = 'ok' return result def _stop_music(self): self._player.stop() def _get_mp3_list(self): mp3_list = glob.glob('{}/*.[mM][pP]3'.format(self._config.mp3_folder)) return mp3_list def _play_random_one(self): mp3_list = self._get_mp3_list() mp3_file = random.choice(mp3_list) print('Playing: {}'.format(mp3_file)) self._play_music(mp3_file, remote_command=False) def _get_volume(self): return self._player.get_volume() def _set_volume(self, volume): v = -1 try: v = int(volume) except: pass if v >= 0 and v <= 100: self._player.set_volume(v) self._music_config.volume = v self._save_config() return 'ok' else: return 'volume is valid!' def _save_config(self): with open(MUSIC_SAVE_FILE, 'wb') as f: pickle.dump(self._music_config, f) def _load_config(self): self._music_config = None if os.path.isfile(MUSIC_SAVE_FILE): try: with open(MUSIC_SAVE_FILE, 'rb') as f: self._music_config = pickle.load(f) except: pass if self._music_config is None: self._music_config = MusicConfig() print('Volume:', self._music_config.volume) self._player.set_volume(self._music_config.volume) def pause(self): self._player.pause() # 为了解决 alarm 设置不了音量的问题 # 也不彻底,先这样了! self._player.set_volume(100) def resume(self): self._player.resume() # 为了解决 alarm 设置不了音量的问题 # 也不彻底,先这样了! self._player.set_volume(self._music_config.volume)