Module game_qu.base.utility_functions
Expand source code
import math
from math import sqrt
from game_qu.base.library_changer import LibraryChanger
if not LibraryChanger.get_library_has_been_set():
LibraryChanger.set_game_library("pygame")
from game_qu.base.fraction import Fraction
from game_qu.base.important_variables import keyboard, SCREEN_LENGTH, SCREEN_HEIGHT, IS_USING_CONTROLLER
import random
from game_qu.library_abstraction import utility_functions
from game_qu.base.range import Range
# Retrieving the functions from the game library code
load_image = getattr(utility_functions, "load_image")
load_text = getattr(utility_functions, "load_text")
render_text = getattr(utility_functions, "render_text")
render_image = getattr(utility_functions, "render_image")
render_ellipse = getattr(utility_functions, "render_ellipse")
render_rectangle = getattr(utility_functions, "render_rectangle")
set_up_window = getattr(utility_functions, "set_up_window")
key_is_pressed = getattr(utility_functions, "key_is_pressed")
mouse_was_pressed = getattr(utility_functions, "mouse_was_pressed")
call_every_cycle = getattr(utility_functions, "call_every_cycle")
is_mouse_collision = getattr(utility_functions, "is_mouse_collision")
get_time_passed = getattr(utility_functions, "get_time_passed")
load_and_transform_image = getattr(utility_functions, "load_and_transform_image")
get_directional_path_to_image = getattr(utility_functions, "get_directional_path_to_image")
def key_is_pressed(key):
"""
Returns:
bool: whether that key is currently held down (pressed)"""
return keyboard.get_key_event(key).happened_this_cycle
def key_is_clicked(key):
"""
Returns:
bool: whether the key was not held down last cycle and is this cycle (clicked)"""
return keyboard.get_key_event(key).is_click()
def key_has_been_released(key):
"""
Returns:
bool: whether the key was held down last cycle and is not this cycle (released)"""
return keyboard.get_key_event(key).has_stopped()
def get_time_of_key_being_held_in(key):
"""
Returns:
float: the amount of time that the key has been held down"""
return keyboard.get_key_timed_event(key).current_time
def button_is_pressed(button):
"""
Returns:
bool: whether that button is currently held down (pressed)"""
return keyboard.get_button_event(button).happened_this_cycle
def button_is_clicked(button):
"""
Returns:
bool: whether the button was not held down last cycle and is this cycle (clicked)"""
return keyboard.get_button_event(button).is_click()
def button_has_been_released(button):
"""
Returns:
bool: whether the button was held down last cycle and is not this cycle (released)"""
return keyboard.get_button_event(button).has_stopped()
def get_time_of_button_being_held_in(button):
"""
Returns:
float: the amount of time that the button has been held down"""
return keyboard.get_button_timed_event(button).current_time
def button_is_pressed(button):
"""
Returns:
bool: whether that button is currently held down (pressed)"""
return keyboard.get_button_event(button).happened_this_cycle
def get_game_button_timed_event(game_button):
"""
Returns:
TimedEvent: the TimedEvent that is associated with the current state (using the keyboard or controller)"""
return keyboard.get_button_timed_event(game_button) if IS_USING_CONTROLLER else keyboard.get_key_timed_event(game_button)
def get_game_button_event(game_button):
"""
Returns:
Event: the Event that is associated with the current state (using the keyboard or controller)"""
return keyboard.get_button_event(game_button) if IS_USING_CONTROLLER else keyboard.get_key_event(game_button)
def game_button_is_pressed(game_button):
"""
Returns:
bool: whether that game_button is currently held down (pressed)"""
return get_game_button_event(game_button).happened_this_cycle
def game_button_is_clicked(game_button):
"""
Returns:
bool: whether the game_button was not held down last cycle and is this cycle (clicked)"""
return get_game_button_event(game_button).is_click()
def game_button_has_been_released(game_button):
"""
Returns:
bool: whether the game_button was held down last cycle and is not this cycle (released)"""
return get_game_button_event(game_button).has_stopped()
def get_time_of_game_button_being_held_in(game_button):
"""
Returns:
float: the amount of time that the game_button has been held down"""
return get_game_button_timed_event(game_button).current_time
def mouse_is_clicked():
"""
Returns:
bool: whether the mouse was not pressed last cycle and is this cycle (clicked)"""
return keyboard.mouse_clicked_event.is_click()
def get_index_of_range(number, range_lengths=[], ranges=None):
""" Finds the index of the range that contains the current number. A range is defined by the numbers between
two adjacent indexes (range_lengths[0] -> range_lengths[1])
Args:
range_lengths (list[float]): the lengths of the ranges. For instance, if the range_lengths is [1, 1, 1] then the ranges would be [0 -> 1, 1 -> 2, 2 -> 3]
number (float): the number that is wanted to be within a range
Returns:
int: The index of the range that contains the number and -1 no range contains it"""
index = -1
if ranges is None:
ranges = get_ranges(range_lengths)
for x in range(len(ranges)):
if ranges[x].__contains__(number):
index = x
break
return index
def get_ranges(range_lengths) -> list[Range]:
"""
Returns:
list[Range]: the ranges gotten from the range_lengths. A range is defined by two adjacent indexes (range_lengths[0] -> range_lengths[1])"""
return_value = []
current_value = 0
for range_length in range_lengths:
return_value.append(Range(current_value, current_value + range_length))
current_value += range_length
return return_value
def is_within_screen(game_object):
"""
Returns:
bool: if the game_object is within the screen (can be seen on the screen)"""
return (game_object.right_edge > 0 and game_object.left_edge < SCREEN_LENGTH and
game_object.bottom_edge > 0 and game_object.top_edge < SCREEN_HEIGHT)
def is_random_chance(probability: Fraction):
""" Uses the probability for the random chance (for instance if the probability is 7/10 then 7 out of 10
times it will return True and the other 3 times it will return False)
Args:
probability (Fraction): the probability this function will return True
Returns:
bool: if the random number between 1-probability.denominator is >= probability.numerator
"""
return random.randint(1, probability.denominator) <= probability.numerator
def is_beyond_screen_left(left_edge):
"""
Returns:
bool: if the left_edge is beyond the left side of the screen"""
return left_edge <= 0
def is_beyond_screen_right(right_edge):
"""
Returns:
bool: if the right_edge is beyond the right side of the screen"""
return right_edge >= SCREEN_LENGTH
def min_value(item1, item2):
"""
Returns:
float: the smallest item"""
if item1 is None:
return item2
if item2 is None:
return item1
return item1 if item1 < item2 else item2
def max_value(item1, item2):
"""
Returns:
float: the biggest item"""
return item1 if item1 > item2 else item2
def get_combined_number_values(numbers):
"""
Returns:
float or int: all the numbers in 'numbers' added up together in one number"""
return_value = 0
for number in numbers:
return_value += number
return return_value
def get_next_index(current_index, max_index):
"""
Returns:
int: the index after current_index (it cycles, so once it gets beyond the max_index it goes back to 0)"""
next_index = current_index + 1
return next_index if next_index <= max_index else 0
def get_previous_index(current_index, max_index):
"""
Returns:
int: the index before current_index (it cycles, so once it gets below 0 it goes to the max_index"""
prev_index = current_index - 1
return prev_index if prev_index >= 0 else max_index
def rounded(number, places):
"""
Returns:
float: the number rounded to that many decimal places"""
rounded_number = int(number * pow(10, places))
# Converting it back to the proper decimals once it gets rounded from above
return rounded_number / pow(10, places)
def get_kwarg_item(kwargs, key, default_value):
"""
Returns: the value associated with the key in kwargs and the default value if the key is not in kwargs
Args:
kwargs (dict): the **kwargs
key (object): the key for the item
default_value (object): the value that will be obtained if the kwargs doesn't contain the key
Returns:
object: kwargs.get(key) if kwargs contains the key otherwise it will return the default_value
"""
return kwargs.get(key) if kwargs.__contains__(key) else default_value
def solve_quadratic(a, b, c):
"""
Returns:
list[float]: [answer1, answer2] the answers to the quadratic
and if the answer is an imaginary number it returns float('nan')"""
number_under_square_root = pow(b, 2) - 4 * a * c
number_under_square_root = rounded(number_under_square_root, 4)
if number_under_square_root < 0:
return None
square_root = sqrt(number_under_square_root)
answer1 = (-b + square_root) / (2 * a)
answer2 = (-b - square_root) / (2 * a)
answers = [answer2, answer1]
# If the answers are the same I should only return one of them
return answers if answers[0] != answers[1] else [answers[0]]
def modified_mod(number, modulus):
""" This is a modified version of the modulus operator. This performs the same way for negative numbers and positive
numbers. This means that 50 % 9 = 5 and -50 % 9 = -5.
Returns:
float: the number % modulus that conforms to the rules specified above"""
number_is_negative = number < 0
value = math.fabs(number) % modulus
constant_factor = -1 if number_is_negative else 1 # So the number can be converted back to a negative number
# If the decimal is chopped off by converting it into an int and it is still the same value, it must be equal
modulus_is_whole_number = modulus == int(modulus)
if modulus_is_whole_number:
number_decimal = get_decimal_with_full_accuracy(number)
int_number = int(number)
value = int(math.fabs(int_number)) % modulus
value += number_decimal
return value * constant_factor # An int should be gotten back
def get_decimal_with_full_accuracy(number):
"""
Returns:
float: the decimal part of the number i.e. 1.2345 -> 0.2345 (maintains full decimal accuracy)"""
string_number = str(number)
float_string = ""
for x in range(len(string_number)):
if string_number[x] == ".":
float_string = f"0{string_number[x:]}" # [x:] gives the entire decimal ('.' onwards)
return float(float_string) if len(float_string) != 0 else 0
def do_nothing(*args):
"""This function does absolutely nothing (useful if you want to have a command and have it by default do nothing)"""
pass
def is_within_bounds(value, min_value, max_value):
""" Checks if the 'value' is within the specified bounds
Args:
value (float): value to be checked
min_value (float): minimum bound
max_value (float): maximum bound
Returns:
bool: whether the value is within the specified bounds"""
return min_value <= value <= max_value
def get_sign(number):
"""
Returns:
int: -1 if the number is negative and 1 if the number is positive"""
return -1 if number < 0 else 1
def get_inverse_sign(number):
"""
Returns:
int: 1 if the number is negative and -1 if the number is positive"""
return -get_sign(number)
Functions
-
Returns: bool: whether the button was held down last cycle and is not this cycle (released)
Expand source code
def button_has_been_released(button): """ Returns: bool: whether the button was held down last cycle and is not this cycle (released)""" return keyboard.get_button_event(button).has_stopped()
-
Returns: bool: whether the button was not held down last cycle and is this cycle (clicked)
Expand source code
def button_is_clicked(button): """ Returns: bool: whether the button was not held down last cycle and is this cycle (clicked)""" return keyboard.get_button_event(button).is_click()
-
Returns: bool: whether that button is currently held down (pressed)
Expand source code
def button_is_pressed(button): """ Returns: bool: whether that button is currently held down (pressed)""" return keyboard.get_button_event(button).happened_this_cycle
def do_nothing(*args)
-
This function does absolutely nothing (useful if you want to have a command and have it by default do nothing)
Expand source code
def do_nothing(*args): """This function does absolutely nothing (useful if you want to have a command and have it by default do nothing)""" pass
-
Returns: bool: whether the game_button was held down last cycle and is not this cycle (released)
Expand source code
def game_button_has_been_released(game_button): """ Returns: bool: whether the game_button was held down last cycle and is not this cycle (released)""" return get_game_button_event(game_button).has_stopped()
-
Returns: bool: whether the game_button was not held down last cycle and is this cycle (clicked)
Expand source code
def game_button_is_clicked(game_button): """ Returns: bool: whether the game_button was not held down last cycle and is this cycle (clicked)""" return get_game_button_event(game_button).is_click()
-
Returns: bool: whether that game_button is currently held down (pressed)
Expand source code
def game_button_is_pressed(game_button): """ Returns: bool: whether that game_button is currently held down (pressed)""" return get_game_button_event(game_button).happened_this_cycle
def get_combined_number_values(numbers)
-
Returns: float or int: all the numbers in 'numbers' added up together in one number
Expand source code
def get_combined_number_values(numbers): """ Returns: float or int: all the numbers in 'numbers' added up together in one number""" return_value = 0 for number in numbers: return_value += number return return_value
def get_decimal_with_full_accuracy(number)
-
Returns: float: the decimal part of the number i.e. 1.2345 -> 0.2345 (maintains full decimal accuracy)
Expand source code
def get_decimal_with_full_accuracy(number): """ Returns: float: the decimal part of the number i.e. 1.2345 -> 0.2345 (maintains full decimal accuracy)""" string_number = str(number) float_string = "" for x in range(len(string_number)): if string_number[x] == ".": float_string = f"0{string_number[x:]}" # [x:] gives the entire decimal ('.' onwards) return float(float_string) if len(float_string) != 0 else 0
-
Returns: Event: the Event that is associated with the current state (using the keyboard or controller)
Expand source code
def get_game_button_event(game_button): """ Returns: Event: the Event that is associated with the current state (using the keyboard or controller)""" return keyboard.get_button_event(game_button) if IS_USING_CONTROLLER else keyboard.get_key_event(game_button)
-
Returns: TimedEvent: the TimedEvent that is associated with the current state (using the keyboard or controller)
Expand source code
def get_game_button_timed_event(game_button): """ Returns: TimedEvent: the TimedEvent that is associated with the current state (using the keyboard or controller)""" return keyboard.get_button_timed_event(game_button) if IS_USING_CONTROLLER else keyboard.get_key_timed_event(game_button)
def get_index_of_range(number, range_lengths=[], ranges=None)
-
Finds the index of the range that contains the current number. A range is defined by the numbers between two adjacent indexes (range_lengths[0] -> range_lengths[1])
Args
range_lengths
:list[float]
- the lengths of the ranges. For instance, if the range_lengths is [1, 1, 1] then the ranges would be [0 -> 1, 1 -> 2, 2 -> 3]
number
:float
- the number that is wanted to be within a range
Returns: int: The index of the range that contains the number and -1 no range contains it
Expand source code
def get_index_of_range(number, range_lengths=[], ranges=None): """ Finds the index of the range that contains the current number. A range is defined by the numbers between two adjacent indexes (range_lengths[0] -> range_lengths[1]) Args: range_lengths (list[float]): the lengths of the ranges. For instance, if the range_lengths is [1, 1, 1] then the ranges would be [0 -> 1, 1 -> 2, 2 -> 3] number (float): the number that is wanted to be within a range Returns: int: The index of the range that contains the number and -1 no range contains it""" index = -1 if ranges is None: ranges = get_ranges(range_lengths) for x in range(len(ranges)): if ranges[x].__contains__(number): index = x break return index
def get_inverse_sign(number)
-
Returns: int: 1 if the number is negative and -1 if the number is positive
Expand source code
def get_inverse_sign(number): """ Returns: int: 1 if the number is negative and -1 if the number is positive""" return -get_sign(number)
def get_kwarg_item(kwargs, key, default_value)
-
Returns: the value associated with the key in kwargs and the default value if the key is not in kwargs
Args
kwargs
:dict
- the **kwargs
key
:object
- the key for the item
default_value
:object
- the value that will be obtained if the kwargs doesn't contain the key
Returns: object: kwargs.get(key) if kwargs contains the key otherwise it will return the default_value
Expand source code
def get_kwarg_item(kwargs, key, default_value): """ Returns: the value associated with the key in kwargs and the default value if the key is not in kwargs Args: kwargs (dict): the **kwargs key (object): the key for the item default_value (object): the value that will be obtained if the kwargs doesn't contain the key Returns: object: kwargs.get(key) if kwargs contains the key otherwise it will return the default_value """ return kwargs.get(key) if kwargs.__contains__(key) else default_value
def get_next_index(current_index, max_index)
-
Returns: int: the index after current_index (it cycles, so once it gets beyond the max_index it goes back to 0)
Expand source code
def get_next_index(current_index, max_index): """ Returns: int: the index after current_index (it cycles, so once it gets beyond the max_index it goes back to 0)""" next_index = current_index + 1 return next_index if next_index <= max_index else 0
def get_previous_index(current_index, max_index)
-
Returns: int: the index before current_index (it cycles, so once it gets below 0 it goes to the max_index
Expand source code
def get_previous_index(current_index, max_index): """ Returns: int: the index before current_index (it cycles, so once it gets below 0 it goes to the max_index""" prev_index = current_index - 1 return prev_index if prev_index >= 0 else max_index
def get_ranges(range_lengths) ‑> list[Range]
-
Returns: list[Range]: the ranges gotten from the range_lengths. A range is defined by two adjacent indexes (range_lengths[0] -> range_lengths[1])
Expand source code
def get_ranges(range_lengths) -> list[Range]: """ Returns: list[Range]: the ranges gotten from the range_lengths. A range is defined by two adjacent indexes (range_lengths[0] -> range_lengths[1])""" return_value = [] current_value = 0 for range_length in range_lengths: return_value.append(Range(current_value, current_value + range_length)) current_value += range_length return return_value
def get_sign(number)
-
Returns: int: -1 if the number is negative and 1 if the number is positive
Expand source code
def get_sign(number): """ Returns: int: -1 if the number is negative and 1 if the number is positive""" return -1 if number < 0 else 1
-
Returns: float: the amount of time that the button has been held down
Expand source code
def get_time_of_button_being_held_in(button): """ Returns: float: the amount of time that the button has been held down""" return keyboard.get_button_timed_event(button).current_time
-
Returns: float: the amount of time that the game_button has been held down
Expand source code
def get_time_of_game_button_being_held_in(game_button): """ Returns: float: the amount of time that the game_button has been held down""" return get_game_button_timed_event(game_button).current_time
def get_time_of_key_being_held_in(key)
-
Returns: float: the amount of time that the key has been held down
Expand source code
def get_time_of_key_being_held_in(key): """ Returns: float: the amount of time that the key has been held down""" return keyboard.get_key_timed_event(key).current_time
def is_beyond_screen_left(left_edge)
-
Returns: bool: if the left_edge is beyond the left side of the screen
Expand source code
def is_beyond_screen_left(left_edge): """ Returns: bool: if the left_edge is beyond the left side of the screen""" return left_edge <= 0
def is_beyond_screen_right(right_edge)
-
Returns: bool: if the right_edge is beyond the right side of the screen
Expand source code
def is_beyond_screen_right(right_edge): """ Returns: bool: if the right_edge is beyond the right side of the screen""" return right_edge >= SCREEN_LENGTH
def is_random_chance(probability: Fraction)
-
Uses the probability for the random chance (for instance if the probability is 7/10 then 7 out of 10 times it will return True and the other 3 times it will return False)
Args
probability
:Fraction
- the probability this function will return True
Returns: bool: if the random number between 1-probability.denominator is >= probability.numerator
Expand source code
def is_random_chance(probability: Fraction): """ Uses the probability for the random chance (for instance if the probability is 7/10 then 7 out of 10 times it will return True and the other 3 times it will return False) Args: probability (Fraction): the probability this function will return True Returns: bool: if the random number between 1-probability.denominator is >= probability.numerator """ return random.randint(1, probability.denominator) <= probability.numerator
def is_within_bounds(value, min_value, max_value)
-
Checks if the 'value' is within the specified bounds
Args
value
:float
- value to be checked
min_value
:float
- minimum bound
max_value
:float
- maximum bound
Returns
bool
- whether the value is within the specified bounds
Expand source code
def is_within_bounds(value, min_value, max_value): """ Checks if the 'value' is within the specified bounds Args: value (float): value to be checked min_value (float): minimum bound max_value (float): maximum bound Returns: bool: whether the value is within the specified bounds""" return min_value <= value <= max_value
def is_within_screen(game_object)
-
Returns: bool: if the game_object is within the screen (can be seen on the screen)
Expand source code
def is_within_screen(game_object): """ Returns: bool: if the game_object is within the screen (can be seen on the screen)""" return (game_object.right_edge > 0 and game_object.left_edge < SCREEN_LENGTH and game_object.bottom_edge > 0 and game_object.top_edge < SCREEN_HEIGHT)
def key_has_been_released(key)
-
Returns: bool: whether the key was held down last cycle and is not this cycle (released)
Expand source code
def key_has_been_released(key): """ Returns: bool: whether the key was held down last cycle and is not this cycle (released)""" return keyboard.get_key_event(key).has_stopped()
def key_is_clicked(key)
-
Returns: bool: whether the key was not held down last cycle and is this cycle (clicked)
Expand source code
def key_is_clicked(key): """ Returns: bool: whether the key was not held down last cycle and is this cycle (clicked)""" return keyboard.get_key_event(key).is_click()
def key_is_pressed(key)
-
Returns: bool: whether that key is currently held down (pressed)
Expand source code
def key_is_pressed(key): """ Returns: bool: whether that key is currently held down (pressed)""" return keyboard.get_key_event(key).happened_this_cycle
def max_value(item1, item2)
-
Returns: float: the biggest item
Expand source code
def max_value(item1, item2): """ Returns: float: the biggest item""" return item1 if item1 > item2 else item2
def min_value(item1, item2)
-
Returns: float: the smallest item
Expand source code
def min_value(item1, item2): """ Returns: float: the smallest item""" if item1 is None: return item2 if item2 is None: return item1 return item1 if item1 < item2 else item2
def modified_mod(number, modulus)
-
This is a modified version of the modulus operator. This performs the same way for negative numbers and positive numbers. This means that 50 % 9 = 5 and -50 % 9 = -5.
Returns: float: the number % modulus that conforms to the rules specified above
Expand source code
def modified_mod(number, modulus): """ This is a modified version of the modulus operator. This performs the same way for negative numbers and positive numbers. This means that 50 % 9 = 5 and -50 % 9 = -5. Returns: float: the number % modulus that conforms to the rules specified above""" number_is_negative = number < 0 value = math.fabs(number) % modulus constant_factor = -1 if number_is_negative else 1 # So the number can be converted back to a negative number # If the decimal is chopped off by converting it into an int and it is still the same value, it must be equal modulus_is_whole_number = modulus == int(modulus) if modulus_is_whole_number: number_decimal = get_decimal_with_full_accuracy(number) int_number = int(number) value = int(math.fabs(int_number)) % modulus value += number_decimal return value * constant_factor # An int should be gotten back
def mouse_is_clicked()
-
Returns: bool: whether the mouse was not pressed last cycle and is this cycle (clicked)
Expand source code
def mouse_is_clicked(): """ Returns: bool: whether the mouse was not pressed last cycle and is this cycle (clicked)""" return keyboard.mouse_clicked_event.is_click()
def rounded(number, places)
-
Returns: float: the number rounded to that many decimal places
Expand source code
def rounded(number, places): """ Returns: float: the number rounded to that many decimal places""" rounded_number = int(number * pow(10, places)) # Converting it back to the proper decimals once it gets rounded from above return rounded_number / pow(10, places)
def solve_quadratic(a, b, c)
-
Returns: list[float]: [answer1, answer2] the answers to the quadratic and if the answer is an imaginary number it returns float('nan')
Expand source code
def solve_quadratic(a, b, c): """ Returns: list[float]: [answer1, answer2] the answers to the quadratic and if the answer is an imaginary number it returns float('nan')""" number_under_square_root = pow(b, 2) - 4 * a * c number_under_square_root = rounded(number_under_square_root, 4) if number_under_square_root < 0: return None square_root = sqrt(number_under_square_root) answer1 = (-b + square_root) / (2 * a) answer2 = (-b - square_root) / (2 * a) answers = [answer2, answer1] # If the answers are the same I should only return one of them return answers if answers[0] != answers[1] else [answers[0]]