def sel_unit_move(self, pos): """ Move the selected unit to the given position. """ # Change the game state to show that there was a movement. self.change_mode(Modes.Moving) # Mark that the unit has moved self.sel_unit.turn_state[0] = True #the tile position the unit is at from_tile_pos = (self.sel_unit.tile_x, self.sel_unit.tile_y) # Play the unit's movement sound SoundManager.play(self.sel_unit.move_sound) # These will be used in pathfinding cost = lambda c: (self.sel_unit.move_cost(self.map.tile_data(c))) passable = lambda c: (self.sel_unit.is_passable( self.map.tile_data(c), c)) #set the path in the unit. self.sel_unit.set_path( tiles.find_path(self.map, from_tile_pos, pos, cost, passable))
class Client: def __init__(self, gui) -> None: self.gui = gui self.sounds = SoundManager(self) self.state = CSGOState(self) async def update_status(self) -> None: with self.state.lock: if self.state.old_state is None: self.gui.SetStatusText("Waiting for CS:GO...") elif self.state.old_state.is_ingame: phase = self.state.old_state.phase if phase == "unknown": phase = "" else: phase = " (%s)" % phase self.gui.SetStatusText( f"Round {self.state.old_state.current_round}{phase}" ) else: self.gui.SetStatusText("Not in a match.") async def reload_sounds(self) -> None: """Reloads all sounds. Do not call outside of gui, unless you disable the update sounds button first. """ await self.sounds.reload() await self.update_status() self.gui.updateSoundsBtn.Enable() self.sounds.play("Round start")
def sel_unit_move(self, pos): """ Move the selected unit to the given position. """ # Change the game state to show that there was a movement. self.change_mode(Modes.Moving) # Implements animation for movement of unit if it exists (teleport unit spawns a warp) if self.sel_unit.move_animation: self._effects.add( self.sel_unit.move_animation(self.map.screen_coords(pos))) # Mark that the unit has moved self.sel_unit.turn_state[0] = True #the tile position the unit is at from_tile_pos = (self.sel_unit.tile_x, self.sel_unit.tile_y) # Play the unit's movement sound SoundManager.play(self.sel_unit.move_sound) # These will be used in pathfinding cost = lambda c: (self.sel_unit.move_cost(self.map.tile_data(c))) passable = lambda c: (self.sel_unit.is_passable( self.map.tile_data(c), c)) #set the path in the unit. self.sel_unit.set_path( tiles.find_path(self.map, from_tile_pos, pos, cost, passable))
def sel_unit_move(self, pos): """ Move the selected unit to the given position. """ # Change the game state to show that there was a movement. self.change_mode(Modes.Moving) # Mark that the unit has moved self.sel_unit.turn_state[0] = True #the tile position the unit is at from_tile_pos = (self.sel_unit.tile_x, self.sel_unit.tile_y) # Play the unit's movement sound SoundManager.play(self.sel_unit.move_sound) # These will be used in pathfinding cost = lambda c: ( self.sel_unit.move_cost(self.map.tile_data(c))) passable = lambda c: ( self.sel_unit.is_passable(self.map.tile_data(c), c)) #set the path in the unit. self.sel_unit.set_path( tiles.find_path( self.map, from_tile_pos, pos, cost, passable))
def on_click(self, e): """ This is called when a click event occurs. e is the click event. """ # Don't react when in move, attack or game over mode. if (self.mode == Modes.Moving or self.mode == Modes.GameOver): return # make sure we have focus and that it was the left mouse button if (e.type == pygame.MOUSEBUTTONUP and e.button == 1 and pygame.mouse.get_focused()): # If this is in the map, we're dealing with units or tiles if self.map.rect.collidepoint(e.pos): # Get the tile's position to_tile_pos = self.map.tile_coords(e.pos) # get the unit at the mouseclick unit = self.get_unit_at_screen_pos(e.pos) if unit: # clicking the same unit again deselects it and, if # necessary, resets select mode if unit == self.sel_unit: self.change_mode(Modes.Select) self.sel_unit = None # select a new unit elif (self.mode == Modes.Select and unit.team == self.cur_team): self.sel_unit = unit SoundManager.play(SELECT_SOUND) # Attack elif (self.mode == Modes.ChooseAttack and self.sel_unit and to_tile_pos in self._attackable_tiles): # Attack the selected tile self.sel_unit_attack(to_tile_pos) else: # No unit there, so a tile was clicked if (self.mode == Modes.ChooseMove and self.sel_unit and to_tile_pos in self._movable_tiles): # Move to the selected tile self.sel_unit_move(to_tile_pos) # Otherwise, the user is interacting with the GUI panel else: # Check which button was pressed for button in self.buttons: # If the button is enabled and has a click function, call # the function if ((not button.condition or button.condition()) and self.get_button_rect(button).collidepoint(e.pos)): button.onClick() # Play the button sound SoundManager.play(BUTTON_SOUND)
def sel_unit_attack(self, pos): """ Attack the given position using the selected unit. """ # Change the game state to show that there was an attack. self.change_mode(Modes.Select) # Mark that the unit has attacked. self.sel_unit.turn_state[1] = True # Face the attackee self.sel_unit.face_vector(( pos[0] - self.sel_unit.tile_x, pos[1] - self.sel_unit.tile_y)) # Get info about the attackee atk_unit = unit.base_unit.BaseUnit.get_unit_at_pos(pos) atk_tile = self.map.tile_data(pos) # Calculate the damage damage = self.sel_unit.get_damage(atk_unit, atk_tile) damage += random.choice([-1, -1, 0, 0, 0, 0, 0, 1, 1, 2]) damage = max(damage, 0) # Deal damage atk_unit.hurt(damage) # Do the attack effect. if self.sel_unit.hit_effect: self._effects.add(self.sel_unit.hit_effect( self.map.screen_coords(pos))) # Play the unit's attack sound if self.sel_unit.hit_sound: SoundManager.play(self.sel_unit.hit_sound) if not atk_unit.active: # Add its death effect if atk_unit.die_effect: self._effects.add(atk_unit.die_effect( self.map.screen_coords(pos))) # Play its death sound if atk_unit.die_sound: SoundManager.play(atk_unit.die_sound) # If the unit was destroyed, check if there are any others # left on a team other than the selected unit for u in unit.base_unit.BaseUnit.active_units: if u.team != self.sel_unit.team: return # No other units, so game over! self.win_team = self.sel_unit.team self.mode = Modes.GameOver
class LevelTransition: TRANSITION_CHANNEL = 4 def __init__(self, screen, score_controller, transition_time=5000): self.screen = screen self.score_controller = score_controller self.sound = SoundManager(['pacman_beginning.wav'], keys=['transition'], channel=LevelTransition.TRANSITION_CHANNEL, volume=0.6) self.score_font = pygame.font.Font('fonts/emulogic.ttf', 24) ready_pos = screen.get_width() // 2, int(screen.get_height() * 0.65) self.level_msg = None self.level_msg_rect = None self.transition_time = transition_time # total time to wait until the transition ends self.transition_begin = None self.transition_show = False def prep_level_msg(self): text = 'level ' + str(self.score_controller.level) self.level_msg = self.score_font.render(text, True, ScoreBoard.SCORE_WHITE) self.level_msg_rect = self.level_msg.get_rect() level_pos = self.screen.get_width() // 2, self.screen.get_height() // 2 self.level_msg_rect.centerx, self.level_msg_rect.centery = level_pos def set_show_transition(self): self.prep_level_msg() self.transition_begin = pygame.time.get_ticks() self.transition_show = True self.sound.play('transition') def draw(self): if abs(self.transition_begin - pygame.time.get_ticks()) > self.transition_time: self.transition_show = False else: self.screen.fill((0, 0, 0)) self.screen.blit(self.level_msg, self.level_msg_rect)
class Game(): def __init__(self): # definir si le jeu a commence ou non self.is_playing = False self.player = Player(self) # Generer joueur self.all_player = pygame.sprite.Group() self.all_player.add(self.player) self.all_monster = pygame.sprite.Group() # groupe de monstre self.sound_manager = SoundManager() self.comet_event = CometFallEvent(self) self.font = pygame.font.Font("./assets/PottaOne.ttf", 20) self.score = 0 self.pressed = {} def start(self): self.is_playing = True self.spawn_monster(Mummy) self.spawn_monster(Mummy) self.spawn_monster(Alien) def spawn_monster(self, monster_name): self.all_monster.add(monster_name.__call__(self)) def check_collision(self, sprite, group): return pygame.sprite.spritecollide(sprite, group, False, pygame.sprite.collide_mask) def add_score(self, points=10): # ajouter le nbr ptn au score self.score += points def game_over(self): # remettre le jeu a neuf et en attente self.all_monster = pygame.sprite.Group() self.comet_event.all_comet = pygame.sprite.Group() self.comet_event.reset_percent() self.player.health = self.player.max_health self.is_playing = False self.score = 0 # jouer le son self.sound_manager.play("game_over") def update(self, screen): # afficher le score sur l'ecran score_text = self.font.render(f"Score : {self.score}", 1, (0, 0, 0)) screen.blit(score_text, (20, 20)) # Afficher l'image du joueur screen.blit(self.player.image, self.player.rect) # Acualiser la barre de vie du joueur self.player.update_health_bar(screen) # Actualiser l'animation du joueur self.player.update_animation() # Actualiser la barre d'event du jeu self.comet_event.update_bar(screen) # recuperer les projectile du joueur for projectile in self.player.all_projectile: projectile.move() # Recuperer les monstres du jeu for monster in self.all_monster: monster.forward() monster.update_health_bar(screen) monster.update_animation() # Recuperer les comets de notre jeu for comet in self.comet_event.all_comet: comet.fall() # appliquer les images du groupe projectile self.player.all_projectile.draw(screen) # appliquer les images du groupe monstre self.all_monster.draw(screen) # appliquer le groupe des comets self.comet_event.all_comet.draw(screen) # mouvement du joueur a droite ou gauche if self.pressed.get( pygame.K_RIGHT ) and self.player.rect.x + self.player.rect.width < screen.get_width(): self.player.move_right() elif self.pressed.get(pygame.K_LEFT) and self.player.rect.x > 0: self.player.move_left()
class Game: def __init__(self, screen_width, screen_height): #le jeu a commencé T/F self.is_playing = False #taille de l'ecran de jeu self.screen_width = screen_width self.screen_height = screen_height #groupe de monstre self.all_monsters = pygame.sprite.Group() #générer l'evenement self.comet_event = CometFallEvent(self) #touche pressee self.pressed = {} #score à 0 self.score = 0 #afficher le score sur l'écran self.font = pygame.font.Font("assets/myfont.ttf", 30) #gerer le son self.sound_manager = SoundManager() def start(self): """lance le jeu et les monstres""" self.is_playing = True self.spawn_monster(Mummy) self.spawn_monster(Mummy) self.spawn_monster(Alien) #le joueur dans un groupe self.all_players = pygame.sprite.Group() #generer notre joueur self.player = Player(self) #ajoute le joueur au groupe self.all_players.add(self.player) def add_score(self, points=10): """ajout de points """ self.score += points def game_over(self): """ arret du jeu """ #groupe de monstre vide self.all_monsters = pygame.sprite.Group() #groupe de comètes vide self.comet_event.all_comets = pygame.sprite.Group() #vie du joueur self.player.health = self.player.max_health #jauge d'événement à 0 self.comet_event.reset_percent() self.is_playing = False #remise à 0 du score self.score = 0 #son game over self.sound_manager.play('game_over') def update(self, screen): """mise à jour des evevenements """ score_text = self.font.render(f"Score : {self.score}", 1, (0, 0, 0)) screen.blit(score_text, (20, 20)) #appliquer l'image de mon joueur screen.blit(self.player.image, self.player.rect) #actualise la barre de vie du joueur self.player.update_health_bar(screen) #actualise la barre d'évènement du jeu self.comet_event.update_bar(screen) #actualiser l'animation du joeur self.player.update_animation() #boucle sur les projectiles for projectile in self.player.all_projectiles: #lance projectile projectile.move(screen.get_width()) #boucle sur les monstres for monster in self.all_monsters: #fait avancer les monstres monster.forward() #affiche bar de vie monster.update_health_bar(screen) #anime le monstre monster.update_animation() #appliquer le projectile sur l'ecran self.player.all_projectiles.draw(screen) #boucle sur les cometes for comet in self.comet_event.all_comets: comet.fall() #appliquer les monstres self.all_monsters.draw(screen) #appliquer les comètes self.comet_event.all_comets.draw(screen) #verifie le sens de deplacement du joueur #print(self.pressed) #si touche droite activée if self.pressed.get( pygame.K_RIGHT ) and self.player.rect.x + self.player.rect.width < screen.get_width(): #déplacement à droite self.player.move_right() #si touche gauche activée elif self.pressed.get(pygame.K_LEFT) and self.player.rect.x > 0: #déplacement à gauche self.player.move_left() def check_collision(self, sprite, group): """methode qui gere les collisions""" return pygame.sprite.spritecollide(sprite, group, False, pygame.sprite.collide_mask) def spawn_monster(self, monster_class_name): """methode d'apparition du monstre""" #création d'une liste de monstres self.all_monsters.add(monster_class_name.__call__(self))
class PortalController: PORTAL_AUDIO_CHANNEL = 3 def __init__(self, screen, user, maze): self.screen = screen self.maze = maze self.user = user self.sound_manager = SoundManager( sound_files=['portal-open.wav', 'portal-travel.wav'], keys=['open', 'travel'], channel=PortalController.PORTAL_AUDIO_CHANNEL) self.blue_portal = pygame.sprite.GroupSingle( ) # portals as GroupSingle, which only allows one per group self.blue_projectile = None self.orange_portal = pygame.sprite.GroupSingle() self.orange_projectile = None self.portal_directions = {'l': 'r', 'r': 'l', 'u': 'd', 'd': 'u'} def clear_portals(self): self.blue_portal.empty() self.orange_portal.empty() self.blue_projectile = None self.orange_projectile = None def fire_b_portal_projectile(self): if self.user.direction is not None: self.blue_projectile = PortalProjectile( screen=self.screen, source=self.user, direction=self.user.direction, p_type=Portal.portal_1) def fire_o_portal_projectile(self): if self.user.direction is not None: self.orange_projectile = PortalProjectile( screen=self.screen, source=self.user, direction=self.user.direction, p_type=Portal.portal_2) def create_blue_portal(self, x, y, direction): if self.blue_portal: old_x, old_y = self.blue_portal.sprite.rect.x, self.blue_portal.sprite.rect.y self.maze.maze_blocks.add( Block(old_x, old_y, self.maze.block_size, self.maze.block_size, self.maze.block_image)) self.blue_portal.add( Portal(screen=self.screen, x=x, y=y, direction=direction, maze=self.maze, p_type=Portal.portal_1)) def create_orange_portal(self, x, y, direction): if self.orange_portal: old_x, old_y = self.orange_portal.sprite.rect.x, self.orange_portal.sprite.rect.y self.maze.maze_blocks.add( Block(old_x, old_y, self.maze.block_size, self.maze.block_size, self.maze.block_image)) self.orange_portal.add( Portal(screen=self.screen, x=x, y=y, direction=direction, maze=self.maze, p_type=Portal.portal_2)) def update(self): self.blue_portal.update() self.orange_portal.update() if self.blue_projectile: self.blue_projectile.update() if pygame.sprite.spritecollideany(self.blue_projectile, self.blue_portal) or \ pygame.sprite.spritecollideany(self.blue_projectile, self.orange_portal): self.blue_projectile = None return collision = pygame.sprite.spritecollideany(self.blue_projectile, self.maze.maze_blocks) if collision: x, y = collision.rect.x, collision.rect.y collision.kill() direction = self.portal_directions[ self.blue_projectile.direction] self.blue_projectile = None self.create_blue_portal(x, y, direction) self.sound_manager.play('open') elif self.blue_projectile.is_off_screen(): self.blue_projectile = None if self.orange_projectile: self.orange_projectile.update() if pygame.sprite.spritecollideany(self.orange_projectile, self.blue_portal) or \ pygame.sprite.spritecollideany(self.orange_projectile, self.orange_portal): self.orange_projectile = None return collision = pygame.sprite.spritecollideany(self.orange_projectile, self.maze.maze_blocks) if collision: x, y = collision.rect.x, collision.rect.y collision.kill() direction = self.portal_directions[ self.orange_projectile.direction] self.orange_projectile = None self.create_orange_portal(x, y, direction) self.sound_manager.play('open') elif self.orange_projectile.is_off_screen(): self.orange_projectile = None def portables_usable(self): return self.blue_portal and self.orange_portal def collide_portals(self, other): return pygame.sprite.spritecollideany(other, self.blue_portal) or \ pygame.sprite.spritecollideany(other, self.orange_portal) def check_portals(self, *args): for arg in args: if pygame.sprite.spritecollideany( arg, self.blue_portal) and self.orange_portal: i, j = self.orange_portal.sprite.get_nearest_row( ), self.orange_portal.sprite.get_nearest_col() if self.orange_portal.sprite.direction == 'l': j -= 1 elif self.orange_portal.sprite.direction == 'r': j += 1 elif self.orange_portal.sprite.direction == 'u': i -= 1 else: i += 1 x, y = ((self.screen.get_width()) // 5 + (j * self.maze.block_size)), \ ((self.screen.get_height()) // 12 + (i * self.maze.block_size)) arg.rect.x, arg.rect.y = x, y self.sound_manager.play('travel') elif pygame.sprite.spritecollideany( arg, self.orange_portal) and self.blue_portal: i, j = self.blue_portal.sprite.get_nearest_row( ), self.blue_portal.sprite.get_nearest_col() if self.blue_portal.sprite.direction == 'l': j -= 1 elif self.blue_portal.sprite.direction == 'r': j += 1 elif self.blue_portal.sprite.direction == 'u': i -= 1 else: i += 1 x, y = ((self.screen.get_width() // 5) + (j * self.maze.block_size)), \ ((self.screen.get_height() // 12) + (i * self.maze.block_size)) arg.rect.x, arg.rect.y = x, y self.sound_manager.play('travel') def blit(self): if self.blue_projectile: self.blue_projectile.blit() if self.orange_projectile: self.orange_projectile.blit() if self.blue_portal: self.blue_portal.sprite.blit() if self.orange_portal: self.orange_portal.sprite.blit()
class Game: def __init__(self): self.is_playing = False self.all_players = pygame.sprite.Group() self.player = Player(self) self.all_players.add(self.player) self.all_monsters = pygame.sprite.Group() self.sound_manager = SoundManager() self.pressed = {} self.score = 0 def start(self): self.is_playing = True self.spawn_monster(Wizard) self.spawn_monster(Wizard) self.spawn_monster(Wraith) self.sound_manager.play('start') def game_over(self): self.all_monsters = pygame.sprite.Group() self.player.health = self.player.max_health self.is_playing = False self.score = 0 self.sound_manager.play('game_over') def launch_game(self, screen): # appliquer image joueur screen.blit(self.player.image, self.player.rect) for projectile in self.player.all_projectiles: projectile.move() self.player.update_health_bar(screen) if self.player.animation is False: self.player.load_animation("assets/idle", [8, 8, 8]) self.player.all_projectiles.draw(screen) self.player.update_animation() self.all_monsters.draw(screen) for monster in self.all_monsters: monster.forward() monster.update_health_bar(screen) monster.update_animations() # verifier si le joueur veut aller à gauche ou à droite if self.pressed.get( pygame.K_RIGHT ) and self.player.rect.x + self.player.rect.width < screen.get_width(): self.player.move_right() elif self.pressed.get(pygame.K_LEFT) and self.player.rect.x > 0: self.player.move_left() def check_collision(self, sprite, group): return pygame.sprite.spritecollide(sprite, group, False, pygame.sprite.collide_mask) def spawn_monster(self, monster_name): self.all_monsters.add(monster_name.__call__(self))
def update_logic(self): """ Update Logic runs through all player movement, controller inputs, player attack_status, checks for game_over or map scroll advance. Anything that involves changing numbers is done here. """ #Limit logic loop by frames per second pygame.time.wait(int(1000/self.FPS)) #If all players are dead game over is enabled. self.game_over = True for Players in self.unit_roster.get("Players"): if Players.dead == False: self.game_over = False # Update Script (Event Handler responsible for spawning monsters, printing quest text, enabling scroll) self.script.update_script() # Player Loop for player in self.unit_roster.get("Players"): # If scroll available and player at edge scroll change map if player.xpos > 900 and self.script.scroll_available: self.script.text_print = 0 self.maps.is_map_scrolling = 1 spawn_players(self.unit_roster.get("Players")) # If player has died remove from Roster for unit in self.unit_roster.get("Players"): if unit.dead: self.unit_roster.get("Players").remove(unit) #Player is still alive if player.get_health() > 0: #Update Controller (Get input) for control in self.controllers: if control.player == player: control.update() #Check for defense if player.defending: player.defend_spell() else: player.armor = 1 #passive health/energy restore player.gain_energy(0.3) player.gain_health(0.1) #If player has triggered attack in controller update #but not yet dealt possible dmg to surroundings do it. #Only if possible to dmg enemies, unless duel mode is active. if not player.dmg_dealt: SoundManager.play(player.atk1_sound) player.check_dmg_done(self.unit_roster.get("Enemies")) if self.script.duel_mode: player.check_dmg_done(self.unit_roster.get("Players")) player.dmg_dealt = True #Player is not alive else: # health < 0 player.dead = True #Enemy Loop (Very similar to Player Loop) for unit in self.unit_roster.get("Enemies"): #Enemie is alive if unit.get_health() > 0: unit.gain_energy(0.3) #This is basically AI version of Controller update unit.AI_update(self.screen) #If possible to deal dmg do it. if not unit.dmg_dealt: SoundManager.play(unit.atk1_sound) unit.check_dmg_done(self.unit_roster.get("Players")) unit.dmg_dealt = True else: # Enemy is dead #Remove from roster and feild after despawn time despawn_time = 2000 if not unit.dead: unit.dead_time = pygame.time.get_ticks() unit.dead = True if unit.dead_time + despawn_time < pygame.time.get_ticks(): self.unit_roster.get("Enemies").remove(unit)
class Game: def __init__(self): # definir si notre jeu a commencé ou non self.is_playing = False # generer notre joueur self.all_players = pygame.sprite.Group() self.player = Player(self) self.all_players.add(self.player) # generer l'evenement self.comet_event = CometFallEvent(self) # groupe de monstres self.all_monsters = pygame.sprite.Group() # gerer le son self.sound_manager = SoundManager() # mettre le score à 0 self.font = pygame.font.Font("assets/HanaleiFill-Regular.ttf", 25) self.score = 0 self.pressed = {} def start(self): self.is_playing = True self.spawn_monster(Mummy) self.spawn_monster(Mummy) self.spawn_monster(Alien) def add_score(self, points=10): self.score += points def game_over(self): # remettre le jeu à neuf, retirer les monstres, remettre le joueur a 100 de vie, et mettre le jeu en attente self.all_monsters = pygame.sprite.Group() self.comet_event.all_comets = pygame.sprite.Group() self.player.health = self.player.max_health self.comet_event.reset_percent() self.is_playing = False self.score = 0 # jouer le son self.sound_manager.play('game_over') def update(self, screen): # afficher le score sur l'écran score_text = self.font.render(f"Score : {self.score}", 1, (0, 0, 0)) screen.blit(score_text, (20, 20)) # appliquer l'image de mon joueur screen.blit(self.player.image, self.player.rect) # actualiser la barre de vie du joueur self.player.update_health_bar(screen) # actualiser la barre d'évenement du jeu self.comet_event.update_bar(screen) # actualiser l'animation du joueur self.player.update_animation() # recuperer les projectiles du joueur for projectile in self.player.all_projectiles: projectile.move() # recuperer les monstres de notre jeu for monster in self.all_monsters: monster.forward() monster.update_health_bar(screen) monster.update_animation() # recuperer les cometes de notre jeu for comet in self.comet_event.all_comets: comet.fall() # appliquer l'ensemble des images de mon groupe de projectiles self.player.all_projectiles.draw(screen) # appliquer l'ensemble des images de mon groupe de monstres self.all_monsters.draw(screen) # appliquer l'ensemble des images de mon groupe de cometes self.comet_event.all_comets.draw(screen) # verifier si le joueur souhaite aller à gauche ou à droite if self.pressed.get(pygame.K_RIGHT) and self.player.rect.x + self.player.rect.width < screen.get_width(): self.player.move_right() elif self.pressed.get(pygame.K_LEFT) and self.player.rect.x > 0: self.player.move_left() def check_collision(self, sprite, group): return pygame.sprite.spritecollide(sprite, group, False, pygame.sprite.collide_mask) def spawn_monster(self, monster_class_name): self.all_monsters.add(monster_class_name.__call__(self))
class Game: def __init__(self): self.is_playing = False self.all_players = pygame.sprite.Group() self.player = Player(self) self.all_players.add(self.player) self.comet_event = CometFallEvent(self) self.all_monsters = pygame.sprite.Group() self.font_text = pygame.font.Font("assets/DancingScript-Bold.ttf", 80) self.score = 0 self.sound_manager = SoundManager() self.pressed = {} def start(self): self.is_playing = True self.spawn_monster(Mummy) self.spawn_monster(Mummy) self.spawn_monster(Alien) def add_score(self, points=20): self.score += points def game_over(self): self.all_monsters = pygame.sprite.Group() self.comet_event.all_comets = pygame.sprite.Group() self.player.health = self.player.max_health self.comet_event.reset_percent() self.is_playing = False self.score = 0 self.sound_manager.play("game_over") def update(self, screen): # font_number = pygame.font.Font("assets/Archivo-Italic.ttf", 80) score_text = self.font_text.render(f"Score : {self.score}", 1, (0, 0, 255)) # score_number = font_number.render(f"{self.score}", 1, (0, 0, 255)) screen.blit(score_text, (20, 20)) # screen.blit(score_number, (230, 20)) screen.blit(self.player.image, self.player.rect) self.player.update_health_bar(screen) self.comet_event.update_bar(screen) self.player.update_animation() for projectile in self.player.all_projectiles: projectile.move() for monster in self.all_monsters: monster.forward() monster.update_health_bar(screen) monster.update_animation() for comet in self.comet_event.all_comets: comet.fall() self.player.all_projectiles.draw(screen) self.all_monsters.draw(screen) self.comet_event.all_comets.draw(screen) if self.pressed.get( pygame.K_RIGHT ) and self.player.rect.x + self.player.rect.width < screen.get_width(): self.player.move_right() elif self.pressed.get(pygame.K_LEFT) and self.player.rect.x > 0: self.player.move_left() def spawn_monster(self, monster_class_name): self.all_monsters.add(monster_class_name.__call__(self)) @staticmethod def check_collision(sprite, sprite_group): return pygame.sprite.spritecollide(sprite, sprite_group, False, pygame.sprite.collide_mask)
class Game: def __init__(self): # Generer le jouer self.all_players = pygame.sprite.Group() self.player = Player(self) self.all_players.add(self.player) # Definir si le jeu a commence self.is_playing = False # groupe de monstre self.all_monsters = pygame.sprite.Group() self.pressed = {} # generer l'evenement comet self.comet_event = CometFallEvent(self) # mettre le score a zero self.font = pygame.font.SysFont('monospace', 25, True) self.score = 0 # gerer le son self.sound_manager = SoundManager() def start(self): self.is_playing = True self.spawn_monster(Mummy) self.spawn_monster(Mummy) self.spawn_monster(Alien) def game_over(self): self.all_monsters = pygame.sprite.Group() self.comet_event.all_comets = pygame.sprite.Group() self.player.health = self.player.max_health self.comet_event.reset_percent() self.is_playing = False self.score = 0 self.sound_manager.play('game_over') def add_score(self, score=1): self.score += score def update(self, screen): # afficher le score: score_text = self.font.render(f'Score: {self.score}', 1, (0, 0, 0)) screen.blit(score_text, (20, 20)) # Add player image screen.blit(self.player.image, self.player.rect) # actualiser la barre de vie du joueur self.player.update_health_bar(screen) # actualiser l'animation du joueur self.player.update_animation() # actualiser la barre d'evenement du jeu self.comet_event.update_bar(screen) # recuperer les pojectiles du joueur for projectile in self.player.all_projectiles: projectile.move() # recuperer les monstres for monster in self.all_monsters: monster.forward() monster.update_health_bar(screen) monster.update_animation() # recuperer les commettes du jeu for comet in self.comet_event.all_comets: comet.fall() # appliquer l'ensemble des images du groupe projectile self.player.all_projectiles.draw(screen) # appliquer l'ensemble des images du groupe monstre self.all_monsters.draw(screen) # appliquer l'ensemble des images du groupe comet self.comet_event.all_comets.draw(screen) # Verifier si le joueur souhaite aller à gauche ou droite if self.pressed.get( pygame.K_RIGHT ) and self.player.rect.x + self.player.rect.width < screen.get_width(): self.player.move_right() elif self.pressed.get(pygame.K_LEFT) and self.player.rect.x > 0: self.player.move_left() def check_collision(self, sprite, group): return pygame.sprite.spritecollide(sprite, group, False, pygame.sprite.collide_mask) def spawn_monster(self, monster_class_name): self.all_monsters.add(monster_class_name.__call__(self))
class Game: MAX_LEVEL = 3 LEVEL_INCREMENT = 1 def __init__(self): self.is_playing = False self.player = Player(self) self.all_players = pygame.sprite.Group([self.player]) self.comet_event = CometFallEvent(self) self.all_monster = pygame.sprite.Group() self.sound_manager = SoundManager() self.font = pygame.font.Font( "cometfall/assets/fonts/Anton-Regular.ttf", 30) self.score = 0 self.level = {} self.username = None self.comet_event_number = 0 image = pygame.image.load(f"cometfall/assets/background/planet.jpg") self.background = pygame.transform.scale(image, (1200, 720)) @property def key_pressed(self): return pygame.key.get_pressed() def start(self): self.is_playing = True self.load_level() self.spawn_monsters() self.sound_manager.play('click') def spawn_monsters(self, n=None): """ Spawn n monsters with probability for each monster to appear """ monsters_type = self.level['monsters'] probability = self.level.get('probability') attack_factor = 1 + int(self.level.get('attack_bonus', '0%')[:-1]) / 100 health_factor = 1 + int(self.level.get('health_bonus', '0%')[:-1]) / 100 player_factor = 1 + int(self.level.get('player_bonus', '0%')[:-1]) / 100 self.player.attack *= player_factor spawn_number = n or int(self.level.get('spawn_number')) monsters = np.random.choice(monsters_type, spawn_number, p=probability) for name in monsters: try: monster_type = getattr(monster, name.title()) except AttributeError: raise AttributeError( f"Monster {name.title()} not exists, check the levels.json file" ) self.all_monster.add( monster_type(self, health_factor, attack_factor)) def add_score(self, points=10): self.score += points @staticmethod def check_colision(sprite, group): return pygame.sprite.spritecollide(sprite, group, False, pygame.sprite.collide_mask) def game_over(self): """ Remet le jeu à neuf """ self.all_monster = pygame.sprite.Group() self.comet_event.all_comet = pygame.sprite.Group() self.player.health = self.player.max_health self.comet_event.reset_percent() self.is_playing = False self.score = 0 self.player.rect.x = 400 self.player.rect.y = 470 self.load_level(1) self.sound_manager.stop_all() self.sound_manager.play('game_over') print() a = basedonnee() a.enregistrer() a.score() def update(self, screen): """ Update the screen display""" score_text = self.font.render(f"Score : {self.score}", True, (0, 0, 0)) screen.blit(score_text, (20, 20)) username = self.font.render(self.username, True, (0, 0, 0)) screen.blit(username, (950, 20)) # appliquer l'image du joueur if self.key_pressed[pygame.K_LCTRL]: # shoot mode screen.blit(self.player.shoot_image, self.player.rect) elif self.player.animation: self.player.animate() screen.blit(self.player.image, self.player.rect) else: screen.blit(self.player.default_image, self.player.rect) self.player.update_health_bar(screen) self.comet_event.update_bar(screen) # récupérer les projectiles du joueur for projectile in self.player.all_projectiles: projectile.move() # récupérer les monstres de notre jeu for active_monster in self.all_monster: active_monster.forward() active_monster.update_health_bar(screen) active_monster.update_animation() # récupérer les comètes de notre jeu for comet in self.comet_event.all_comet: comet.fall() # récuperer le boss de notre jeu """ for Boss in self.Boss_event.ship: Boss.fall() """ self.player.all_projectiles.draw(screen) self.comet_event.all_comet.draw(screen) self.all_monster.draw(screen) # verifier si le joueur souhaite aller à gauche ou à droite if not self.key_pressed[pygame.K_LCTRL]: if self.key_pressed[pygame.K_RIGHT] and \ self.player.rect.x + self.player.rect.width < screen.get_width(): self.player.move_right() elif self.key_pressed[pygame.K_LEFT] and self.player.rect.x > 0: self.player.move_left() def load_level(self, wanted_level=None): """ Apply values defined in levels.json for current level """ if self.comet_event_number % self.LEVEL_INCREMENT == 0: level = wanted_level or ( self.comet_event_number // self.LEVEL_INCREMENT + 1) if level <= self.MAX_LEVEL: with open("cometfall/static/levels.json", 'r', encoding='utf-8') as f: self.level = json.load(f)[f"level {level}"] image = pygame.image.load( f"cometfall/assets/background/{self.level['background']}") self.background = pygame.transform.scale(image, (1080, 720)) if sound := self.level.get('game_sound'): self.sound_manager.stop_all() self.sound_manager.play(sound, volume=0.15) else: raise AttributeError( f"You must define a game_sound attribute " f"for the level {level}")
class PacMan(pygame.sprite.Sprite): PAC_YELLOW = (255, 255, 0) PAC_AUDIO_CHANNEL = 0 def __init__(self, screen, maze): super().__init__() self.screen = screen self.radius = maze.block_size // 1 self.maze = maze self.sound_manager = SoundManager( sound_files=[ 'yum_one.wav', 'yum_two.wav', 'pacman-killed.wav', 'pacman-portal.wav' ], keys=['eat', 'fruit', 'dead', 'portal'], channel=PacMan.PAC_AUDIO_CHANNEL) self.pacman_horizontal = ImageManager('pacman-horiz.png', sheet=True, pos_offsets=[(0, 0, 32, 32), (32, 0, 32, 32), (0, 32, 32, 32), (32, 32, 32, 32), (0, 64, 32, 32)], resize=(self.maze.block_size, self.maze.block_size), reversible=True) self.pacman_vertical = ImageManager('pacman-vert.png', sheet=True, pos_offsets=[(0, 0, 32, 32), (32, 0, 32, 32), (0, 32, 32, 32), (32, 32, 32, 32), (0, 64, 32, 32)], resize=(self.maze.block_size, self.maze.block_size), reversible=True) self.pacman_dead = ImageManager('pacman-death.png', sheet=True, pos_offsets=[(0, 0, 32, 32), (32, 0, 32, 32), (0, 32, 32, 32), (32, 32, 32, 32), (0, 64, 32, 32), (32, 64, 32, 32)], resize=(self.maze.block_size, self.maze.block_size), animation_delay=150, repeat=False) self.flip_status = { 'use_horiz': True, 'h_flip': False, 'v_flip': False } self.spawn_info = self.maze.player_spawn[1] self.tile = self.maze.player_spawn[0] self.direction = None self.moving = False self.speed = maze.block_size // 7 self.image, self.rect = self.pacman_horizontal.get_image() self.rect.centerx, self.rect.centery = self.spawn_info self.dead = False self.portal_controller = PortalController(screen, self, maze) self.event_map = { pygame.KEYDOWN: self.perform_action, pygame.KEYUP: self.reset_direction } self.action_map = { pygame.K_UP: self.set_move_up, pygame.K_LEFT: self.set_move_left, pygame.K_DOWN: self.set_move_down, pygame.K_RIGHT: self.set_move_right, pygame.K_q: self.blue_portal, pygame.K_w: self.orange_portal } def eat(self): score = 0 fruit_count = 0 power = None collision = pygame.sprite.spritecollideany(self, self.maze.pellets) if collision: collision.kill() score += 10 self.sound_manager.play('eat') collision = pygame.sprite.spritecollideany(self, self.maze.fruits) if collision: collision.kill() score += 20 fruit_count += 1 self.sound_manager.play('fruit') collision = pygame.sprite.spritecollideany(self, self.maze.power_pellets) if collision: collision.kill() score += 20 power = True self.sound_manager.play('eat') return score, fruit_count, power def is_blocked(self): result = False if self.direction is not None and self.moving: original_pos = self.rect if self.direction == 'u': test = self.rect.move((0, -self.speed)) elif self.direction == 'l': test = self.rect.move((-self.speed, 0)) elif self.direction == 'd': test = self.rect.move((0, self.speed)) else: test = self.rect.move((self.speed, 0)) self.rect = test if pygame.sprite.spritecollideany(self, self.maze.maze_blocks): result = True elif pygame.sprite.spritecollideany(self, self.maze.shield_blocks): result = True elif not self.portal_controller.portables_usable(): result = self.portal_controller.collide_portals(self) self.rect = original_pos return result def set_move_up(self): if self.direction != 'u': self.direction = 'u' if self.flip_status['v_flip']: self.pacman_vertical.flip(False, True) self.flip_status['v_flip'] = False self.flip_status['use_horiz'] = False self.moving = True def set_move_left(self): if self.direction != 'l': self.direction = 'l' if not self.flip_status['h_flip']: self.pacman_horizontal.flip() self.flip_status['h_flip'] = True self.flip_status['use_horiz'] = True self.moving = True def set_move_down(self): if self.direction != 'd': self.direction = 'd' if not self.flip_status['v_flip']: self.pacman_vertical.flip(x_bool=False, y_bool=True) self.flip_status['v_flip'] = True self.flip_status['use_horiz'] = False self.moving = True def set_move_right(self): if self.direction != 'r': self.direction = 'r' if self.flip_status['h_flip']: self.pacman_horizontal.flip() self.flip_status['h_flip'] = False self.flip_status['use_horiz'] = True self.moving = True def clear_portals(self): self.portal_controller.clear_portals() def blue_portal(self): self.sound_manager.play('portal') self.portal_controller.fire_b_portal_projectile() def orange_portal(self): self.sound_manager.play('portal') self.portal_controller.fire_o_portal_projectile() def set_death(self): self.sound_manager.play('dead') self.dead = True self.image, _ = self.pacman_dead.get_image() def revive(self): self.dead = False self.image, _ = self.pacman_horizontal.get_image() self.pacman_dead.image_index = 0 def reset_position(self): self.rect.centerx, self.rect.centery = self.spawn_info # screen coordinates for spawn def reset_direction(self, event): if event.key in (pygame.K_UP, pygame.K_DOWN, pygame.K_LEFT, pygame.K_RIGHT): self.moving = False def perform_action(self, event): if event.key in self.action_map: self.action_map[event.key]() def get_nearest_col(self): return (self.rect.x - (self.screen.get_width() // 5)) // self.maze.block_size def get_nearest_row(self): return (self.rect.y - (self.screen.get_height() // 12)) // self.maze.block_size def update(self): if not self.dead: self.portal_controller.update() self.portal_controller.check_portals(self) if self.direction and self.moving: if self.flip_status['use_horiz']: self.image = self.pacman_horizontal.next_image() else: self.image = self.pacman_vertical.next_image() if not self.is_blocked(): if self.direction == 'u': self.rect.centery -= self.speed elif self.direction == 'l': self.rect.centerx -= self.speed elif self.direction == 'd': self.rect.centery += self.speed elif self.direction == 'r': self.rect.centerx += self.speed self.tile = (self.get_nearest_row(), self.get_nearest_col()) else: self.image = self.pacman_dead.next_image() def blit(self): self.portal_controller.blit() self.screen.blit(self.image, self.rect)
class Game: def __init__(self): self.is_playing = False # Génération de notre joueur self.all_player = pygame.sprite.Group() self.player = Player(self) self.all_player.add(self.player) # Générer l'évènement self.comet_event = CometFallEvent(self) # groupe de monstres self.all_monster = pygame.sprite.Group() self.pressed = {} # Mettre le score a 0 self.score = 0 self.font = pygame.font.SysFont("monospace", 16, True) # fself.ont = pygame.font.Font("assets/my_custom_font.ttf", 25) # Gestion des effets sonores self.sound_manager = SoundManager() def start(self): self.is_playing = True self.spawn_monster(Mummy) self.spawn_monster(Mummy) self.spawn_monster(Alien) def add_score(self, points=10): # Ajouter le nombre de point au score self.score += 20 def game_over(self): # Remettre le jeu a zéro. self.all_monster = pygame.sprite.Group() self.comet_event.all_comets = pygame.sprite.Group() self.player.health = self.player.max_health self.comet_event.reset_percent() self.is_playing = False self.score = 0 # jouer le son self.sound_manager.play("game_over") def update(self, screen): # Afficher le score sur l'ecran score_text = self.font.render(f"Score: {self.score}", 1, (0, 0, 0)) screen.blit(score_text, (20, 20)) # Appliquer l'image du joueur screen.blit(self.player.image, self.player.rect) self.player.update_health_bar(screen) # actualiser la barre d'évènement du jeu self.comet_event.update_bar(screen) # actualiser l'animation du joueur self.player.update_animation() # Recupereer les projectile du joueur for projectile in self.player.all_projectiles: projectile.move() # Recuperer les projectile du joueur for monster in self.all_monster: monster.forward() monster.update_health_bar(screen) monster.update_animation() # Recuperer les cometes du joueur for comet in self.comet_event.all_comets: comet.fall() # Applique l'image du projectile self.player.all_projectiles.draw(screen) # Appliquer l'ensemble des images de monstre self.all_monster.draw(screen) # Appliquer l'ensemble des image du goupe comete self.comet_event.all_comets.draw(screen) # Verifier si le joueur souhaite aller a gauche ou a droite if self.pressed.get( pygame.K_RIGHT ) and self.player.rect.x + self.player.rect.width < screen.get_width(): self.player.move_right() elif self.pressed.get(pygame.K_LEFT) and self.player.rect.x >= 0: self.player.move_left() def check_collision(self, sprinte, group): return pygame.sprite.spritecollide(sprinte, group, False, pygame.sprite.collide_mask) def spawn_monster(self, monster_class_name): monster = Mummy(self) self.all_monster.add(monster_class_name.__call__(self))
def update_logic(self): """ Update Logic runs through all player movement, controller inputs, player attack_status, checks for game_over or map scroll advance. Anything that involves changing numbers is done here. """ #Limit logic loop by frames per second pygame.time.wait(int(1000 / self.FPS)) #If all players are dead game over is enabled. self.game_over = True for Players in self.unit_roster.get("Players"): if Players.dead == False: self.game_over = False # Update Script (Event Handler responsible for spawning monsters, printing quest text, enabling scroll) self.script.update_script() # Player Loop for player in self.unit_roster.get("Players"): # If scroll available and player at edge scroll change map if player.xpos > 900 and self.script.scroll_available: self.script.text_print = 0 self.maps.is_map_scrolling = 1 spawn_players(self.unit_roster.get("Players")) # If player has died remove from Roster for unit in self.unit_roster.get("Players"): if unit.dead: self.unit_roster.get("Players").remove(unit) #Player is still alive if player.get_health() > 0: #Update Controller (Get input) for control in self.controllers: if control.player == player: control.update() #Check for defense if player.defending: player.defend_spell() else: player.armor = 1 #passive health/energy restore player.gain_energy(0.3) player.gain_health(0.1) #If player has triggered attack in controller update #but not yet dealt possible dmg to surroundings do it. #Only if possible to dmg enemies, unless duel mode is active. if not player.dmg_dealt: SoundManager.play(player.atk1_sound) player.check_dmg_done(self.unit_roster.get("Enemies")) if self.script.duel_mode: player.check_dmg_done(self.unit_roster.get("Players")) player.dmg_dealt = True #Player is not alive else: # health < 0 player.dead = True #Enemy Loop (Very similar to Player Loop) for unit in self.unit_roster.get("Enemies"): #Enemie is alive if unit.get_health() > 0: unit.gain_energy(0.3) #This is basically AI version of Controller update unit.AI_update(self.screen) #If possible to deal dmg do it. if not unit.dmg_dealt: SoundManager.play(unit.atk1_sound) unit.check_dmg_done(self.unit_roster.get("Players")) unit.dmg_dealt = True else: # Enemy is dead #Remove from roster and feild after despawn time despawn_time = 2000 if not unit.dead: unit.dead_time = pygame.time.get_ticks() unit.dead = True if unit.dead_time + despawn_time < pygame.time.get_ticks(): self.unit_roster.get("Enemies").remove(unit)
class Game: def __init__(self): self.is_playing = False self.all_players = pygame.sprite.Group() self.player = Player(self) self.all_players.add(self.player) self.all_monsters = pygame.sprite.Group() #gerer le son self.sound_manager = SoundManager() #mettre le score a 0 self.font = pygame.font.Font("assets/my_custom_font.ttf", 25) self.score = 0 self.pressed = {} self.comet_event = CometFallEvent(self) def start(self): self.is_playing = True self.spawn_monster(Mummy) self.spawn_monster(Mummy) self.spawn_monster(Mummy) self.spawn_monster(Alien) def add_score(self, points=10): self.score += points def game_over(self): self.all_monsters = pygame.sprite.Group() self.comet_event.all_comets = pygame.sprite.Group() self.player.health = self.player.max_health self.comet_event.reset_percent() self.is_playing = False self.score = 0 #jouerle son self.sound_manager.play('game_over') def update(self, screen): #afficher le score sur l ecran score_text = self.font.render(f"Score: {self.score}", 1, (0, 0, 0)) screen.blit(score_text, (20, 20)) screen.blit(self.player.image, self.player.rect) self.player.update_health_bar(screen) self.comet_event.update_bar(screen) self.player.update_animation() for projectile in self.player.all_projectiles: projectile.move() for monster in self.all_monsters: monster.forward() monster.update_health_bar(screen) monster.update_animation() for comet in self.comet_event.all_comets: comet.fall() self.player.all_projectiles.draw(screen) self.all_monsters.draw(screen) self.comet_event.all_comets.draw(screen) if self.pressed.get(pygame.K_RIGHT) and \ self.player.rect.x + self.player.\ rect.width < screen.get_width(): self.player.move_right() elif self.pressed.get(pygame.K_LEFT) and \ self.player.rect.x > 0: self.player.move_left() def check_collision(self, sprite, group): return pygame.sprite.spritecollide(sprite, group, False, pygame.sprite.collide_mask) def spawn_monster(self, monster_class_name): monster = Mummy(self) self.all_monsters.add(monster_class_name.__call__(self))
class Game(pygame.sprite.Sprite): def __init__(self): super().__init__() self.key_pressed = {} self.player = Ninja(self) self.player_group = pygame.sprite.Group(self.player) self.all_zombies_right = pygame.sprite.Group() self.all_zombies_left = pygame.sprite.Group() self.all_heart = pygame.sprite.Group() self.all_flask = pygame.sprite.Group() self.kill = 0 self.dismiss_monsters = False self.total_points = 0 self.game_finish = False self.finish_scene = True self.kamehameha_mode = False self.kill_before_kamehameha = 0 self.kill_after_kamehameha = 0 self.game_results = False self.game_replay = False self.game_time = 0 self.monster_counter = 0 self.round = 0 self.target_number = 0 self.sound_manager = SoundManager() def game_engine(self): self.round += 1 self.target_number += 10 self.monster_counter = 0 total_spawn = 2 * self.round spawn_right = random.randint(1, (total_spawn - 1)) spawn_left = total_spawn - spawn_right spawn_right_counter = 0 spawn_left_counter = 0 while spawn_right_counter < spawn_right: self.spawn_right_zombie() spawn_right_counter += 1 while spawn_left_counter < spawn_left: self.spawn_left_zombie() spawn_left_counter += 1 self.sound_manager.play('ambience', 0.6, -1) def spawn_right_zombie(self): zombie_right = Zombie(self) zombie_right.rect.x = 1080 + random.randint(0, 300) self.all_zombies_right.add(zombie_right) def spawn_left_zombie(self): zombie_left = Zombie(self) zombie_left.rect.x = 0 - zombie_left.image.get_width( ) - random.randint(0, 300) self.all_zombies_left.add(zombie_left) def spawn_heart(self): heart = Heart(self) self.all_heart.add(heart) def spawn_flask(self): flask = Flask(self) self.all_flask.add(flask) def check_collision(self, sprite, group): return pygame.sprite.spritecollide(sprite, group, False, pygame.sprite.collide_mask) def vanish_all_monsters(self): for zombie in self.all_zombies_right: zombie.current_image = 0 for zombie in self.all_zombies_left: zombie.current_image = 0 for heart in self.all_heart: heart.kill() for poison in self.all_flask: poison.kill() self.sound_manager.play('poof', 0.2, 0) self.dismiss_monsters = True def game_over(self, surface): go_font = pygame.font.SysFont("arial", 95, True) rounds_font = pygame.font.SysFont("arial", 25, True) results_font = pygame.font.SysFont("arial", 30, True) self.game_time = int(self.game_time) seconds = (self.game_time / 1000) % 60 seconds = int(seconds) minutes = (self.game_time / (1000 * 60)) % 60 minutes = int(minutes) hours = (self.game_time / (1000 * 60 * 60)) % 24 hours = int(hours) go_text = go_font.render("Game Over", True, (255, 255, 255)) round_text = rounds_font.render(f"You Survived {self.round} Rounds", True, (255, 255, 255)) points_text = results_font.render("Points", True, (255, 234, 0)) points_nb = results_font.render(f"{self.total_points}", True, (255, 234, 0)) kills_text = results_font.render("Kills", True, (57, 192, 237)) kills_nb = results_font.render(f"{self.kill}", True, (57, 192, 237)) game_time_text = results_font.render("Game Time", True, (0, 230, 118)) game_time_nb = results_font.render( f"{hours:02d}:{minutes:02d}:{seconds:02d}", True, (0, 230, 118)) retry_text = results_font.render("Press space to restart a game.", True, (255, 255, 255)) surface.blit(go_text, ((surface.get_width() - go_text.get_width()) / 2, 60)) surface.blit(round_text, ((surface.get_width() - round_text.get_width()) / 2, 180)) surface.blit(points_text, ((508.5 - points_text.get_width()) / 2, 300)) surface.blit( points_nb, (((508.5 - points_text.get_width()) / 2) + (points_text.get_width() - points_nb.get_width()) / 2, 350)) surface.blit(kills_text, ((surface.get_width() - kills_text.get_width()) / 2, 300)) surface.blit( kills_nb, (((surface.get_width() - kills_text.get_width()) / 2) + (kills_text.get_width() - kills_nb.get_width()) / 2, 350)) surface.blit(game_time_text, (((508.5 - points_text.get_width()) / 2) + 508.5 + kills_text.get_width(), 300)) surface.blit( game_time_nb, ((((508.5 - points_text.get_width()) / 2) + 508.5 + kills_text.get_width()) + (game_time_text.get_width() - game_time_nb.get_width()) / 2, 350)) surface.blit(retry_text, ((surface.get_width() - retry_text.get_width()) / 2, 680)) self.game_replay = True
class Game: def __init__(self): #definir le commencement du jeu self.is_playing = False #generate player self.all_players = pygame.sprite.Group() self.player = Player(self) self.all_players.add(self.player) #generer l'evenement self.comet_event = CometFallEvent(self) #groupe monstres self.all_monsters = pygame.sprite.Group() #gestion du son self.sound_manager = SoundManager() #METTRE score a zero self.font = pygame.font.Font("assets/font.ttf", 25) self.score = 0 self.pressed = {} def start(self): self.is_playing = True self.spawn_monster(Mummy) self.spawn_monster(Mummy) self.spawn_monster(Alien) def add_score(self, points): self.score += points def game_over(self): #remettre le jeu a neuf, enlever le monstre, remettre le joueur a 100 de vie, jeu en attente self.all_monsters = pygame.sprite.Group() self.comet_event.all_comets = pygame.sprite.Group() self.player.health = self.player.max_health self.comet_event.reset_percent() self.is_playing = False self.score = 0 #jouer le son self.sound_manager.play('game_over') def update(self, screen): #afficher le score score_text = self.font.render(f"Score : {self.score}", 1, (0, 0, 0)) screen.blit(score_text, (20, 20)) # screen image screen.blit(self.player.image, self.player.rect) # actulisation barre vie joueur self.player.update_health_bar(screen) #actualiser la barre d'evenement du jeu self.comet_event.update_bar(screen) #actualiser l'animation du jouer self.player.update_anumation() # recuperer projectiles for projectile in self.player.all_projectiles: projectile.move() # recuperer monstres for monster in self.all_monsters: monster.forward() monster.update_health_bar(screen) monster.update_animation() #recuperer les comettes for comet in self.comet_event.all_comets: comet.fall() # appliquer groupe projectile self.player.all_projectiles.draw(screen) # appiquer images groupe monstres self.all_monsters.draw(screen) #appliquer l'ensemble des images de groupe comette self.comet_event.all_comets.draw(screen) # verifier direction if self.pressed.get( pygame.K_RIGHT ) and self.player.rect.x + self.player.rect.width < screen.get_width(): self.player.move_right() elif self.pressed.get(pygame.K_LEFT) and self.player.rect.x > 0: self.player.move_left() def check_collision(self, sprite, group): return pygame.sprite.spritecollide(sprite, group, False, pygame.sprite.collide_mask) def spawn_monster(self, monster_class_name): self.all_monsters.add(monster_class_name.__call__(self))
class Game: def __init__(self): # Generer joueur self.all_players = pygame.sprite.Group() self.player = Player(self) self.all_players.add(self.player) # Groupe de Monstres self.all_monsters = pygame.sprite.Group() # Jeu a commencé ou non ? self.isPlaying = False # Comet self.comet_event = CometFallEvent(self) # Gérer le son self.soundManager = SoundManager() # Mettre score à 0 self.score = 0 self.pressed = {} self.font = pygame.font.Font("assets/PottaOne-Regular.ttf", 25) def start(self): self.isPlaying = True self.spawn_monster(Mummy) self.spawn_monster(Mummy) self.spawn_monster(Alien) def game_over(self): # Reinit le jeu self.all_monsters = pygame.sprite.Group() self.player.health = self.player.max_health self.isPlaying = False self.comet_event.all_comets = pygame.sprite.Group() self.comet_event.reset_percent() self.score = 0 self.soundManager.play('gameOver') def update(self, screen): # Afficher le score #font = pygame.font.SysFont("monospace", 16) scoreText = self.font.render(f"Score: {self.score}", 1, (0, 0, 0)) screen.blit(scoreText, (20, 20)) # Appliquer l'image du joueur screen.blit(self.player.image, self.player.rect) # Actualiser la barre de vie du joueur self.player.update_health_bar(screen) # Actualiser la barre d'événement du jeu self.comet_event.update_bar(screen) # Actualiser l'animation du joueur self.player.update_animation() # Recuperer projectile for projectile in self.player.all_projectiles: projectile.move() # Récupérer les Monstres for monster in self.all_monsters: monster.forward() monster.update_health_bar(screen) monster.update_animation() # Récupérer les comètes for comet in self.comet_event.all_comets: comet.fall() # Dessiner Image projectiles self.player.all_projectiles.draw(screen) # Dessiner Groupe de monstre self.all_monsters.draw(screen) # Appliquer les comètes self.comet_event.all_comets.draw(screen) # Vérifier si à gauche ou à droite if self.pressed.get( pygame.K_RIGHT ) and self.player.rect.x + self.player.rect.width < screen.get_width(): self.player.move_right() elif self.pressed.get(pygame.K_LEFT) and self.player.rect.x > 0: self.player.move_left() def check_collision(self, sprite, group): return pygame.sprite.spritecollide(sprite, group, False, pygame.sprite.collide_mask) def spawn_monster(self, monsterClassName): #monster = Mummy(self) self.all_monsters.add(monsterClassName.__call__(self))
class Client: sock = None connected = False reconnect_timeout = 1 shard_code = '' downloaded = 0 download_total = 0 uploaded = 0 upload_total = 0 def __init__(self, gui, global_mutex): self.threadripper = global_mutex self.gui = gui self.shard_code = gui.shardCodeIpt.GetValue() self.sounds = SoundManager(self) self.state = CSGOState(self) Thread(target=self.listen, daemon=True).start() Thread(target=self.keepalive, daemon=True).start() def send(self, type, packet): # Build the packet... raw_packet = packet.SerializeToString() header = PacketInfo() header.type = type header.length = len(raw_packet) # ...And off it goes self.threadripper.packets_to_send.put([header, raw_packet]) def client_update(self): """Thread-safe: Send a packet informing the server of our current state.""" packet = ClientUpdate() # Unused packet.status = ClientUpdate.CONNECTED packet.map = b'' # Set current steamid and shard core packet.steamid = 0 with self.state.lock: if self.state.old_state is not None and self.state.old_state.steamid is not None: packet.steamid = int(self.state.old_state.steamid) packet.shard_code = self.shard_code.encode('utf-8') self.send(PacketInfo.CLIENT_UPDATE, packet) def update_status(self): if not self.connected: wx.CallAfter(self.gui.SetStatusText, 'Connecting to sound sync server...') return with self.state.lock: if self.state.old_state == None: wx.CallAfter(self.gui.SetStatusText, 'Waiting for CS:GO...') elif self.state.old_state.is_ingame: phase = self.state.old_state.phase if phase == 'unknown': phase = '' else: phase = ' (%s)' % phase wx.CallAfter( self.gui.SetStatusText, f'Room "{self.shard_code}" - Round {self.state.old_state.current_round}{phase}' ) else: wx.CallAfter(self.gui.SetStatusText, 'Room "%s" - Not in a match.' % self.shard_code) def file_callback(self, hash, file): self.sounds.cache[hash] = file self.loaded_sounds = self.loaded_sounds + 1 wx.CallAfter( self.gui.SetStatusText, 'Loading sounds... (%d/%d)' % (self.loaded_sounds, self.max_sounds)) def error_callback(self, msg): dialog = wx.GenericMessageDialog(self.gui, message=msg, caption='Sound loading error', style=wx.OK | wx.ICON_ERROR) wx.CallAfter(dialog.ShowModal) def reload_sounds(self): """Reloads all sounds. Not thread safe, should only be called from GUI""" self.loaded_sounds = 0 self.max_sounds = len(self.sounds.sound_list('sounds')) self.sounds.load(self.file_callback, self.error_callback) wx.CallAfter(self.gui.updateSoundsBtn.Enable) self.update_status() # Send sound list to server if not self.connected: return packet = SoundRequest() with self.sounds.cache_lock: for hash in self.sounds.cache: packet.sound_hash.append(hash) self.send(PacketInfo.SOUNDS_LIST, packet) def request_sounds(self): if self.state.is_alive() and not self.gui.downloadWhenAliveChk.Value: return try: hash = self.threadripper.sounds_to_download.get(block=False) packet = SoundRequest() packet.sound_hash.append(hash) self.send(PacketInfo.SOUND_REQUEST, packet) except Empty: if self.download_total != 0: self.update_status() self.download_total = 0 def respond_sounds(self): if self.state.is_alive() and not self.gui.uploadWhenAliveChk.Value: return try: hash = self.threadripper.sounds_to_upload.get(block=False) filepath = os.path.join('cache', hash.hex()) with open(filepath, 'rb') as infile: packet = SoundResponse() packet.data = infile.read() packet.hash = hash self.send(PacketInfo.SOUND_RESPONSE, packet) except Empty: if self.upload_total != 0: self.update_status() self.upload_total = 0 def handle(self, packet_type, raw_packet): print('Received %s packet' % PacketInfo.Type.Name(packet_type)) if packet_type == PacketInfo.PLAY_SOUND and self.state.is_ingame(): packet = PlaySound() packet.ParseFromString(raw_packet) if not self.sounds.play(packet): self.download_total = self.download_total + 1 self.threadripper.sounds_to_download.put(packet.sound_hash) elif packet_type == PacketInfo.SOUND_REQUEST: req = SoundRequest() req.ParseFromString(raw_packet) self.upload_total += len(req.sound_hash) for hash in req.sound_hash: self.threadripper.sounds_to_upload.put(hash) elif packet_type == PacketInfo.SOUND_RESPONSE: packet = SoundResponse() packet.ParseFromString(raw_packet) self.sounds.save(packet) self.sounds.play_received(packet.hash) elif packet_type == PacketInfo.SOUNDS_LIST: packet = SoundRequest() packet.ParseFromString(raw_packet) download_list = [] with self.sounds.cache_lock: for hash in packet.sound_hash: if hash not in self.sounds.cache: download_list.append(hash) self.download_total += len(download_list) for hash in download_list: self.threadripper.sounds_to_download.put(hash) else: print("Unhandled packet type!") def keepalive(self): while True: self.client_update() sleep(10) def listen(self): while True: if not self.connected: try: with config.lock: ip = config.config['Network'].get( 'ServerIP', 'kiwec.net') port = config.config['Network'].getint( 'ServerPort', 4004) self.sock = socket.create_connection((ip, port)) self.connected = True self.reconnect_timeout = 1 self.client_update() except ConnectionRefusedError: self.connected = False if self.sock is not None: self.sock.shutdown(socket.SHUT_RDWR) sleep(self.reconnect_timeout) self.reconnect_timeout *= 2 if self.reconnect_timeout > 60: self.reconnect_timeout = 60 continue # The big network loop try: # Let's try SENDING some packets! self.request_sounds() self.respond_sounds() try: header, raw_packet = self.threadripper.packets_to_send.get( block=False) print(f'Sending {PacketInfo.Type.Name(header.type)}') self.sock.sendall(header.SerializeToString()) total_sent = 0 while total_sent < header.length: # Give some feedback about sound upload status if header.type == PacketInfo.SOUND_RESPONSE: sent_percent = int(total_sent / header.length * 100) wx.CallAfter( self.gui.SetStatusText, f'Uploading sound {self.uploaded + 1}/{self.upload_total}... ({sent_percent}%)' ) sent = self.sock.send(raw_packet) if sent == 0: raise ConnectionResetError total_sent += sent except Empty: # Nothing to send :( pass # Let's try RECEIVING some packets! self.sock.settimeout(0.1) data = self.sock.recv(7) self.sock.settimeout(None) if len(data) == 0: print('Invalid header size, reconnecting') self.connected = False self.sock.shutdown(socket.SHUT_RDWR) continue packet_info = PacketInfo() packet_info.ParseFromString(data) if packet_info.length > 3 * 1024 * 1024: # Don't allow files or packets over 3 Mb print('Invalid payload size, reconnecting') self.connected = False self.sock.shutdown(socket.SHUT_RDWR) continue data = b'' received = 0 while received < packet_info.length: # Give some feedback about download status if packet_info.type == PacketInfo.SOUND_RESPONSE: wx.CallAfter( self.gui.SetStatusText, 'Downloading sound {0}/{1}... ({2}%)'.format( self.downloaded + 1, self.download_total, int(received / packet_info.length * 100))) chunk = self.sock.recv(packet_info.length - received) data += chunk received += len(chunk) self.handle(packet_info.type, data) # Handle connection errors except ConnectionResetError: print("Connection reset, reconnecting") self.connected = False self.sock.shutdown(socket.SHUT_RDWR) except socket.timeout: self.sock.settimeout(None) except socket.error as msg: print("Connection error: " + str(msg)) self.connected = False self.sock.shutdown(socket.SHUT_RDWR)