import math import pygame import entity_classes as ce import Auxiliary_Functionalities as Af M_C = 0.8 # mutation chance game_over_sound = Af.load_sound( "game/game_over.WAV") # sound of the match ending def normalize(max_value, min_value, value): return (value - min_value) / (max_value - min_value) def activation_function(value): return 1 / (1 + math.e**(-value)) def mutate_value(value, mutation_chance=M_C): if Af.random() > mutation_chance: # invert value's signal value *= Af.random_choice([-1, 1]) if Af.random() > mutation_chance: # increase or decrease value value += Af.random_choice( [-1, 1]) * (Af.random() / Af.random_choice([1000, 100, 10])) if Af.random() > M_C: return Af.random_choice( [-1, 1]) * (Af.random() / Af.random_choice([100, 10])) return value # Creates a world where the AI can be trained
class Lightning: internal_beam_color = (0, 255, 255) external_beam_color = (0, 0, 255) starting_point_coo = (95, 150) frame = 0 space_time_hit_sound = Af.load_sound( "game/space_time_hit.WAV") # sound of the space-time entity hitting segments_coo = () def __init__(self): self.segment_number = None # how many segments the lightning has self.internal_beam_radius = None # radius of the central part of the beam self.external_beam_radius = None # radius of the external part of the beam self.last_segment_direction = None # last segment goes up or down alternatively self.change_properties() # gives new valid values to the attributes def change_properties(self): self.segment_number = Af.randint(5, 7) self.internal_beam_radius = 2 * self.segment_number self.external_beam_radius = Af.get_fibonacci(self.segment_number) self.frame = 0 self.segments_coo = [self.starting_point_coo] self.last_segment_direction = Af.choice([-1, 1]) def add_segment(self, car_x, car_y): if self.frame == self.segment_number: # last segment is always the car's position self.segments_coo.append((car_x, car_y)) return None medium_segment_length = (car_x - self.segments_coo[0][0] ) // self.segment_number # (Xf-Xi)/ n segment_x = self.segments_coo[-1][0] + Af.randint( int(medium_segment_length * 0.75), medium_segment_length) segment_y = self.segments_coo[-1][1] + Af.randint( 10, 70) * self.last_segment_direction self.last_segment_direction *= -1 # invert next segment direction self.segments_coo.append((segment_x, segment_y)) def draw_segments(self, screen): starting_point = self.starting_point_coo for adjust, ending_point in enumerate(self.segments_coo): central_segment_width = int(self.internal_beam_radius * (1 - adjust / self.segment_number)) + 4 pygame.draw.line(screen, self.internal_beam_color, starting_point, ending_point, central_segment_width) pygame.draw.line(screen, (255, 255, 255), starting_point, ending_point, 2) external_beam_width = (self.segment_number - adjust) // 2 + 1 upper_coo_start = (starting_point[0], starting_point[1] - central_segment_width // 2) upper_coo_ending = (ending_point[0], ending_point[1] - central_segment_width // 2) pygame.draw.line(screen, self.external_beam_color, upper_coo_start, upper_coo_ending, external_beam_width) lower_coo_start = (starting_point[0], starting_point[1] + central_segment_width // 2) lower_coo_ending = (ending_point[0], ending_point[1] + central_segment_width // 2) pygame.draw.line(screen, self.external_beam_color, lower_coo_start, lower_coo_ending, external_beam_width) starting_point = ending_point # make next segment start where last one ended def draw(self, screen, car_x, car_y): if self.frame == 0: Af.play(self.space_time_hit_sound) if car_x > Af.CAR_STE_MIN_DAMAGE_DISTANCE: # lightning should not hit car if car is too far car_x = Af.CAR_STE_MIN_DAMAGE_DISTANCE car_y += 25 # adjust y coordinate to match car center car_x += 25 # adjust y coordinate to match car center self.frame += 1 self.add_segment(car_x, car_y) # create a new segment of the lightning self.draw_segments(screen) # draw all segments if self.frame == self.segment_number: # lightning has been fully drawn self.change_properties() return False return True
# This module contains two classes. This classes are responsible for managing the game's graphics,input and output (HUD) # They are both similar and most of the things they do are the same. They only differ in duration and returned values. # They utilize classes of the "entity_classes" module. This way we can think about both of them like an interaction # management system for the game's entities (dictating rules, changing attributes based on certain events, etc.) # ----------------------------------------------- IMPORTS -------------------------------------------------------------- import entity_classes as ce import pygame import Auxiliary_Functionalities as Af # ----------------------------------------------- SOUNDS --------------------------------------------------------------- go_sound = Af.load_sound("game/car_ignition.WAV") # sound of after the final count down alert (GO) count_down_sound = Af.load_sound("game/count_down.WAV") # sound of the usual count down (3, 2, 1) tic_toc_sound = Af.load_sound("game/tic_toc.WAV") # sound of the final clock ticking game_over_sound = Af.load_sound("game/game_over.WAV") # sound of the match ending start_sound = Af.load_sound("game/go.WAV") # sound of the GO image wrong_letter_sound = Af.load_sound("game/letter_wrong.WAV") # sound of the user typing a character wrong # ----------------------------------------------- CLASSES -------------------------------------------------------------- # Parent Class for managing a Mission-Type World class Mission: def __init__(self, screen): self.screen = screen self.background = Af.load_image("HUD/HUD_background.png") # Game objects self.sp_ti_entity = ce.Space_Time_Entity() self.car = ce.Car() self.road = ce.Road() self.obstacles_list = ce.Obstacles() self.parts_list = ce.Parts() self.parts_collected = 0
# This module contains all the classes that are used in the game classes in order to make the game work. # Everything that needs to appear in the game is an instance of these classes. # for those entities that need to appear multiple times, can be of different kinds or comes and goes from the screen, # there is a class that represents a group of these instances, and can be differentiated from the normal classes by # looking if his name is plural # ---------------------------------------------------- IMPORTS --------------------------------------------------------- import pygame import Auxiliary_Functionalities as Af # ---------------------------------------------------- SOUNDS ---------------------------------------------------------- fire_sound = Af.load_sound("game/level failed.WAV") part_sound = Af.load_sound("game/part_collection.WAV") hit_sound = Af.load_sound("game/impact.WAV") # ----------------------------------------------- GLOBAL VARIABLES ----------------------------------------------------- obstacles_distance = 290 parts_distance = 5 space_between_obstacles = [o for o in range(300, 1290, obstacles_distance)] # ----------------------------------------------------- CAR ------------------------------------------------------------ class Car: def __init__(self): self.y_values = [20, 121, 240] self.middle = (self.y_values[1] - 1, self.y_values[1], self.y_values[1] - 1 ) # +-1 error when checking if centered self.image = self.get_car_image() self.fire_image = None self.fire_image_time = 0
# This module contains all the functions called by the main module. # All the functions take the screen where the images are going to be displayed as a parameter # For each of the functions there is a correspondent class that manages the functionality of the function # Each function in this module returns values that correspond to the functionality that the game should open next # A function's comment in this module has a description and the functions it can lead to when it finishes # This module is divided in categories like: --- CATEGORY NAME --- ; in order to make it more understandable # -------------------------------------------- IMPORTS ----------------------------------------------------------------- import menu_classes as mc import game_classes as gc import Auxiliary_Functionalities as Af # -------------------------------------------- SOUNDS ------------------------------------------------------------------ change_menu_sound = Af.load_sound( "menu/change_menu.WAV") # sound for when a user enters a new menu delete_account_sound = Af.load_sound( "menu/delete_account.WAV") # sound for deleting account enter_password_sound = Af.load_sound( "menu/enter_password.WAV" ) # sound for when a password verification is required exit_sound = Af.load_sound( "menu/exit.WAV") # sound for when the user wants to exit or logout start_sound = Af.load_sound( "menu/ignition.WAV") # sound for when the game is executed # ------------------------------------------ GAME START ---------------------------------------------------------------- # this is the first interface the user sees when he opens the game def start_page(screen: Af.Surface): start = mc.Start(screen) Af.play(start_sound)