class Scene(State): def __init__(self): super(Scene, self).__init__() pygame.mixer.init(44100, -16, 4, 2048) self.all_object_list = pygame.sprite.LayeredUpdates() self.zombie_list = pygame.sprite.Group() self.blood_splash = BloodSplash() self.background = Object() self.player = Player() self.zombie_sprite = [] self.grave_list = [] self.hud = HUD() self.sound_list = dict() self.bg_music = pygame.mixer.music self.game_over = False self.time = pygame.time.get_ticks() def init(self): self.read_scene() # Bring cursor to front self.all_object_list.move_to_front(self.player) # Set background music self.sound_list['background'].play().set_endevent(pygame.constants.USEREVENT) # Scale background to screen size self.background.image = pygame.transform.scale(self.background.image, (SCREEN_WIDTH, SCREEN_HEIGHT)) def process_events(self, event): if event.type == pygame.USEREVENT: self.sound_list['background'].play() elif event.type == pygame.MOUSEBUTTONDOWN: self.sound_list['gunshot'].play() self.process_raycast() elif event.type == pygame.KEYDOWN: if (event.key == pygame.K_p): if self.is_running: self.pause() else: self.resume() def update(self): if (not self.is_running): return # Process game self.process_zombie() # Update all objects self.all_object_list.update(self.hud) self.hud.update() def draw(self, screen): screen.fill(WHITE) self.all_object_list.draw(screen) apply_all(self.zombie_list.sprites(), 'show_timer', screen) self.hud.draw(screen) #--------------------------------------LOGIC PROCESSING SECTION----------------------------------------------- def process_zombie(self): # Randomly choose an interval between 0.5 to 1.5 second to spawn another zombie if (pygame.time.get_ticks() - self.time >= random.randrange(1, 3) * 500): # Random location for zombie zombie_pos = random.randrange(0, len(self.grave_list)) # Check if grave's position already had zombie if (not next((True for zombie in self.zombie_list.sprites() if zombie.pos == zombie_pos), False)): # Randomly pick zombie from zombie sprite list zombie = deepcopy(self.zombie_sprite[random.randrange(0, len(self.zombie_sprite))]) zombie.set_pos(zombie_pos) # Set zombie to the right position zombie.move_to(*self.grave_list[zombie_pos].get_pos()) zombie.translate(35, -10) # Set zombie layer zombie.set_layer(self.grave_list[zombie_pos]._layer - 1) # Add to zombie list and object list self.zombie_list.add(zombie) self.all_object_list.add(zombie) # Reset timer self.time = pygame.time.get_ticks() def process_raycast(self): mouse_pos = pygame.mouse.get_pos() hit_zombie = next((zombie for zombie in self.zombie_list.sprites() if zombie.collide_point(list(map(operator.sub, mouse_pos, zombie.get_pos())))), None) if (hit_zombie is not None): # Play zombie's death sound self.sound_list['dying_scream'].play() # Update hit count self.hud.update_hit() # Splash blood blood = deepcopy(self.blood_splash) blood.move_to(*self.player.get_pos()) blood.set_layer(self.all_object_list.get_top_layer() + 1) blood.show() self.all_object_list.add(blood) hit_zombie.kill() #----------------------------------------READ FILE SECTION----------------------------------------------------- def read_scene(self): with open(ResourceManager.scene_path_list[0]) as file: self.read_hud(file) self.read_background(file) self.read_player(file) self.read_grave(file) self.read_zombie(file) self.read_blood_splash(file) self.read_sound(file) def read_hud(self, file): file.readline() hud_id = int(file.readline().strip().split(' ')[1]) self.hud.init(ResourceManager.hud_path_list[hud_id]) def read_background(self, file): file.readline() image_id = int(file.readline().strip().split(' ')[1]) self.background.init('Image', file_name = ResourceManager.image_path_list[image_id]) self.all_object_list.add(self.background) def read_player(self, file): file.readline() image_id = int(file.readline().strip().split(' ')[1]) self.player.init('Image', file_name = ResourceManager.image_path_list[image_id], alpha = True) self.player.translate(*map(int, file.readline().strip().split(' ')[1:])) self.player.rotate(float(file.readline().strip().split(' ')[1])) self.player.scale(*map(float, file.readline().strip().split(' ')[1:])) self.all_object_list.add(self.player) def read_grave(self, file): file.readline() image_id = int(file.readline().strip().split(' ')[1]) grave = Object() grave.init('Image', file_name = ResourceManager.image_path_list[image_id], alpha = True) grave.translate(*map(int, file.readline().strip().split(' ')[1:])) grave.rotate(float(file.readline().strip().split(' ')[1])) grave.scale(*map(float, file.readline().strip().split(' ')[1:])) for i in range(3): for j in range(3): self.grave_list.append(deepcopy(grave)) self.grave_list[-1].translate(200 * j, 100 * i) self.grave_list[-1].set_layer(2 * (i + 1)) self.all_object_list.add(self.grave_list) def read_zombie(self, file): zombie_num = int(file.readline().strip().split(' ')[1]) for i in range(zombie_num): image_id = int(file.readline().strip().split(' ')[1]) self.zombie_sprite.append(Zombie()) self.zombie_sprite[-1].init('Image', file_name = ResourceManager.image_path_list[image_id], alpha = True) self.zombie_sprite[-1].translate(*map(int, file.readline().strip().split(' ')[1:])) self.zombie_sprite[-1].rotate(float(file.readline().strip().split(' ')[1])) self.zombie_sprite[-1].scale(*map(float, file.readline().strip().split(' ')[1:])) def read_blood_splash(self, file): file.readline() blood_id = int(file.readline().strip().split(' ')[1]) self.blood_splash.init('Image', file_name = ResourceManager.image_path_list[blood_id], alpha = True) self.blood_splash.translate(*map(int, file.readline().strip().split(' ')[1:])) self.blood_splash.rotate(float(file.readline().strip().split(' ')[1])) self.blood_splash.scale(*map(float, file.readline().strip().split(' ')[1:])) 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.sound_path_list[sound_id]) self.sound_list.update({sound_type: sound})