def delete_instance(self, db_instance_id, timeout=60 * 15): inst = self.get_instance(instance_id=db_instance_id, tags=False) if inst is None: return True if inst["DBInstanceStatus"] == "deleting": while True: with Timer(timeout_seconds=timeout) as t: if t.timeout: return False inst = self.get_instance(instance_id=db_instance_id, tags=False) if inst is None: return True time.sleep(15) self.rds_client.delete_db_instance(DBInstanceIdentifier=db_instance_id, SkipFinalSnapshot=True) while True: with Timer(timeout_seconds=timeout) as t: if t.timeout: return False instance = self.get_instance(instance_id=db_instance_id, tags=False) if instance is None: return time.sleep(15)
def check_unreal( ltl_text, part_text, is_moore, ltl3ba: LTL3BA, solver_factory: Z3SolverFactory, min_size, max_size, ltl3ba_timeout_sec=None, opt_level=0, ) -> LTS: """ :raise: subprocess.TimeoutException :arg opt_level: Note that opt_level > 0 may introduce unsoundness (returns unrealizable while it is) """ timer = Timer() outputs, inputs, expr = parse_acacia_and_build_expr(ltl_text, part_text, ltl3ba, opt_level) timer.sec_restart() automaton = ltl3ba.convert(expr, timeout=ltl3ba_timeout_sec) # note no negation logging.info("(unreal) automaton size is: %i" % len(automaton.nodes)) logging.debug("(unreal) automaton (dot) is:\n" + automaton2dot.to_dot(automaton)) logging.debug("(unreal) automaton translation took (sec): %i" % timer.sec_restart()) encoder = create_encoder(inputs, outputs, not is_moore, automaton, solver_factory.create()) model = model_searcher.search(min_size, max_size, encoder) logging.debug("(unreal) model_searcher.search took (sec): %i" % timer.sec_restart()) return model
class TwoWayImage(pygame.sprite.Sprite): """Sprite which moves in two directions and loops; used to make background/foreground.""" def __init__(self, speed, image_dir, rearrange_coeff, image_type): super(TwoWayImage, self).__init__() self.speed = speed self.image_dir = image_dir # Total number of images; multiplied for rearrange offset self.rearrange_coeff = rearrange_coeff self.image_type = image_type if self.image_type == "foreground": self.image = cache_image.get(self.image_dir, convert_alpha=False) else: self.image = cache_image.get(self.image_dir) self.rect = self.image.get_rect() self.alpha_timer = Timer() self.alpha = 255 self.is_dying = False, if self.image_type == "foreground": self.hitmask = pygame.mask.from_surface(self.image) def rearrange(self): """Reset the sprite if it goes offscreen.""" # If screen_width isn't divisible by speed, the offset will vary: natural_offset = self.rect.x + SCREEN_WIDTH self.rect.x = (self.rearrange_coeff * SCREEN_WIDTH) + natural_offset def kill(self): """Remove foreground terrain for boss battles by fading its alpha.""" if self.alpha_timer.elapsed_time() > 60: self.alpha -= 3 self.image.set_alpha(self.alpha) self.alpha_timer.reset() def update(self): """Update image movement, rearranging or killing alpha as necessary.""" if self.alpha <= 0: all_sprites_list.remove(self) if self.image_type == "foreground": foreground_list.remove(self) if self.is_dying == True: self.kill() self.rect.x -= self.speed if self.rect.x < (0 - self.rect.width): self.rearrange()
class HeadLaserBeam(pygame.sprite.Sprite): def __init__(self, head): super(HeadLaserBeam, self).__init__() self.head = head # Bad variable name TODO self.beam_size_timer = Timer() self.beam_height = 1 self.beam_incrementer = 1 self.update_beam_image(self.beam_height) self.rect.centery = self.head.rect.centery + 10 def update_beam_height(self): """Pulse height, and remove from sprite lists for 1.5 seconds when height=0.""" max_beam_height = 15 beam_downtime = 1500 # Time where there is no beam, aka no damage taken by player if self.beam_height <= 0: enemy_projectile_list.remove(self) if self.beam_size_timer.elapsed_time() > beam_downtime: enemy_projectile_list.add(self) self.beam_height = 1 self.beam_incrementer = 1 elif self.beam_size_timer.elapsed_time() > 60: enemy_projectile_list.add(self) if self.beam_height >= max_beam_height: self.beam_incrementer *= -1 self.beam_height += self.beam_incrementer self.beam_size_timer.reset() def update_beam_image(self, beam_height): self.image = pygame.Surface([640, beam_height]) self.image.fill(BLUE) self.rect = self.image.get_rect() def kill(self): all_sprites_list.remove(self) enemy_projectile_list.remove(self) def update(self): self.update_beam_height() self.update_beam_image(self.beam_height) self.rect.centery = self.head.rect.centery + 10
def __init__(self, txt_img, xpos_center, ypos_center, kill_time): super(BossWarning, self).__init__() self.kill_time = kill_time self.image = cache_image.get("screen_messages/boss_warning" + "_F1.png") self.image.set_colorkey(BLACK) self.rect = self.image.get_rect() self.rect.centerx = xpos_center self.rect.centery = ypos_center self.anim_timer = Timer() self.kill_timer = Timer() self.frame_idx = 2
def delete_stack(self, timeout=900, empty_bucket_resources=False): if self.owned: if not self.is_stack_present(): return True else: if empty_bucket_resources: s3 = S3() buckets = [ r["PhysicalResourceId"] for r in self.cnf_service.describe( services.cloudformation_service.STACK_RESOURCES, StackName=self.stack_name, region=self.region) if r["ResourceType"] == "AWS::S3::Bucket" ] for bucket in buckets: s3.empty_bucket(bucket) with Timer(timeout_seconds=timeout, start=True) as timer: self.cfn_client.delete_stack(StackName=self.stack_name) while self.is_stack_present() is True: if timer.timeout: raise Exception("Timeout deleting stack {}".format( self.stack_name)) time.sleep(20) return True
def cron_thread(): Log("Cron thread started!") time = Timer() while True: Log("Running cron!") time.start() cron_cursor = mydb.cursor() #create cursor specifically for cron jobs cache_user_ids(cron_cursor) cache_ranks(cron_cursor) calculate_cp(cron_cursor) max_star_count_ban(cron_cursor) cache_comment_bans(cron_cursor) cache_server_stats(cron_cursor) cron_cursor.close() #close it after all is done Log(f"Cron done! Took {round(time.end(),2)}s") pytime.sleep(UserConfig["CronThreadDelay"])
def __init__(self, surface, alpha_incrementer): super(FadeIn, self).__init__() self.surface = surface # Alpha value for transparency: self.alpha = 0 # Incrementer will change the 'direction' of the fade: self.alpha_incrementer = alpha_incrementer # Inc_delay = frames that pass before next alpha update: self.alpha_inc_delay = 60 # 60 = One frame # Flag for completion: self.is_complete = False self.image = pygame.Surface([800, 600]) self.rect = self.image.get_rect() self.rect.centerx = SCREEN_WIDTH / 2 self.rect.centery = SCREEN_HEIGHT / 2 self.image.fill((0, 0, 0)) self.image.set_alpha(0) self.fade_timer = Timer() self.initial_time = pygame.time.get_ticks()
def run(): with Timer('Merging Comment and Post Data from Subreddits'): data_dir = '/home/hadoop/reddit_topic_model/app_module/data/' with open(data_dir + 'stashinvest/reddit_submissions.parquet', 'rb') as submissions_file: submissions = pd.read_parquet(submissions_file, engine='pyarrow') submissions.drop( submissions[submissions['author'] == 'stashofficial'].index, axis=0, inplace=True) with open(data_dir + 'stashinvest/reddit_comments.parquet', 'rb') as comments_file: comments = pd.read_parquet(comments_file, engine='pyarrow') comments.drop(comments[comments['author'] == 'stashofficial'].index, axis=0, inplace=True) comments.drop(comments[comments['body'] == '[deleted]'].index, axis=0, inplace=True) merged = merge_parent_and_child_comments(submissions, comments) merged.to_pickle(data_dir + 'tmp/merged.pkl') print("\nSample") print(merged.head(), "\n")
def get_activation_key(): key = None with Timer(timeout_seconds=1200, start=True) as activation_key_timer: while True: # noinspection PyBroadException,PyPep8 try: # start with initial wait as it will time for the instance to initialize time.sleep(15) # get key from redirection result # see https://docs.aws.amazon.com/storagegateway/latest/userguide/get-activation-key.html conn = http.client.HTTPConnection( instance_public_address) conn.request( "GET", "?activationRegion={}".format(self.region)) resp = conn.getresponse() if resp.status == 302: if resp.getheader("Location") is not None: key = [ q[1] for q in [ h.split("=") for h in resp.getheader("Location"). split('?')[1].split('&') ] if q[0] == 'activationKey' ][0] break except: pass if activation_key_timer.timeout: break return key
def wait_for_db_connections(self, db_instance_id, timeout): with Timer(timeout_seconds=timeout, start=True) as t: while not t.timeout: c = self.get_daily_database_connections(db_instance_id, 1) if len(c) > 0 and c[0] > 0: return True time.sleep(15) return False
def wait_for_network_io(self, instance_id, timeout, io_mb): with Timer(timeout, start=True) as t: while not t.timeout: io = self.get_daily_network_io(instance_id, 1) if len(io) > 0 and io[0] >= io_mb * MEGA_BYTE: return True time.sleep(15) return False
def wait_for_cpu_load(self, instance_id, timeout, load): with Timer(timeout, start=True) as t: while not t.timeout: cpu = self.get_daily_cpu_utilization(instance_id, 1) if len(cpu) > 0 and cpu[0] >= load: return True time.sleep(15) return False
def wait_for_volume_iops(self, volume_id, timeout, min_iops): with Timer(timeout, start=True) as t: while not t.timeout: iops = self.get_daily_volume_iops(volume_id, 1) if len(iops) > 0 and iops[0] >= min_iops: return True time.sleep(15) return False
def wait_for_system_ready(self, instance_id, timeout=600): with Timer(timeout_seconds=timeout, start=True) as t: while not t.timeout: status = self.get_system_status(instance_id=instance_id) if status is not None and status == "ok": return True time.sleep(10) return False
def __init__(self, is_looped, is_seesaw=False): self.is_looped = is_looped self.is_seesaw = is_seesaw self.is_done_animating = False self.frame_idx = 0 self.timer = Timer() if self.is_seesaw: self.frame_incrementer = 1
def run(env): with Timer('Updating Table with New Partition'): spark_session = SparkSession.builder.appName( "reddit").enableHiveSupport().getOrCreate() spark_session.sparkContext.setLogLevel("WARN") spark_session.sql(f""" ALTER TABLE source_social.reddit_scores ADD IF NOT EXISTS PARTITION(process_date='{datetime.today().strftime("%Y-%m-%d")}') LOCATION "s3://stash-de-source-{env}/source_social.db/reddit_scores/process_date={datetime.today().strftime("%Y-%m-%d")}" """)
def __init__(self, dict_enemy): super(EnemyNonlinear, self).__init__(dict_enemy) self.rect.centerx = self.params["pos_x"] self.speed = self.params["speed"] self.path_type = self.params["path_type"] self.initialize_specific_params() self.path_timer = Timer()
class Bot(GameObject): """Bot Basic tier 1 unit. """ fire_rate = 3.0 fire_dist = 20 movement_speed = 60.0 def __init__(self, position): super(Bot, self).__init__('assets/circle.png', position) self._fire_timer = Timer(Bot.fire_rate) def _fire(self, position): diff_x = position[0] - self.position[0] diff_y = position[1] - self.position[1] aim = helpers.normalize((diff_x, diff_y)) l = Bot.fire_dist fire_pos = (self.position[0] + aim[0] * l, self.position[1] + aim[1] * l) return Pulse(position=fire_pos, direction=aim) def fire(self, position): if self._fire_timer.check(): self._fire_timer.reset() return self._fire(position) return [] def update(self, delta, **kwargs): self._fire_timer.update(delta) dist = Bot.movement_speed * delta self.move(dist, 0) targets = [(400, 400), (200, 200), (300, 300)] if targets: target = random.choice(targets) shot = self.fire(target) if shot: return [shot] return [] def __str__(self): return 'Bot'
def run(): raw_data = pd.read_pickle("./data/tmp/merged.pkl") with Timer("Preprocess Text"): processor = Preprocessor() prepared_df = processor.preprocess_df(df=raw_data, text_column="text") prepared_df.to_pickle("./data/tmp/preprocessed.pkl") print("\nSample") print(prepared_df.head(), "\n")
def __init__(self, is_looped=None): self.is_doing_action = False self.is_done_action = False self.is_done_subaction = False self.is_dead = False self.action_idx = 0 self.timer = Timer() self.is_looped = is_looped
def run_and_report(spec_file_name, is_moore_: bool, output_file_name, dot_file_name, tasks_creator: TaskCreator): timer = Timer() ltl_text, part_text, is_moore = convert_tlsf_or_acacia_to_acacia( spec_file_name, is_moore_) tasks = tasks_creator.create(ltl_text, part_text, is_moore) is_real, lts_or_aiger = run_synth_tasks(tasks) if is_real is None: logging.warning('Either crashed or did not succeed') print_syntcomp_unknown() exit(UNKNOWN_RC) logging.info('finished in %i sec.' % timer.sec_restart()) if not lts_or_aiger: logging.info('status unknown') print_syntcomp_unknown() exit(UNKNOWN_RC) if not is_real: if isinstance(lts_or_aiger, LTS): lts_str = lts_to_dot(lts_or_aiger, ARG_MODEL_STATE, is_moore) # we invert machine type _write_dot_result(lts_str, dot_file_name) print_syntcomp_unreal() exit(UNREALIZABLE_RC) else: if isinstance(lts_or_aiger, LTS): lts_str = lts_to_dot(lts_or_aiger, ARG_MODEL_STATE, not is_moore) logging.info('state machine size: %i' % len(lts_or_aiger.states)) _write_dot_result(lts_str, dot_file_name) lts_aiger = lts_to_aiger(lts_or_aiger) else: lts_aiger = lts_or_aiger if output_file_name: with open(output_file_name, 'w') as out: out.write(lts_aiger) print_syntcomp_real(lts_aiger) exit(REALIZABLE_RC)
def create_stack(self, template_body=None, template_file=None, iam_capability=False, timeout=600, tags=None, params=None, empty_existing_buckets=True): assert (len( [t for t in [template_body, template_file] if t is not None]) == 1) if template_file is not None: with open(template_file, "rt") as f: template = "".join(f.readlines()) else: template = template_body self.delete_stack(empty_bucket_resources=empty_existing_buckets) args = { "StackName": self.stack_name, "TemplateBody": template, "Parameters": [] if params is None else [{ "ParameterKey": p, "ParameterValue": params[p] } for p in params], "Capabilities": ["CAPABILITY_NAMED_IAM"] if iam_capability else [], "Tags": [{ "Key": t, "Value": tags[t] } for t in tags] if tags is not None else [] } try: self._stack_id = self.cfn_client.create_stack(**args)["StackId"] except Exception as ex: print(ex) with Timer(timeout_seconds=timeout, start=True) as timer: while self.is_stack_in_status("CREATE_IN_PROGRESS") is True: time.sleep(20) if timer.timeout: raise Exception("Timeout creating stack {}".format( self.stack_name)) if self.is_stack_in_status("CREATE_COMPLETE") is True: self.owned = True return else: raise ValueError("Stack did not create successfully")
def run(env:str='edge'): df = pd.read_pickle('./data/tmp/scored.pkl') with Timer("Add Sentiment Analyses"): with Timer('Append Vader Sentiment Scores'): df = get_vader_sentiment(df) # This takes approx. 2.5 hours... Not worth it at the moment # with Timer('Append Flair Sentiment Scores'): # df = get_flair_sentiment(df) df = df[[ 'id','time','Topic: 1','Topic: 2', 'Topic: 3','Topic: 4','Topic: 5','Topic: 6', 'Topic','vader_neg','vader_neu','vader_pos', 'vader_compound' ]] df.to_parquet(f's3://stash-de-source-{env}/source_social.db/reddit_scores/process_date={datetime.today().strftime("%Y-%m-%d")}/batch.parquet') print("\nSample") print(df.head(),"\n")
def __init__(self, dict_enemy): super(FallingBlock, self).__init__(dict_enemy) # NOTE: falling_block_list is only used for collision logic # FallingBlock()s are added to enemy_sprite_list and use that logic falling_block_list.add(self) self.fall_timer = Timer() self.fall_speed = 3 self.is_falling = False
def wait_for_volume_state(self, volume_id, state, timeout=300): with Timer(timeout_seconds=timeout, start=True) as t: count = 0 while not t.timeout: img = self.get_volume(volume_id) if img is not None and img.get("State") == state: count += 1 if count >= 3: return True time.sleep(5) return False
def __init__(self, head): super(HeadLaserBeam, self).__init__() self.head = head # Bad variable name TODO self.beam_size_timer = Timer() self.beam_height = 1 self.beam_incrementer = 1 self.update_beam_image(self.beam_height) self.rect.centery = self.head.rect.centery + 10
def check_real( ltl_text, part_text, is_moore, ltl3ba, solver_factory: Z3SolverFactory, min_size, max_size, opt_level=2 ) -> LTS: """ :param opt_level: values > 0 introduce incompleteness (but it is sound: if returns REAL, then REAL) """ timer = Timer() inputs, outputs, expr = parse_acacia_and_build_expr(ltl_text, part_text, ltl3ba, opt_level) timer.sec_restart() automaton = ltl3ba.convert(~expr) logging.info("(real) automaton size is: %i" % len(automaton.nodes)) logging.debug("(real) automaton (dot) is:\n" + automaton2dot.to_dot(automaton)) logging.debug("(real) automaton translation took (sec): %i" % timer.sec_restart()) encoder = create_encoder(inputs, outputs, is_moore, automaton, solver_factory.create()) model = model_searcher.search(min_size, max_size, encoder) logging.debug("(real) model_searcher.search took (sec): %i" % timer.sec_restart()) return model
def wait_for_image_available(self, image_id, timeout=300): with Timer(timeout_seconds=timeout, start=True) as t: count = 0 while not t.timeout: img = self.get_image(image_id) if img is not None and img.get("State") == "available": count += 1 if count >= 3: return True time.sleep(5) return False
def wait_for_image_not_longer_available(self, image_id, timeout=300): with Timer(timeout_seconds=timeout, start=True) as t: count = 0 while not t.timeout: img = self.get_image(image_id) if img is None: count += 1 if count >= 3: return True time.sleep(5) return False
def main(tlsf_file_name, output_file_name, dot_file_name, smt_files_prefix, keep_temp_files) -> int: """ :return: REALIZABLE, UNREALIZABLE, UNKNOWN (see elli) """ timer = Timer() logic = UFLRA() ltl3ba, solver_factory = create_spec_converter_z3(logic, True, False, smt_files_prefix, not keep_temp_files) ltl_text, part_text = convert_tlsf_to_acacia(tlsf_file_name) is_moore = get_spec_type(tlsf_file_name) try: timer.sec_restart() env_model = elli.check_unreal( ltl_text, part_text, is_moore, ltl3ba, solver_factory, 1, 1, ltl3ba_timeout_sec=200 ) logging.info("unreal check took (sec): %i" % timer.sec_restart()) logging.info("env model is {NOT} FOUND".format(NOT="" if env_model else "NOT")) if env_model: print("UNREALIZABLE") logging.debug(lts_to_dot(env_model, ARG_MODEL_STATE, is_moore)) return UNREALIZABLE except subprocess.TimeoutExpired: logging.info("I aborted unreal check (>200sec). Proceed to real check.") model = elli.check_real(ltl_text, part_text, is_moore, ltl3ba, solver_factory, 1, 40) logging.info("real check took (sec): %i" % timer.sec_restart()) logging.info("sys model is {NOT} FOUND".format(NOT="" if model else "NOT")) if not model: logging.info("trying check_real without formula strengthening") model = elli.check_real(ltl_text, part_text, is_moore, ltl3ba, solver_factory, 1, 40, opt_level=0) logging.info("(without formula strengthening): real check took (sec): %i" % timer.sec_restart()) logging.info("(without formula strengthening): sys model is {NOT} FOUND".format(NOT="" if model else "NOT")) if not model: return UNKNOWN dot_model_str = lts_to_dot(model, ARG_MODEL_STATE, not is_moore) if dot_file_name: with open(dot_file_name, "w") as out: out.write(dot_model_str) logging.info( "{model_type} model is written to {file}".format(model_type=["Mealy", "Moore"][is_moore], file=out.name) ) else: logging.info(dot_model_str) aiger_model_str = lts_to_aiger(model) logging.info("circuit size: %i" % len(model.states)) if output_file_name: with open(output_file_name, "w") as out: out.write(aiger_model_str) else: print("REALIZABLE") print(aiger_model_str) solver_factory.down_solvers() return REALIZABLE
class FadeOut(pygame.sprite.Sprite): def __init__(self, surface): super(FadeOut, self).__init__() self.surface = surface # Alpha value for transparency: self.alpha = 255 # Incrementer will change the 'direction' and speed of the fade: self.alpha_incrementer = -25 # Inc_delay = frames that pass before next alpha update: self.alpha_inc_delay = 60 # Flag for completion: self.is_complete = False self.image = pygame.Surface((800, 600)) self.rect = self.image.get_rect() self.image.fill((0, 0, 0)) self.image.set_alpha(255) self.fade_timer = Timer() def update(self): self.image.set_alpha(self.alpha) self.surface.blit(self.image, (0, 0)) if not self.is_complete: if self.alpha < 0: self.alpha = 0 self.is_complete = True if self.fade_timer.elapsed_time() > self.alpha_inc_delay: self.alpha += self.alpha_incrementer self.fade_timer.reset()
def __init__(self, txt_img, xpos_center, ypos_center, kill_time): super(TextToScreen, self).__init__() self.kill_time = kill_time self.txt_img = txt_img self.image = cache_image.get(txt_img + "_F1.png") self.rect = self.image.get_rect() self.image.set_colorkey(BLACK) self.rect.centerx = xpos_center self.rect.centery = ypos_center self.kill_timer = Timer()
def run(): # Get the Preprocessed Dataset df = pd.read_pickle('./data/tmp/preprocessed.pkl') if os.path.isfile('./models/MALLET/mallet_model.pkl'): # Let's not do any model retraining without building in topic stability constraints # e.g. number of docs or tokens now in different topics seen = False # Data we provide is new and unseen for the model with open('./models/MALLET/mallet_model.pkl', 'rb') as modelfile: topic_model = pickle.load(modelfile) with open('./models/MALLET/mallet_dict.pkl', 'rb') as dictfile: dictionary = pickle.load(dictfile) df['bow'] = df['tokens'].apply(dictionary.doc2bow) else: seen = True # any data we provide is used to train the model with Timer('Train the LDA Model'): test_range = (5, 50) df, corpus, dictionary = get_corpus_and_dict(df, 'tokens') list_of_models, scores = topic_count_selection( dictionary, corpus, list(df['tokens']), test_range) plot_coherence( test_range, scores).savefig('./models/MALLET/ModelCoherence.png') # Let's save the model with highest coherence num_topics = test_range[0] + scores.index(max(scores)) + 1 topic_model = LdaMallet('/home/hadoop/Mallet-master/bin/mallet', corpus=corpus, num_topics=num_topics, id2word=dictionary, iterations=1000, prefix=f'{os.getcwd()}/models/MALLET/', random_seed=42) print(f"* Chosen Model with {num_topics} topics") with open('./models/MALLET/mallet_model.pkl', 'wb') as modelfile: topic_model.save(modelfile) with open('./models/MALLET/mallet_corpus.pkl', 'wb') as corpusfile: pickle.dump(corpus, corpusfile) with open('./models/MALLET/mallet_dict.pkl', 'wb') as dictfile: pickle.dump(dictionary, dictfile) df = get_topic_model_scores(df, topic_model, seen=seen) df.to_pickle('./data/tmp/scored.pkl') print("\nSample") print(df.head(), "\n")
def copy_image(self, image_id, destination_region, name, tags=None, description=None, wait_to_complete=300, encrypted=False): ec2_destination = Ec2(region=destination_region) ec2_destination_client = boto3.client("ec2", region_name=destination_region) args = { "SourceImageId": image_id, "SourceRegion": self.region, "Name": name, "Encrypted": encrypted } if description is not None: args["Description"] = description with Timer(timeout_seconds=wait_to_complete) as timer: # noinspection PyBroadException try: image_copy_id = ec2_destination_client.copy_image( **args)["ImageId"] except Exception: return None image_copy = ec2_destination.get_image(image_copy_id) if wait_to_complete == 0: if image_copy is not None: ec2_destination.create_tags( resource_ids=[image_copy["ImageId"]], tags=tags) return image_copy while True: if image_copy is not None and image_copy[ "State"] == "available": ec2_destination.create_tags( resource_ids=[image_copy["ImageId"]], tags=tags) return image_copy if timer.timeout: return None time.sleep(20) image_copy = ec2_destination.get_image(image_copy_id) if image_copy is not None and image_copy["State"] == "failed": return None
def wait_until_cluster_status(self, db_cluster_id, status, timeout): if not isinstance(status, list): status = [status] while True: with Timer(timeout_seconds=timeout) as t: if t.timeout: return False time.sleep(15) current_status = self.get_cluster(cluster_id=db_cluster_id, tags=False).get("Status") if current_status in status: return True
def create_image(self, instance_id, name, tags=None, description=None, no_reboot=True, wait_to_complete=600): args = {"InstanceId": instance_id, "Name": name, "NoReboot": no_reboot} if description is not None: args["Description"] = description with Timer(timeout_seconds=wait_to_complete) as timer: # noinspection PyBroadException try: image_id = self.ec2_client.create_image(**args)["ImageId"] image = self.get_image(image_id) if wait_to_complete == 0: self.create_tags([image_id], tags=tags) return self.get_image(image_id) while True: if image["State"] == "available": self.create_tags([image_id], tags=tags) # there may be a tile lag between the image created and becoming visible in a new sessions. while True: img = Ec2(self.region, session=boto3.Session()).get_image( image["ImageId"]) if img is not None: return img if timer.timeout: raise Exception( "Image created but not returned by describe function" ) time.sleep(10) if timer.timeout: return None time.sleep(20) image = self.get_image(image_id) if image["State"] == "failed": return None except Exception as ex: print(ex) return None
class BossWarning(pygame.sprite.Sprite): """Flash a 'WARNING!' message in the center of the SCREEN.""" def __init__(self, txt_img, xpos_center, ypos_center, kill_time): super(BossWarning, self).__init__() self.kill_time = kill_time self.image = cache_image.get("screen_messages/boss_warning" + "_F1.png") self.image.set_colorkey(BLACK) self.rect = self.image.get_rect() self.rect.centerx = xpos_center self.rect.centery = ypos_center self.anim_timer = Timer() self.kill_timer = Timer() self.frame_idx = 2 def update(self): """Flash the sign by switching images and destroy it after a set time.""" if self.kill_timer.elapsed_time() > self.kill_time: self.kill() try: flash_time = 360 if self.anim_timer.elapsed_time() > flash_time: self.anim_timer.reset() self.image = cache_image.get("screen_messages/boss_warning_F{}.png" .format(self.frame_idx)) self.image.set_colorkey(BLACK) self.frame_idx += 1 except pygame.error: self.frame_idx = 1 def kill(self): all_sprites_list.remove(self)
def delete_cluster(self, db_cluster_id, timeout=60 * 15): cluster = self.get_cluster(cluster_id=db_cluster_id, tags=False) if cluster is None: return True if cluster["Status"] == "deleting": while True: with Timer(timeout_seconds=timeout) as t: if t.timeout: return False cluster = self.get_instance(instance_id=db_cluster_id, tags=False) if cluster is None: return True time.sleep(15) self.start_cluster(db_cluster_id=db_cluster_id, timeout=timeout) for member_id in [ m["DBInstanceIdentifier"] for m in cluster.get("DBClusterMembers", []) ]: self.delete_instance(member_id) self.rds_client.delete_db_cluster(DBClusterIdentifier=db_cluster_id, SkipFinalSnapshot=True) while True: with Timer(timeout_seconds=timeout) as t: if t.timeout: return False instance = self.get_cluster(cluster_id=db_cluster_id, tags=False) if instance is None: return True time.sleep(15)
class FadeIn(pygame.sprite.Sprite): def __init__(self, surface, alpha_incrementer): super(FadeIn, self).__init__() self.surface = surface # Alpha value for transparency: self.alpha = 0 # Incrementer will change the 'direction' of the fade: self.alpha_incrementer = alpha_incrementer # Inc_delay = frames that pass before next alpha update: self.alpha_inc_delay = 60 # 60 = One frame # Flag for completion: self.is_complete = False self.image = pygame.Surface([800, 600]) self.rect = self.image.get_rect() self.rect.centerx = SCREEN_WIDTH / 2 self.rect.centery = SCREEN_HEIGHT / 2 self.image.fill((0, 0, 0)) self.image.set_alpha(0) self.fade_timer = Timer() self.initial_time = pygame.time.get_ticks() def render(self): pass def update(self): # Alpha incrementer is not actually an incrementer for the image's alpha; # surface.blit STACKS these images on top of each other. Alpha is still # tracked via incrementing, however: self.image.set_alpha(self.alpha_incrementer) self.surface.blit(self.image, (0, 0)) total_elapsed_time = pygame.time.get_ticks() - self.initial_time # End conditions: if total_elapsed_time > 4000 or self.alpha > 255: self.is_complete = True # Transparency incrementation: if self.fade_timer.elapsed_time() > self.alpha_inc_delay: self.alpha += self.alpha_incrementer
def delete_images(self, image_ids): for image_id in image_ids: snapshots = self.get_image_snapshots(image_id) self.deregister_image(image_id) if snapshots is not None: self.delete_snapshots(snapshots) with Timer(timeout_seconds=300) as timer: image = self.get_image(image_id) if image is None: return if timer.timeout: raise "Timeout deleting image {}" time.sleep(10)
def wait_until_not_longer_in_status(self, status, timeout=900): current_status = self.get_stack_status() with Timer(timeout_seconds=timeout, start=True) as timer: while True: if type(status) == list: if current_status not in status: break else: if current_status != status: break if timer.timeout: raise Exception( "Timeout waiting stack {} to get out of status {}". format(self.stack_name, status)) time.sleep(20)
def copy_snapshot(self, snapshot_id, destination_region, tags=None, description=None, wait_to_complete=300): ec2_destination = Ec2(region=destination_region) ec2_destination_client = boto3.client("ec2", region_name=destination_region) args = {"SourceSnapshotId": snapshot_id, "SourceRegion": self.region} if description is not None: args["Description"] = description with Timer(timeout_seconds=wait_to_complete) as timer: while True: try: if timer.timeout: return None snapshot_copy_id = ec2_destination_client.copy_snapshot( **args)["SnapshotId"] break except Exception as ex: if self.snapshot_request_limit_exceeded(ex): time.sleep(20) snapshot = ec2_destination.get_snapshot(snapshot_copy_id) if wait_to_complete == 0: if snapshot is not None: ec2_destination.create_tags( resource_ids=[snapshot["SnapshotId"]], tags=tags) return snapshot while True: if snapshot["State"] == "completed": ec2_destination.create_tags( resource_ids=[snapshot["SnapshotId"]], tags=tags) return snapshot if timer.timeout: return None time.sleep(20) snapshot = ec2_destination.get_snapshot(snapshot_copy_id) if snapshot["State"] == "error": return None
def check_real(ltl_text, part_text, is_moore, ltl_to_atm: LTLToAutomaton, solver: SolverInterface, max_k: int, min_size, max_size, opt_level=0) -> LTS: """ When opt_level>0, introduce incompleteness (but it is sound: if returns REAL, then REAL) When max_k>0, reduce UCW to k-UCW. """ timer = Timer() spec = parse_acacia_and_build_expr(ltl_text, part_text, ltl_to_atm, opt_level) logging.info("LTL formula size: %i", expr_size(spec.formula)) timer.sec_restart() automaton = ltl_to_atm.convert(~spec.formula) logging.info('automaton size is: %i' % len(automaton.nodes)) logging.debug('automaton (dot) is:\n' + automaton_to_dot.to_dot(automaton)) logging.debug('automaton translation took (sec): %i' % timer.sec_restart()) tau_desc = build_tau_desc(spec.inputs) desc_by_output = dict( (o, build_output_desc(o, is_moore, spec.inputs)) for o in spec.outputs) if max_k == 0: logging.info("using CoBuchiEncoder") encoder = CoBuchiEncoder(automaton, tau_desc, spec.inputs, desc_by_output, range(max_size)) model = model_searcher.search(min_size, max_size, encoder, solver) else: coreach_automaton = k_reduce(automaton, max_k) # with open('/tmp/orig.dot', 'w') as f: # f.write(automaton_to_dot.to_dot(automaton)) # with open('/tmp/red.dot', 'w') as f: # f.write(automaton_to_dot.to_dot(coreach_automaton)) # exit() logging.info("using CoReachEncoder") logging.info('co-reachability automaton size is: %i' % len(coreach_automaton.nodes)) logging.debug('co-reachability automaton (dot) is:\n' + automaton_to_dot.to_dot(coreach_automaton)) encoder = CoreachEncoder(coreach_automaton, tau_desc, spec.inputs, desc_by_output, range(max_size), max_k) model = model_k_searcher.search(min_size, max_size, max_k, encoder, solver) logging.info('searching a model took (sec): %i' % timer.sec_restart()) return model
def __init__(self, dict_enemy): """Boss 2 housing class. Controls all body parts.""" super(Boss2, self).__init__(dict_enemy) self.image_dir = self.params["image"] self.has_entered = False self.is_attacking = False self.is_dying = False self.is_dead = False self.next_attack_timer = Timer() self.attack_scheduler = ActionScheduler() self.image = pygame.transform.scale2x(self.image) # Debug only self.hitmask = pygame.mask.from_surface(self.image) self.initialize_body_parts()
def terminate_instance(self, instance_id, wait_to_complete=300): status = self.get_instance_status(instance_id) if status in [None, "terminated"]: return True self.ec2_client.terminate_instances(InstanceIds=[instance_id]) time.sleep(15) with Timer(timeout_seconds=wait_to_complete) as timer: while True: status = self.get_instance_status(instance_id) if status == "terminated": return True if timer.timeout: return False time.sleep(10)
def create_snapshot(self, volume_id, tags=None, description=None, wait_to_complete=300): args = {"VolumeId": volume_id} if tags is not None: args["TagSpecifications"] = [{ "ResourceType": "snapshot", "Tags": [{ "Key": t, "Value": tags[t] } for t in tags] }] if description is not None: args["Description"] = description with Timer(timeout_seconds=wait_to_complete) as timer: while True: try: if timer.timeout: return None snapshot_id = self.ec2_client.create_snapshot( **args)["SnapshotId"] break except Exception as ex: if self.snapshot_creation_per_volume_rate_exceeded(ex): time.sleep(20) snapshot = self.get_snapshot(snapshot_id) if wait_to_complete == 0: return snapshot while True: if snapshot["State"] == "completed": return snapshot if timer.timeout: return None time.sleep(20) snapshot = self.get_snapshot(snapshot_id) if snapshot["State"] == "error": return None
def delete_cluster_snapshots(self, snapshot_ids): for db_id in snapshot_ids if isinstance(snapshot_ids, list) else [snapshot_ids]: if self.get_cluster_snapshot(db_id) is not None: while True: with Timer(timeout_seconds=300) as t: try: self.rds_client.delete_db_cluster_snapshot( DBClusterSnapshotIdentifier=db_id) except Exception as ex: if "InvalidDBClusterSnapshotState" in ex.message: if t.timeout: raise ex time.sleep(10) continue if "DBClusterSnapshotNotFound" in ex.message: break raise ex
def __init__(self, params, image_dir, image_type): super(FourWayImage, self).__init__() self.params = params self.image_type = image_type self.directions = self.params["directions"] self.speed = self.params["speed"] self.image_dir = image_dir if self.image_type == "foreground": self.image = cache_image.get(self.image_dir, convert_alpha=False) else: self.image = cache_image.get(self.image_dir) self.image = pygame.transform.scale2x(self.image) self.rect = self.image.get_rect() if self.image_type == "foreground": self.hitmask = pygame.mask.from_surface(self.image) # Used for re-arranging later: self.initial_x_pos = 0 self.initial_y_pos = 0 # Used to ensure accurate movement to screen edges: self.width_check = 0 self.height_check = 0 self.path_pointer = 0 # For perfect diagonal movement, y and x must move at different speeds, # so we get a fraction here as a coefficient for later: self.diagonal_speed_coeff = Fraction(SCREEN_HEIGHT, SCREEN_WIDTH) * self.speed self.diagonal_counter = 1 self.is_dying = False self.alpha = 255 self.alpha_timer = Timer()
def __init__(self, dict_level): self.params = dict_level self.wave_timer = Timer() self.wave_idx = 1 self.level_scheduler = ActionScheduler() self.wave_scheduler = ActionScheduler() self.level_number = self.params["level_number"] self.is_complete = False self.initialize_level_assets() self.boss = self.initialize_boss() # Wave parameters + deployment times self.deployment_times = {0: 0} self.waves = {0: 0} # self.initialize_waves() self.last_level = key_or_none("last", self.params)
def __init__(self, surface): super(FadeOut, self).__init__() self.surface = surface # Alpha value for transparency: self.alpha = 255 # Incrementer will change the 'direction' and speed of the fade: self.alpha_incrementer = -25 # Inc_delay = frames that pass before next alpha update: self.alpha_inc_delay = 60 # Flag for completion: self.is_complete = False self.image = pygame.Surface((800, 600)) self.rect = self.image.get_rect() self.image.fill((0, 0, 0)) self.image.set_alpha(255) self.fade_timer = Timer()
def __init__(self, speed, image_dir, rearrange_coeff, image_type): super(TwoWayImage, self).__init__() self.speed = speed self.image_dir = image_dir # Total number of images; multiplied for rearrange offset self.rearrange_coeff = rearrange_coeff self.image_type = image_type if self.image_type == "foreground": self.image = cache_image.get(self.image_dir, convert_alpha=False) else: self.image = cache_image.get(self.image_dir) self.rect = self.image.get_rect() self.alpha_timer = Timer() self.alpha = 255 self.is_dying = False, if self.image_type == "foreground": self.hitmask = pygame.mask.from_surface(self.image)
class TextToScreen(pygame.sprite.Sprite): """Renders text to screen as a sprite image; disappears after a set time.""" def __init__(self, txt_img, xpos_center, ypos_center, kill_time): super(TextToScreen, self).__init__() self.kill_time = kill_time self.txt_img = txt_img self.image = cache_image.get(txt_img + "_F1.png") self.rect = self.image.get_rect() self.image.set_colorkey(BLACK) self.rect.centerx = xpos_center self.rect.centery = ypos_center self.kill_timer = Timer() def update(self): if self.kill_timer.elapsed_time() > self.kill_time: self.kill() def kill(self): all_sprites_list.remove(self)
class ActionScheduler(): """ Allows for scheduling of actions via an array of times, an action index, a timer, and 4 booleans (Note: all booleans won't always be used on any given instance. They exist to cover a range of functionality.) This times array... action_times = [0, 1000, 2000, 3000] ...means that an action occurs at 1-second, 2-seconds, and 3-seconds. These elements are considered thresholds for 'sub_actions', and the entire array constitutes one total 'action.' For example, in enemy pathing, these could be changes of direction. So each change in direction would be a 'sub_action', whereas the enemy's entire 'path_times' array would be one total 'action.' 'action_idx' increments at each new time element in the times array. 'is_doing_action' = True while the timer < last time in the times array. (Note that there is no 'is_doing_subaction', because 'action_idx' won't increment until the timer hits the next 'subaction' threshold; it will remain the same for the duration of a 'subaction', so any behavior logic can simply reference that index.) 'is_done_action' = True only when timer > last time in times array. 'is done_subaction' will be True for only one 'update' cycle per 'subaction' completed. This sounds confusing, because it is...This was used to solve a problematic edge condition that arises when elapsed time > total_time and 'is_done_subaction' is set to True: it never gets set back to false. We solve that with some if-else logic and the self.kill() method: self.kill() and 'is_dead' are used only for actions that occur ONCE per 'subaction' threshold. Example: Condition: elapsed time = 1001 action_times[-1] = 1000 What happens: the first time through self.update(), 'is_done_action' and 'is_done_subaction' are set to True the NEXT time through self.update(), because 'is_done_action' is True, we go through our is_looped or kill conditions from there, if 'is_dead' == True, update returns None. """ def __init__(self, is_looped=None): self.is_doing_action = False self.is_done_action = False self.is_done_subaction = False self.is_dead = False self.action_idx = 0 self.timer = Timer() self.is_looped = is_looped def reset(self): """Loop an action by resetting booleans, index, and timer variables.""" self.is_doing_action = False self.is_done_action = False self.action_idx = 0 self.timer.reset() def kill(self): """Used to properly assign 'is_done_subaction' to False when a total action is done.""" self.is_doing_action = False self.is_done_action = True self.is_done_subaction = False self.is_dead = True def execute_final_action(self): """Determine whether to loop the action again or kill it.""" if self.is_looped: self.reset() else: self.kill() def update(self, action_times): """ Check if 'is_dead' or 'is_done_action', otherwise proceed normally: Flip 'is_doing_action' to True. Increment 'action_idx' when elapsed time reaches next 'subaction' threshold. If timer > total time, flip 'is_doing_action' = False, and 'is_done_action' = True. """ if self.is_dead: return self.is_doing_action = True self.is_done_subaction = False if self.is_done_action: self.execute_final_action() elif self.timer.elapsed_time() > action_times[-1]: self.action_idx = -1 self.is_done_action = True self.is_done_subaction = True elif self.timer.elapsed_time() > action_times[self.action_idx]: self.is_done_subaction = True self.action_idx += 1
def __init__(self, position): super(Bot, self).__init__('assets/circle.png', position) self._fire_timer = Timer(Bot.fire_rate)
class FourWayImage(pygame.sprite.Sprite): """Sprite that can move in four directions on a loop; used to create background/foreground.""" def __init__(self, params, image_dir, image_type): super(FourWayImage, self).__init__() self.params = params self.image_type = image_type self.directions = self.params["directions"] self.speed = self.params["speed"] self.image_dir = image_dir if self.image_type == "foreground": self.image = cache_image.get(self.image_dir, convert_alpha=False) else: self.image = cache_image.get(self.image_dir) self.image = pygame.transform.scale2x(self.image) self.rect = self.image.get_rect() if self.image_type == "foreground": self.hitmask = pygame.mask.from_surface(self.image) # Used for re-arranging later: self.initial_x_pos = 0 self.initial_y_pos = 0 # Used to ensure accurate movement to screen edges: self.width_check = 0 self.height_check = 0 self.path_pointer = 0 # For perfect diagonal movement, y and x must move at different speeds, # so we get a fraction here as a coefficient for later: self.diagonal_speed_coeff = Fraction(SCREEN_HEIGHT, SCREEN_WIDTH) * self.speed self.diagonal_counter = 1 self.is_dying = False self.alpha = 255 self.alpha_timer = Timer() def path(self, direction, coefficient): """ Move the sprite in various directions. Diagonal movement was very tricky, as the screen is not square, so 1 : 1 movement doesn't produce desired results. Neither does decimal movement, as trying to move by decimals of a pixel results in de-syncing the background. Instead we have to produce whole-number pixel movement based on a ratio we calculate using the speed, screen height, and screen width: ********************************************************************* EXAMPLE: SCREEN_HEIGHT / SCREEN_WIDTH = (3/4) speed: 5 coefficient = 5 * (3/4) = (15/4) diagonal_counter = 1 ticker will increment up to coefficient's denominator, y will increment by the denominator amount. when the ticker == the denominator, y += total moved space, aka: ((denominator - 1) * denominator) and diagonal_counter will reset to 1: Ticker Moved_Space 1 4 2 8 3 12 4 15 4 updates = 15 moved pixels = our original coefficient! (Some additional if-else logic had to be implemented for coefficients that were < 1 (i.e., if speed == 1 or 2), so as to not get negative movement. """ if direction == "right": self.rect.x -= self.speed self.width_check += self.speed elif direction == "down": self.rect.y -= self.speed self.height_check += self.speed elif direction == "up": self.rect.y += self.speed self.height_check += self.speed elif direction in ["upright", "downright"]: # For diagonal movement, we have to use our coefficient: if self.diagonal_counter < coefficient.denominator: if direction == "upright": # Special conditions if coefficient < 1: if coefficient < 1: self.rect.y += 1 else: self.rect.y += coefficient.denominator elif direction == "downright": if coefficient < 1: self.rect.y -= 1 else: self.rect.y -= coefficient.denominator self.diagonal_counter += 1 else: if coefficient < 1: next_move = 0 else: moved_space = (coefficient.denominator - 1) * coefficient.denominator next_move = coefficient.numerator - moved_space if direction == "upright": self.rect.y += next_move elif direction == "downright": self.rect.y -= next_move self.diagonal_counter = 1 self.rect.x -= self.speed self.width_check += self.speed self.height_check += float(self.diagonal_speed_coeff) def kill(self): if self.alpha_timer.elapsed_time() > 60: self.alpha_timer.reset() self.alpha -= 3 self.image.set_alpha(self.alpha) def update(self): """Update based on 'directions' parameter; loop when finished.""" if self.alpha <= 0: all_sprites_list.remove(self) if self.image_type == "foreground": foreground_list.remove(self) if self.is_dying: self.kill() # Continuous x-loop for foreground only: if self.image_type == "foreground" and self.rect.x < (self.initial_x_pos - 1600): self.rect.x = 0 try: current_direction = self.directions[self.path_pointer] # Reset flags if they reach screen dimensions (more precise than a timer): if self.image_type == "background": if self.width_check >= SCREEN_WIDTH or self.height_check >= SCREEN_HEIGHT: # TODO: Fix looped clipping: self.width_check = 0 self.height_check = 0 self.path_pointer += 1 else: # Foreground moves at 2x the speed of background, thus double the checks: if self.width_check >= SCREEN_WIDTH * 2 or self.height_check >= SCREEN_HEIGHT * 2: self.width_check = 0 self.height_check = 0 self.path_pointer += 1 self.path(current_direction, self.diagonal_speed_coeff) except IndexError: self.rearrange() def rearrange(self): """Reset images for looping.""" self.rect.x = self.initial_x_pos - self.speed self.rect.y = self.initial_y_pos self.path_pointer = 0
class Level(object): """Deploy waves of enemies based on a dictionary of parameters.""" def __init__(self, dict_level): self.params = dict_level self.wave_timer = Timer() self.wave_idx = 1 self.level_scheduler = ActionScheduler() self.wave_scheduler = ActionScheduler() self.level_number = self.params["level_number"] self.is_complete = False self.initialize_level_assets() self.boss = self.initialize_boss() # Wave parameters + deployment times self.deployment_times = {0: 0} self.waves = {0: 0} # self.initialize_waves() self.last_level = key_or_none("last", self.params) def initialize_level_assets(self): """Initialize background and foreground art for the level.""" # Boolean which determines if level is sidescrolling or multi-directional self.has_directional_bg = key_or_none("has_directional_bg", self.params) if self.has_directional_bg is None: self.background = TwoWayBackground(self.params["bg_params"]) self.foreground = TwoWayForeground(self.params["fg_params"]) else: self.background = FourWayBackground(self.params["bg_params"]) self.foreground = FourWayForeground(self.params["fg_params"]) def initialize_boss(self): """Initialize the level's boss, based on params.""" params_dict = self.params["boss"] klass = params_dict["class"] params = params_dict["params"] boss = klass(params) return boss def initialize_waves(self): """Unpack wave and deployment time parameters into separate dicts.""" # NOTE: DO NOT TOUCH THESE BLOCKS!!! # Loops for collecting Deployment Times: deployment_times = self.params["deployment_times"] for wave_num in deployment_times: try: for subwave_times in deployment_times[wave_num]: self.deployment_times[len(self.deployment_times)] = subwave_times except TypeError: self.deployment_times[len(self.deployment_times)] = deployment_times[wave_num] # Multiply times by 1000 to account for milliseconds: for wave_num in self.deployment_times: self.deployment_times[wave_num] *= 1000 # Loop for collecting Waves: waves = self.params["waves"] for wave_num in waves: if isinstance(waves[wave_num][0], list): for wave_params in waves[wave_num]: self.waves[len(self.waves)] = wave_params else: self.waves[len(self.waves)] = waves[wave_num] def load_wave(self, params_wave): """ Return a wave of enemies based on the parameters dictionary, accounting for positional offsets, vertical flips, and horizontal flips. """ # Get parameters from the dict: next_wave = [] num_enemy = params_wave[0] klass = params_wave[1] params_enemy = params_wave[2] offsets = params_wave[3] vertical_flips = params_wave[4] horizontal_flips = params_wave[5] # Special offsets applied to FallingBlocks to spawn simultaneously: if klass == FallingBlock: for i in range(num_enemy): enemy = klass(params_enemy) if offsets is not None: enemy.rect.centerx += offsets[i][0] enemy.rect.centery += offsets[i][1] next_wave.append(enemy) else: # Apply any x- or y- shifts: for i in range(0, num_enemy): enemy = klass(params_enemy) if offsets is not None: enemy.rect.centerx += offsets[0] enemy.rect.centery += offsets[1] next_wave.append(enemy) # Apply flips ([i - 1] because params are not 0-indexed): if horizontal_flips is not None: for i in horizontal_flips: next_wave[i - 1].flip_path_horizontal() if vertical_flips is not None: for i in vertical_flips: next_wave[i - 1].flip_path_vertical() all_sprites_list.add(next_wave) enemy_sprite_list.add(next_wave) def display_boss_warning(self): """Flash a warning message that the boss is approaching.""" warning = BossWarning("screen_messages/boss_warning", SCREEN_WIDTH / 2, 200, 6000) all_sprites_list.add(warning) message = TextToScreen("screen_messages/boss_approaching", SCREEN_WIDTH / 2, 300, 6000) all_sprites_list.add(message) def release_wave(self, wave, offset): if self.wave_scheduler.is_done_action: self.wave_scheduler.reset() self.wave_timer.reset() self.wave_idx += 1 return wave_times = [((x * 1000) + offset) for x in wave["wave_times"]] enemy_params = wave["enemies"] self.wave_scheduler.update(wave_times) wave_idx = self.wave_scheduler.action_idx - 1 #TODO: Temporary hack, should fix if wave_idx == -2: wave_idx = -1 if self.wave_scheduler.is_done_subaction or self.wave_scheduler.is_done_action: self.load_wave(enemy_params[wave_idx]) def run(self): """Load all waves and deploy them based on a timed schedule.""" # try: # Level completion conditions: if self.boss.is_dead == True: self.is_complete = True last_wave = self.params["waves"][self.wave_idx - 1] current_wave = self.params["waves"][self.wave_idx] start_time = (current_wave["deployment_time"] - last_wave["deployment_time"]) * 1000 if self.wave_timer.elapsed_time() > start_time: if current_wave["wave_times"] == "BOSS": all_sprites_list.add(self.boss) boss_list.add(self.boss) elif current_wave["wave_times"] == "WARNING": self.wave_timer.reset() self.wave_idx += 1 self.display_boss_warning() self.foreground.kill() else: self.release_wave(current_wave, start_time)
class AnimationScheduler(): """Class to handle various types of sprite animations.""" def __init__(self, is_looped, is_seesaw=False): self.is_looped = is_looped self.is_seesaw = is_seesaw self.is_done_animating = False self.frame_idx = 0 self.timer = Timer() if self.is_seesaw: self.frame_incrementer = 1 def reset(self): """Reset boolean, frame index, and timer.""" self.is_done_animating = False self.frame_idx = 0 self.timer.reset() def looped_update(self, anim_times, static_time_threshold): """Update looped animation based on a schedule of times or a single static threshold.""" if anim_times is not None: if self.timer.elapsed_time() > anim_times[self.frame_idx]: self.frame_idx += 1 self.timer.reset() elif self.timer.elapsed_time() > static_time_threshold: self.frame_idx += 1 self.timer.reset() def seesaw_update(self, anim_times, static_time_threshold): """Update an animation that loops by playing itself backwards and forwards.""" try: if self.timer.elapsed_time() > static_time_threshold: self.frame_idx += self.frame_incrementer self.timer.reset() except pygame.error: self.frame_incrementer *= -1 def normal_update(self, anim_times): """Update linear animation that plays one time before flipping 'is_done_animating'.""" if self.is_done_animating: return # Necessary edge condition: elif len(anim_times) < 2: if self.timer.elapsed_time() > anim_times[self.frame_idx]: self.frame_idx += 1 self.is_done_animating = True elif self.frame_idx == len(anim_times) - 1 and self.timer.elapsed_time() > anim_times[-1]: self.is_done_animating = True # This needs to be separated from the above if-statement to preserve the last frame of # animation. If we tried to flip 'is_done_animating' AND increment frame_idx at the same # time, we don't get to see the last frame of the animation. Separating here ensures that: elif self.frame_idx == len(anim_times) - 2 and self.timer.elapsed_time() > anim_times[-2]: self.frame_idx += 1 elif self.timer.elapsed_time() > anim_times[self.frame_idx]: self.frame_idx += 1 self.timer.reset() def get_next_frame(self, image_dir, convert_alpha=True): """Return next frame in the animation.""" # Using aTry-Except block allows me to easily add new frame assets to a # looped animation without updating any code whatsoever! try: image = cache_image.get(image_dir + "_F{}.png".format(self.frame_idx), convert_alpha) except pygame.error: if self.is_looped: self.reset() image = cache_image.get(image_dir + "_F{}.png".format(self.frame_idx), convert_alpha) elif self.is_seesaw: self.frame_incrementer *= -1 self.frame_idx += self.frame_incrementer image = cache_image.get(image_dir + "_F{}.png".format(self.frame_idx), convert_alpha) return image def update(self, anim_times=None, static_time_threshold=120): """Update based on type of animation.""" if self.is_looped: self.looped_update(anim_times, static_time_threshold) elif self.is_seesaw: self.seesaw_update(anim_times, static_time_threshold) else: self.normal_update(anim_times)
class Boss2(EnemyLinear): def __init__(self, dict_enemy): """Boss 2 housing class. Controls all body parts.""" super(Boss2, self).__init__(dict_enemy) self.image_dir = self.params["image"] self.has_entered = False self.is_attacking = False self.is_dying = False self.is_dead = False self.next_attack_timer = Timer() self.attack_scheduler = ActionScheduler() self.image = pygame.transform.scale2x(self.image) # Debug only self.hitmask = pygame.mask.from_surface(self.image) self.initialize_body_parts() def initialize_body_parts(self): """Set up head and claw body parts as separate sprites.""" from models.bosses.boss_2_head import Boss2Head head = Boss2Head(self) self.head = head def add_body_parts(self): """Add body parts to necessary lists.""" all_sprites_list.add(self.head) def enter(self): if self.has_entered: return if self.rect.centerx <= 550 and self.rect.centery <= SCREEN_HEIGHT / 2: self.has_entered = True self.next_attack_timer.reset() self.head.attack_scheduler.reset() self.attack_scheduler.reset() if not self.has_entered: self.add_body_parts() if self.rect.centerx >= 550: self.rect.x -= 1 if self.rect.centery >= SCREEN_HEIGHT / 2: self.rect.y -= 1 def reset_attack_parameters(self): """Reset all parameters for boss's (and body parts') attacks.""" self.next_attack_timer.reset() self.attack_scheduler.reset() self.head.reset_attack_parameters() def laser_head_attack(self, time_offset): attack_times = [750, 10000, 10750] attack_speeds = [6, 0, -6] attack_times = [(x + time_offset) for x in attack_times] self.attack_scheduler.update(attack_times) if not self.attack_scheduler.is_done_action: idx = self.attack_scheduler.action_idx current_speed = attack_speeds[idx] self.rect.x += current_speed if idx == 1: self.head.laser_attack(time_offset + 750) else: self.reset_attack_parameters() self.is_attacking = self.attack_scheduler.is_doing_action def update(self): self.enter() if self.has_entered and not self.is_dying: if self.next_attack_timer.elapsed_time() > 2500: self.laser_head_attack(2500)
class FallingBlock(EnemyLinear): """Environment Block that will fall unless supported by a floor block.""" def __init__(self, dict_enemy): super(FallingBlock, self).__init__(dict_enemy) # NOTE: falling_block_list is only used for collision logic # FallingBlock()s are added to enemy_sprite_list and use that logic falling_block_list.add(self) self.fall_timer = Timer() self.fall_speed = 3 self.is_falling = False def check_collision(self, sprite_list): """Check for vertical collision with a sprite list, skipping itself.""" for block in sprite_list: # Continue falling if self = the only block in the list: if self == block: if len(sprite_list) == 1: self.is_falling = True self.fall_timer.reset() continue # 15 = the 'edge cushion' needed to keep the block from falling: x_range = range(block.rect.x - self.rect.width + 15, block.rect.x + block.rect.width - 15) y_range = range(block.rect.y, block.rect.y + block.rect.height) if (self.rect.x in x_range and self.rect.y + self.rect.height in y_range): self.rect.y = (block.rect.y - self.rect.height + (self.fall_speed / 2) ) self.is_falling = False else: if not self.is_falling: self.is_falling = True self.fall_timer.reset() def fall(self, fall_speed): """Move the block downward, with a slight pause at the top for visual effect.""" if self.fall_timer.elapsed_time() > 60: self.rect.y += (fall_speed * 4) else: self.rect.y += fall_speed def update(self): """Kill if necessary; check collisions; update fall speed.""" if (self.rect.centerx < -700 or self.rect.centerx > SCREEN_WIDTH + 700 or self.rect.centery < -200 or self.rect.centery > SCREEN_HEIGHT + 200): self.kill() self.check_collision(falling_block_list) if self.is_falling: self.fall(self.fall_speed) self.rect.x -= 3