def __init__(self, file_path): super(Scene, self).__init__() pygame.mixer.init(44100, -16, 4, 2048) self.position = ['goalkeeper', 'defender', 'midfielder', 'attacker'] self.all_object_list = pygame.sprite.LayeredUpdates() self.selection_circle = [] # Prototype self.left_player = Player() # Prototype self.right_player = Player() # Prototype self.teams = collections.defaultdict(dict) self.field = Object() self.field_border = Object() self.goal = [] self.ball = Ball() self.hud = HUD() self.goal_image = EffectObject() self.formation = {Team_side.LEFT: [1, 4, 3, 3], Team_side.RIGHT: [1, 4, 4, 2]} self.sound_list = dict() # Game config self.game_mode = Game_mode.PvP self.P1_controlled_team = Team_side.LEFT self.P1_controlled_position = 'midfielder' self.P2_controlled_team = Team_side.RIGHT self.P2_controlled_position = 'midfielder' # Load scene's resources self.read_scene(file_path)
class Scene(State): def __init__(self, file_path): super(Scene, self).__init__() pygame.mixer.init(44100, -16, 4, 2048) self.position = ['goalkeeper', 'defender', 'midfielder', 'attacker'] self.all_object_list = pygame.sprite.LayeredUpdates() self.selection_circle = [] # Prototype self.left_player = Player() # Prototype self.right_player = Player() # Prototype self.teams = collections.defaultdict(dict) self.field = Object() self.field_border = Object() self.goal = [] self.ball = Ball() self.hud = HUD() self.goal_image = EffectObject() self.formation = {Team_side.LEFT: [1, 4, 3, 3], Team_side.RIGHT: [1, 4, 4, 2]} self.sound_list = dict() # Game config self.game_mode = Game_mode.PvP self.P1_controlled_team = Team_side.LEFT self.P1_controlled_position = 'midfielder' self.P2_controlled_team = Team_side.RIGHT self.P2_controlled_position = 'midfielder' # Load scene's resources self.read_scene(file_path) def init(self): # Set teams info # Left team self.game_mode = self.get_shared_var('mode') self.formation[self.P1_controlled_team] = self.get_shared_var('P1_formation') team1_id = self.get_shared_var('P1_team_ID') self.hud.set_left_team_name(Team_name[team1_id]) self.left_player.setImage(ResourceManager.instance().image_path_list[56 + team1_id]) # Right team self.formation[self.P2_controlled_team] = self.get_shared_var('P2_formation') team2_id = self.get_shared_var('P2_team_ID') self.hud.set_right_team_name(Team_name[team2_id]) self.right_player.setImage(ResourceManager.instance().image_path_list[56 + team2_id]) # Calculate players and ball position self.calculate_position() # Set controlled team self.controlled_team = Team_side.LEFT # Randomize ball direction self.ball.set_angle(random.randrange(0, 360, 20)) # Game control self.game_over = False self.match_state = Match_state.KICKOFF self.match_time = 120000 self.time = self.match_time # Reset score self.hud.reset_score() # Set background music pygame.mixer.stop() self.sound_list['background'].play().set_endevent(pygame.constants.USEREVENT) def process_key_press(self, key): if key[pygame.K_w]: apply_all(self.teams[self.P1_controlled_team][self.P1_controlled_position], 'move_up') if key[pygame.K_s]: apply_all(self.teams[self.P1_controlled_team][self.P1_controlled_position], 'move_down') if key[pygame.K_UP]: apply_all(self.teams[self.P2_controlled_team][self.P2_controlled_position], 'move_up') if key[pygame.K_DOWN]: apply_all(self.teams[self.P2_controlled_team][self.P2_controlled_position], 'move_down') def process_events(self, event): if event.type == pygame.USEREVENT: self.sound_list['background'].play() elif event.type == pygame.MOUSEBUTTONDOWN: return '' elif event.type == pygame.KEYDOWN: if event.key == pygame.K_ESCAPE: if self.is_running: self.pause() else: self.resume() elif event.key == pygame.K_a: apply_all(self.teams[self.P1_controlled_team][self.P1_controlled_position], 'stop') self.P1_controlled_position = self.position[max(0, self.position.index(self.P1_controlled_position) - 1)] elif event.key == pygame.K_d: apply_all(self.teams[self.P1_controlled_team][self.P1_controlled_position], 'stop') self.P1_controlled_position = self.position[min(3, self.position.index(self.P1_controlled_position) + 1)] elif event.key == pygame.K_LEFT: apply_all(self.teams[self.P2_controlled_team][self.P2_controlled_position], 'stop') self.P2_controlled_position = self.position[min(3, self.position.index(self.P2_controlled_position) + 1)] elif event.key == pygame.K_RIGHT: apply_all(self.teams[self.P2_controlled_team][self.P2_controlled_position], 'stop') self.P2_controlled_position = self.position[max(0, self.position.index(self.P2_controlled_position) - 1)] elif event.type == pygame.KEYUP: if event.key == pygame.K_w or event.key == pygame.K_s: apply_all(self.teams[self.P1_controlled_team][self.P1_controlled_position], 'stop') elif event.key == pygame.K_UP or event.key == pygame.K_DOWN: if self.game_mode is Game_mode.PvP: apply_all(self.teams[self.P2_controlled_team][self.P2_controlled_position], 'stop') def update(self): if (not self.is_running): return if self.match_state == Match_state.KICKOFF: self.sound_list['whistle'].play() pygame.time.delay(1500) self.match_state = Match_state.PLAYING elif self.match_state == Match_state.PLAYING: # Logic processing self.time -= 1000 / 60 if self.time <= 0.0: self.match_state = Match_state.KICKOFF self.reset_game() self.hud.set_time(int(self.time)) self.process_ball() elif self.match_state == Match_state.GOAL: goal_image = self.goal_image.clone() goal_image.set_appear_time(500) goal_image.show() self.all_object_list.add(goal_image) self.match_state = Match_state.KICKOFF self.reset_game() # Update all objects self.all_object_list.update() self.hud.update() def draw(self, screen): screen.fill(BLACK) self.all_object_list.draw(screen) apply_all(self.teams[self.P1_controlled_team][self.P1_controlled_position], 'show_selection_circle', screen) if self.game_mode is Game_mode.PvP: apply_all(self.teams[self.P2_controlled_team][self.P2_controlled_position], 'show_selection_circle', screen) self.hud.draw(screen) def reset_game(self): self.calculate_position() self.match_state = Match_state.KICKOFF #--------------------------------------LOGIC PROCESSING SECTION----------------------------------------------- def process_ball(self): # Check if hit goals if (pygame.sprite.collide_mask(self.ball, self.goal[0])) is not None: self.sound_list['goal'].play() self.hud.update_right_score() self.match_state = Match_state.GOAL return elif pygame.sprite.collide_mask(self.ball, self.goal[1]) is not None: self.sound_list['goal'].play() self.hud.update_left_score() self.match_state = Match_state.GOAL return # Check if hit field's border self.process_collide_border() # Check if hit players player_list = [players for sublist in (list(self.teams[Team_side.LEFT].values()) + list(self.teams[Team_side.RIGHT].values())) for players in sublist] hit_player = pygame.sprite.spritecollideany(self.ball, player_list, pygame.sprite.collide_circle) if hit_player is not None: self.sound_list['ball_kick'].play() self.ball.collide_object(hit_player) # Process AI list(chain(*self.teams[Team_side.LEFT].values())) """for position in self.teams[Team_side.RIGHT].keys(): action = 'move_up' if random.randrange(0, 2) is 0 else 'move_down' apply_all(self.teams[Team_side.RIGHT][position], action)""" def process_collide_border(self): """Check if ball touch field's border and calculate rebound direction """ ball_pos = self.ball.get_pos() if ball_pos[0] < 50: self.ball.move_to(51, self.ball.get_pos()[1]) self.ball.toggle_x_vel() elif (ball_pos[0] + self.ball.get_width()) > SCREEN_WIDTH - 50: self.ball.move_to(SCREEN_WIDTH - 51 - self.ball.get_width(), self.ball.get_pos()[1]) self.ball.toggle_x_vel() elif ball_pos[1] < 20: self.ball.move_to(self.ball.get_pos()[0], 21) self.ball.toggle_y_vel() elif (ball_pos[1] + self.ball.get_height()) > SCREEN_HEIGHT - 20: self.ball.move_to(self.ball.get_pos()[0], SCREEN_HEIGHT - 21 - self.ball.get_height()) self.ball.toggle_y_vel() def calculate_position(self): """Calculate and move ball and players to the right position """ # Calculate ball postion x = (SCREEN_WIDTH - self.ball.get_width()) // 2 y = (SCREEN_HEIGHT - 8 - self.ball.get_height()) // 2 self.ball.move_to(x, y) # Generate and calculate red team players for i in range(len(self.formation[Team_side.LEFT])): if len(self.teams[Team_side.LEFT]) == 4: apply_all(self.teams[Team_side.LEFT][self.position[i]], 'kill') self.teams[Team_side.LEFT].update({self.position[i]: []}) # Calculate offset x_offset = 100 y_offset = (self.field.get_height() - 8 - self.left_player.get_height() * self.formation[Team_side.LEFT][i]) // (self.formation[Team_side.LEFT][i] + 1) for j in range(self.formation[Team_side.LEFT][i]): # Calculate position x = self.left_player.get_pos()[0] + (x_offset * (i ** 1.69)) y = y_offset * (j + 1) + self.left_player.get_height() * j + 4 self.teams[Team_side.LEFT][self.position[i]].append(self.left_player.clone()) self.teams[Team_side.LEFT][self.position[i]][j].move_to(x, y) self.teams[Team_side.LEFT][self.position[i]][-1].set_layer(1) self.teams[Team_side.LEFT][self.position[i]][-1].set_radius() self.teams[Team_side.LEFT][self.position[i]][j].set_max_offset(y_offset - 20) self.all_object_list.add(self.teams[Team_side.LEFT][self.position[i]][-1]) # Generate and calculate blue team players for i in range(len(self.formation[Team_side.RIGHT])): if len(self.teams[Team_side.RIGHT]) == 4: apply_all(self.teams[Team_side.RIGHT][self.position[i]], 'kill') self.teams[Team_side.RIGHT].update({self.position[i]: []}) # Calculate offset x_offset = 100 y_offset = (self.field.get_height() - 8 - self.right_player.get_height() * self.formation[Team_side.RIGHT][i]) // (self.formation[Team_side.RIGHT][i] + 1) for j in range(self.formation[Team_side.RIGHT][i]): # Calculate position x = self.right_player.get_pos()[0] - (x_offset * (i ** 1.69)) y = y_offset * (j + 1) + self.right_player.get_height() * j + 4 self.teams[Team_side.RIGHT][self.position[i]].append(self.right_player.clone()) self.teams[Team_side.RIGHT][self.position[i]][j].move_to(x, y) self.teams[Team_side.RIGHT][self.position[i]][-1].set_layer(1) self.teams[Team_side.RIGHT][self.position[i]][-1].set_radius() self.teams[Team_side.RIGHT][self.position[i]][j].set_max_offset(y_offset - 20) self.all_object_list.add(self.teams[Team_side.RIGHT][self.position[i]][-1]) # Assign selection_circle to each player # Left team for player in [players for sublist in list(self.teams[Team_side.LEFT].values()) for players in sublist]: player.selection_circle = self.selection_circle[0].clone() # Right team for player in [players for sublist in list(self.teams[Team_side.RIGHT].values()) for players in sublist]: player.selection_circle = self.selection_circle[1].clone() #----------------------------------------READ FILE SECTION----------------------------------------------------- def read_scene(self, file_path): with open(file_path) as file: self.read_hud(file) self.read_field(file) self.read_red_team(file) self.read_blue_team(file) self.read_selection_circle(file) self.read_ball(file) self.read_effect(file) self.read_sound(file) def read_hud(self, file): file.readline() hud_id = int(file.readline().strip().split(' ')[1]) self.hud.init(ResourceManager.instance().hud_path_list[hud_id]) def read_field(self, file): # Read field file.readline() image_id = int(file.readline().strip().split(' ')[1]) self.field.init('Image', file_name = ResourceManager.instance().image_path_list[image_id]) self.field.scale_to(SCREEN_WIDTH, SCREEN_HEIGHT) self.all_object_list.add(self.field) # Read goal file.readline() image_id_1, image_id_2 = list(map(int, file.readline().strip().split(' ')[1:])) self.goal.append(Object()) self.goal[-1].init('Image', file_name = ResourceManager.instance().image_path_list[image_id_1]) self.goal[-1].scale_to(SCREEN_WIDTH, SCREEN_HEIGHT) self.goal[-1].set_layer(-1) self.goal.append(Object()) self.goal[-1].init('Image', file_name = ResourceManager.instance().image_path_list[image_id_2]) self.goal[-1].scale_to(SCREEN_WIDTH, SCREEN_HEIGHT) self.goal[-1].set_layer(-1) self.all_object_list.add(self.goal) def read_red_team(self, file): self.teams[Team_side.LEFT] = dict() file.readline() image_id = int(file.readline().strip().split(' ')[1]) # Prototype self.left_player.init('Image', file_name = ResourceManager.instance().image_path_list[image_id]) self.left_player.rotate(float(file.readline().strip().split(' ')[1])) self.left_player.scale(*map(float, file.readline().strip().split(' ')[1:])) self.left_player.translate(*map(int, file.readline().strip().split(' ')[1:])) def read_blue_team(self, file): self.teams[Team_side.RIGHT] = dict() file.readline() image_id = int(file.readline().strip().split(' ')[1]) # Prototype self.right_player.init('Image', file_name = ResourceManager.instance().image_path_list[image_id]) self.right_player.rotate(float(file.readline().strip().split(' ')[1])) self.right_player.scale(*map(float, file.readline().strip().split(' ')[1:])) self.right_player.translate(*map(int, file.readline().strip().split(' ')[1:])) def read_selection_circle(self, file): file.readline() image_id = list(map(int, (file.readline().strip().split(' ')[1:]))) image_id_green = image_id[0] image_id_red = image_id[1] # Green circle self.selection_circle.append(Object()) self.selection_circle[-1].init('Image', file_name = ResourceManager.instance().image_path_list[image_id_green], alpha = True) self.selection_circle[-1].rotate(float(file.readline().strip().split(' ')[1])) self.selection_circle[-1].scale(*map(float, file.readline().strip().split(' ')[1:])) self.selection_circle[-1].translate(*map(int, file.readline().strip().split(' ')[1:])) # Red circle self.selection_circle.append(self.selection_circle[-1].clone()) self.selection_circle[-1].setImage(ResourceManager.instance().image_path_list[image_id_red]) def read_ball(self, file): file.readline() image_id = int(file.readline().strip().split(' ')[1]) self.ball.init('Image', file_name = ResourceManager.instance().image_path_list[image_id], alpha = True) self.ball.rotate(float(file.readline().strip().split(' ')[1])) self.ball.scale(*map(float, file.readline().strip().split(' ')[1:])) self.ball.translate(*map(int, file.readline().strip().split(' ')[1:])) self.ball.set_radius() self.all_object_list.add(self.ball) def read_effect(self, file): file.readline() image_id = int(file.readline().strip().split(' ')[1]) self.goal_image.init('Image', file_name = ResourceManager.instance().image_path_list[image_id], alpha = True) self.goal_image.rotate(float(file.readline().strip().split(' ')[1])) self.goal_image.scale(*map(float, file.readline().strip().split(' ')[1:])) self.goal_image.translate(*map(int, file.readline().strip().split(' ')[1:])) self.goal_image.set_layer(5) def read_sound(self, file): sound_num = int(file.readline().strip().split(' ')[1]) for i in range(sound_num): sound_type = file.readline().strip().replace('#', '') sound_id = int(file.readline().strip().split(' ')[1]) sound = pygame.mixer.Sound(ResourceManager.instance().sound_path_list[sound_id]) self.sound_list.update({sound_type: sound})