def update(self, events, world): context = world.find_component("context") settings = world.find_component("settings") context["paused"] = True exiting = False for event in events: if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE: context["paused"] = False return SceneManager.pop() elif event.type == PAUSE_CONTINUE: context["paused"] = False return SceneManager.pop() elif event.type == PAUSE_SAVE_AND_QUIT: self._save(settings["save_file"], world) context["paused"] = False exiting = True elif event.type == PAUSE_QUIT_TO_MENU: context["paused"] = False exiting = True if exiting: world.inject_event({ "type": "sound", "action": "stop", "sound": "background_music", }) return SceneManager.new_root(scenes.title.TitleScene()) world.process_all_systems(events)
def update(self, events, world): for event in events: if event.type == NEW_GAME: return SceneManager.new_root(GameScene()) if event.type == CONTINUE: # we have no data to save right now, so just start a fresh game if we have a save file settings = world.find_component("settings") if path.exists( path.join(user_data_dir(APP_NAME, APP_AUTHOR), settings["save_file"])): with open( path.join(user_data_dir(APP_NAME, APP_AUTHOR), settings["save_file"]), "r", ) as f: loaded_json = json.load(f) player_entity = world.find_entity("player") player_entity.player.currency = loaded_json["currency"] player_entity.player.hasCloudSleeves = loaded_json[ "hasCloudSleeves"] player_entity.player.hasWings = loaded_json["hasWings"] player_entity.player.hasJetBoots = loaded_json[ "hasJetBoots"] self.teardown(world) return SceneManager.push(EquipScene()) if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: return SceneManager.pop() world.process_all_systems(events)
def update(self, events, world): settings = world.find_component("settings") for event in events: if event.type == EQUIP_QUIT: return SceneManager.new_root(scenes.title.TitleScene()) if event.type == EQUIP_BUY_CLOUD_SLEEVES: self._shop(settings["cloudSleevesCost"], "cloud_sleeves", world) self.teardown(world) self.setup(world) if event.type == EQUIP_BUY_WINGS: self._shop(settings["wingsCost"], "wings", world) self.teardown(world) self.setup(world) if event.type == EQUIP_BUY_JET_BOOTS: self._shop(settings["jetBootsCost"], "jet_boots", world) self.teardown(world) self.setup(world) if event.type == EQUIP_SAVE_AND_START: self._save(settings["save_file"], world) self.teardown(world) post(Event(LOAD)) return SceneManager.pop() world.process_all_systems(events)
def update(self, events, world): context = world.find_component("context") settings = world.find_component("settings") context["paused"] = True exiting = False for event in events: if event.type == PAUSE_QUIT_TO_MENU: context["paused"] = False exiting = True elif event.type == PAUSE_SAVE_AND_QUIT: self._save(settings["save_file"], world) context["paused"] = False world.inject_event({ "type": "sound", "action": "stop", "sound": "background_music", }) self.teardown(world) return SceneManager.replace(scenes.equip.EquipScene()) if exiting: world.inject_event({ "type": "sound", "action": "stop", "sound": "background_music", }) return SceneManager.new_root(scenes.title.TitleScene()) world.process_all_systems(events)
def update(self, events, world): settings = world.find_component("settings") for event in events: if event.type == EQUIP_QUIT: world.inject_event({ "type": "sound", "action": "stop", "sound": "shop_music", }) return SceneManager.new_root(scenes.title.TitleScene()) if event.type == EQUIP_BUY_CLOUD_SLEEVES: self._shop(settings["cloudSleevesCost"], "cloud_sleeves", world) self.teardown(world) self.setup(world) if event.type == EQUIP_BUY_WINGS: self._shop(settings["wingsCost"], "wings", world) self.teardown(world) self.setup(world) if event.type == EQUIP_BUY_JET_BOOTS: self._shop(settings["jetBootsCost"], "jet_boots", world) self.teardown(world) self.setup(world) if event.type == EQUIP_BUY_MORE_FUEL: self._shop(self.extra_fuel_cost, "extra_fuel", world) self.teardown(world) self.setup(world) if event.type == EQUIP_SAVE_AND_START: world.inject_event({ "type": "sound", "action": "stop", "sound": "shop_music", }) self._save(settings["save_file"], world) self.teardown(world) post(Event(LOAD)) return SceneManager.pop() world.process_all_systems(events) # start music world.inject_event({ "type": "sound", "action": "start", "sound": "shop_music", })
def main(): # Initialize pygame before we do anything else pygame.init() programIcon = pygame.image.load( find_data_file("resources/icarus_icon.png")) pygame.display.set_icon(programIcon) # Initialize global systems in the game world if pygame.mixer.get_init() is not None: WORLD.register_system(AudioSystem()) WORLD.register_system(ButtonSystem()) # Load game metadata and store it in an entity settings = Component.load_from_json("settings") WORLD.gen_entity().attach(settings) # Set up the pygame window flags = pygame.SCALED screen = pygame.display.set_mode((settings["height"], settings["width"]), flags=flags, vsync=1) pygame.display.set_caption(settings["title"]) # Store our dynamic resources that are created at runtime in the game world background = pygame.Surface(screen.get_size()) background = background.convert() background.fill((200, 200, 200)) context = ContextComponent(screen, pygame.time.Clock(), background) game = WORLD.gen_entity() game.attach(context) # Create a new Title screen object title_screen = TitleScene() # Initialize a SceneManager with our title screen manager = SceneManager(title_screen, WORLD) # BIG GAME LOOP while game["context"]["running"]: game["context"]["clock"].tick(60) # Process game wide events, most likely only QUIT events = pygame.event.get() for event in events: if event.type == pygame.QUIT: game["context"]["running"] = False # Update the current scene switch_event = manager.update(events, WORLD) # Render the current scene manager.render(WORLD) pygame.display.flip( ) # Double buffers whatever was on the screen object to the actual display # Finally switch scenes in the scene manager manager.switch(switch_event, WORLD)
def __init__(self, title="No-title Game Window", screen_size=(800, 600)): pygame.init() self.__screensurf = pygame.display.set_mode(screen_size) pygame.display.set_caption(title) self.SCREENWIDTH = screen_size[0] self.SCREENHEIGHT = screen_size[1] self.__scenedude = SceneManager() self.signalSceneDict = {} self.clock = pygame.time.Clock() self.FPS = 60
def update(self, events, world): # Run all the systems registered in the world world.process_all_systems(events) # If a key press is detected, push the next scene for event in events: if event.type == SCENE_REFOCUS: self._transition_back_to(events, world) if event.type == pygame.KEYDOWN or event.type == pygame.MOUSEBUTTONDOWN: self._transition_away_from(events, world) return SceneManager.push(MenuScene())
def update(self, events, world): for event in events: if event.type == BACK: return SceneManager.pop() if event.type == pygame.MOUSEBUTTONDOWN: if event.button == 4 and self.scroll_offset < 0: self.scroll_offset += 5 if event.button == 5 and self.scroll_offset > -180: self.scroll_offset -= 5 world.process_all_systems(events)
def update(self, events, world): for event in events: if event.type == SCENE_REFOCUS: self._transition_back_to(events, world) if event.type == NEW_GAME: self.teardown(world) return SceneManager.new_root(GameScene()) if event.type == CONTINUE: self.teardown(world) post(Event(LOAD)) return SceneManager.new_root(GameScene()) if event.type == CONTROLS: self._transition_away_from(events, world) return SceneManager.push(ControlsScene()) if event.type == CREDITS: self._transition_away_from(events, world) return SceneManager.push(CreditsScene()) if event.type == pygame.KEYDOWN and event.key == pygame.K_ESCAPE: return SceneManager.pop() world.process_all_systems(events)
def update(self, events, world): world.process_all_systems(events) for event in events: if event.type == PAUSE_QUIT_TO_MENU: world.inject_event({ "type": "sound", "action": "stop", "sound": "background_music", }) return SceneManager.new_root(scenes.title.TitleScene())
def update(self, events, world): # Start music loop world.inject_event({ "type": "sound", "action": "start", "sound": "title_music", }) # Run all the systems registered in the world world.process_all_systems(events) # If a key press is detected, push the next scene for event in events: if event.type == SCENE_REFOCUS: self._transition_back_to(events, world) if event.type == pygame.KEYDOWN or event.type == pygame.MOUSEBUTTONDOWN: self._transition_away_from(events, world) return SceneManager.push(MenuScene())
def run(self): self.init() sm = SceneManager() sm.register_scene(DevicesWaiting(self.display, self.ee)) # sm.go(SceneId.DEVICES_WAITING) sm.register_scene(Dummy(self.display)) # sm.go(SceneId.DUMMY) sm.register_scene(Loading(self.display)) sm.go(SceneId.LOADING) while (True): if Config.ENABLE_CLI: input_str = self.cli.read() if input_str == 'exit': sm.destroy() break self.handle_cli_command(input_str) time.sleep(0.01)
def update(self, events, world): # There will only ever be one player entity, unless scope drastically changes player_entity = world.filter("player")[0] # No physics until the player has jumped if player_entity.player.has_jumped: # First, clear out per-frame physics values world.inject_event({"type": "physics_frame_reset"}) # TODO: Simulate gravity as a force, instead of just doing it in the movement system # world.inject_event({"type": "physics_force", "magnitude": 0, "angle": 90}) # Then gliding, which translates rotation into acceleration world.inject_event({"type": "glide"}) # Finally, we add movement after any events that could affect acceleration world.inject_event({"type": "move"}) world.process_all_systems(events) keys = pygame.key.get_pressed() # Before doing anything else, the player must jump off the cliff if not player_entity.player.has_jumped: if keys[pygame.K_SPACE]: # Tell everyone we've jumped player_entity.player.has_jumped = True # The jump itself world.inject_event({ "type": "physics_force", "magnitude": 5, "angle": -20 }) # Start background music world.inject_event({ "type": "sound", "action": "start", "sound": "background_music", }) # We don't want to rotate before jumping. # TODO: or do we? else: # The player only has direct control over their angle from the ground. # Our rudimentary physics takes care of the rest. # Also, clamp the angle from straight up to straight down. if keys[pygame.K_RIGHT]: angle = player_entity.rotation.angle + 1 player_entity.rotation.angle = min(angle, 90) if keys[pygame.K_LEFT]: angle = player_entity.rotation.angle - 1 player_entity.rotation.angle = max(angle, -90) for event in events: # Use keyup here as a simple way to only trigger once and not repeatedly if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE: return SceneManager.push(PauseScene())
def update(self, events, world): for event in events: if event.type == BACK: return SceneManager.pop() world.process_all_systems(events)
def setUp(self): self.scenedude = SceneManager() class SubScene(Scene): def __init__(self): super().__init__('Scene subclass') self.ss = SubScene()
class TestSceneManager(unittest.TestCase): def setUp(self): self.scenedude = SceneManager() class SubScene(Scene): def __init__(self): super().__init__('Scene subclass') self.ss = SubScene() def test_add(self): # test that the scene being added subclasses Scene with self.assertRaises(TypeError): self.scenedude['123'] = Scene('blanko') # test string-<incompatible_type> pair adding with self.assertRaises(TypeError): self.scenedude['123'] = 123 # test <incompatible_type>-Scene pair adding with self.assertRaises(TypeError): self.scenedude[123] = self.ss # test screendude's current screen. This should be set when its # __currentscreen attribute is written by adding a new screen. self.scenedude['blank'] = self.ss self.assertEqual(self.scenedude.current, self.ss) def test_get(self): blankScene = self.ss self.scenedude['blank'] = blankScene self.assertEqual(self.scenedude['blank'], blankScene) # test incompatible key type retrieving a Scene item with self.assertRaises(TypeError): self.scenedude[123456] def test_currentStatus(self): blankScene = self.ss self.scenedude['blank'] = blankScene with self.assertRaises(NotImplementedError): print(self.scenedude.current.status) def test_change_scene(self): scene1 = self.ss scene2 = copy(self.ss) self.scenedude['scene1'] = scene1 self.scenedude['scene2'] = scene2 self.assertEqual(self.scenedude.current, scene1) # change the scene current_scene = self.scenedude.change_scene('scene2') self.assertEqual(current_scene, scene2) # Try changing to an invalid/non-existant scene with self.assertRaises(KeyError): self.scenedude.change_scene('invalid-scene') self.scenedude.change_scene(None) def test_num_scenes(self): self.scenedude['d'] = self.ss self.scenedude['e'] = self.ss self.scenedude['f'] = self.ss self.scenedude['g'] = self.ss self.assertEqual(self.scenedude.count, 4)
def update(self, events, world): for event in events: if event.type == SCENE_REFOCUS: self.teardown(world) self.setup(world) # Loading MUST happen after refocusing for event in events: if event.type == LOAD: load(world) context = world.find_component("context") screen = context["screen"] # There will only ever be one player entity, unless scope drastically changes player_entity = world.filter("player")[0] # No physics until the player has jumped if player_entity.player.has_jumped: # First, clear out per-frame physics values world.inject_event({"type": "physics_frame_reset"}) # TODO: Simulate gravity as a force, instead of just doing it in the movement system # world.inject_event({"type": "physics_force", "magnitude": 0, "angle": 90}) # Then gliding, which translates rotation into acceleration world.inject_event({"type": "glide"}) # Finally, we add movement after any events that could affect acceleration world.inject_event({"type": "move"}) if calculate_altitude(player_entity, screen) > 0: for sys in self.systems: world.unregister_system(sys) return SceneManager.push(CrashResultsScene()) world.process_all_systems(events) keys = pygame.key.get_pressed() mods = pygame.key.get_mods() # TODO: this is just for debug purposes if keys[pygame.K_c]: player_entity.player.currency = 100000 # Before doing anything else, the player must jump off the cliff if not player_entity.player.has_jumped: if keys[pygame.K_SPACE]: # Tell everyone we've jumped player_entity.player.has_jumped = True # The jump itself world.inject_event( {"type": "physics_force", "magnitude": 10, "angle": -20} ) # Start background music world.inject_event( { "type": "sound", "action": "start", "sound": "background_music", } ) # We don't want to rotate before jumping. TODO: or do we? else: rotation_speed = 1 if player_entity.player.hasWings and not mods & pygame.KMOD_SHIFT: rotation_speed = 3 # The player only has direct control over their angle from the ground. # Our rudimentary physics takes care of the rest. # Also, clamp the angle from straight up to straight down. if keys[pygame.K_RIGHT]: angle = player_entity.rotation.angle + rotation_speed player_entity.rotation.angle = min(angle, 90) if keys[pygame.K_LEFT]: angle = player_entity.rotation.angle - rotation_speed player_entity.rotation.angle = max(angle, -90) for event in events: if ( event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE and player_entity.player.has_jumped and player_entity.player.hasJetBoots and player_entity.player.numBoosts > 0 ): player_entity.player.numBoosts -= 1 world.inject_event( { "type": "physics_force", "magnitude": 50, "angle": player_entity.rotation.angle, } ) for event in events: # Use keyup here as a simple way to only trigger once and not repeatedly if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE: return SceneManager.push(PauseScene())
import pygame import sys from scene import SceneManager pygame.init() pygame.mixer.init(frequency=44100, channels=1) size = width, height = 640, 480 bg_color = 245, 245, 245 pygame.display.set_caption('You\'re a fly') screen = pygame.display.set_mode(size) prev_time = pygame.time.get_ticks() manager = SceneManager() manager.set_scene('menu') while 1: curr_time = pygame.time.get_ticks() delta = curr_time - prev_time prev_time = curr_time for event in pygame.event.get(): if event.type == pygame.QUIT: sys.exit() else: manager.event(event) manager.update(delta)
def update(self, events, world): for event in events: if event.type == VICTORY: return SceneManager.replace(VictoryScene()) if event.type == SCENE_REFOCUS: self.teardown(world) self.setup(world) # Loading should happen only AFTER refocusing, if both events have fired this frame for event in events: if event.type == LOAD: load(world) context = world.find_component("context") screen = context["screen"] # There will only ever be one player entity, unless scope drastically changes player_entity = world.filter("player")[0] # No physics until the player has jumped if player_entity.player.has_jumped: # First, clear out per-frame physics values world.inject_event({"type": "physics_frame_reset"}) # TODO: Simulate gravity as a force, instead of just doing it in the movement system # world.inject_event({"type": "physics_force", "magnitude": 0, "angle": 90}) # Then gliding, which translates rotation into acceleration world.inject_event({"type": "glide"}) # Finally, we add movement after any events that could affect acceleration world.inject_event({"type": "move"}) if calculate_altitude(player_entity, screen) > 0: # allow the deafening silence to emphasize the player's deadly mistake world.inject_event( { "type": "sound", "action": "stop", "sound": "background_music", } ) # also make a funny sound effect world.inject_event( { "type": "sound", "action": "play", "sound": "crash", } ) for sys in self.systems: world.unregister_system(sys) return SceneManager.push(CrashResultsScene()) world.process_all_systems(events) keys = pygame.key.get_pressed() mods = pygame.key.get_mods() # # Win button for debugging # if keys[pygame.K_v]: # pygame.event.post(pygame.event.Event(VICTORY)) # Before doing anything else, the player must jump off the cliff if not player_entity.player.has_jumped: if keys[pygame.K_SPACE] and not player_entity.player.jumping: # Tell everyone we've jumped player_entity.player.has_jumped = True player_entity.player.jumping = True # The jump itself world.inject_event( {"type": "physics_force", "magnitude": 20, "angle": -20} ) # Start background music world.inject_event( { "type": "sound", "action": "start", "sound": "background_music", } ) # We don't want to rotate before jumping. TODO: or do we? else: if player_entity.player.jumping: player_entity.rotation.angle += 0.5 if player_entity.rotation.angle > 0: player_entity.player.jumping = False rotation_speed = 1 # If you have the wings upgrade, you can use shift to go back to slower rotation if player_entity.player.hasWings and not mods & pygame.KMOD_SHIFT: rotation_speed = 2 # The player only has direct control over their angle from the ground. # Our rudimentary physics takes care of the rest. # Also, clamp the angle from straight up to straight down. if keys[pygame.K_RIGHT]: player_entity.player.jumping = False angle = player_entity.rotation.angle + rotation_speed player_entity.rotation.angle = min(angle, 90) if keys[pygame.K_LEFT]: player_entity.player.jumping = False angle = player_entity.rotation.angle - rotation_speed player_entity.rotation.angle = max(angle, -90) for event in events: if ( event.type == pygame.KEYDOWN and event.key == pygame.K_SPACE and player_entity.player.has_jumped and player_entity.player.hasJetBoots and player_entity.player.numBoosts > 0 ): player_entity.player.jumping = False player_entity.player.numBoosts -= 1 world.inject_event( { "type": "physics_force", "magnitude": 15, "angle": player_entity.rotation.angle, } ) for event in events: # Use keyup here as a simple way to only trigger once and not repeatedly if event.type == pygame.KEYUP and event.key == pygame.K_ESCAPE: return SceneManager.push(PauseScene())